Commit f83fdfb4 authored by Dominik Charousset's avatar Dominik Charousset

Refactor {object => uniform_value}

parent fb65de5a
...@@ -198,7 +198,6 @@ set(LIBCPPA_SRC ...@@ -198,7 +198,6 @@ set(LIBCPPA_SRC
src/middleman.cpp src/middleman.cpp
src/middleman_event_handler.cpp src/middleman_event_handler.cpp
src/node_id.cpp src/node_id.cpp
src/object.cpp
src/object_array.cpp src/object_array.cpp
src/opt.cpp src/opt.cpp
src/output_stream.cpp src/output_stream.cpp
......
...@@ -237,12 +237,8 @@ class meta_cow_tuple : public uniform_type_info { ...@@ -237,12 +237,8 @@ class meta_cow_tuple : public uniform_type_info {
do_deserialize(source, ref, util::get_indices(ref)); do_deserialize(source, ref, util::get_indices(ref));
} }
void* new_instance(const void* other = nullptr) const override { uniform_value create(const uniform_value& other) const override {
return (other) ? new tuple_type{*cast(other)} : new tuple_type; return create_impl<tuple_type>(other);
}
void delete_instance(void* instance) const override {
delete cast(instance);
} }
any_tuple as_any_tuple(void* instance) const override { any_tuple as_any_tuple(void* instance) const override {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "cppa/on.hpp" #include "cppa/on.hpp"
#include "cppa/extend.hpp" #include "cppa/extend.hpp"
#include "cppa/behavior.hpp" #include "cppa/behavior.hpp"
#include "cppa/exception.hpp"
#include "cppa/local_actor.hpp" #include "cppa/local_actor.hpp"
#include "cppa/sync_sender.hpp" #include "cppa/sync_sender.hpp"
#include "cppa/typed_actor.hpp" #include "cppa/typed_actor.hpp"
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/memory_cached.hpp"
#include "cppa/detail/memory.hpp" #include "cppa/detail/memory.hpp"
namespace cppa { namespace cppa {
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <vector> #include <vector>
#include "cppa/object.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/detail/abstract_tuple.hpp"
namespace cppa { namespace cppa {
...@@ -38,11 +38,11 @@ class object_array : public abstract_tuple { ...@@ -38,11 +38,11 @@ class object_array : public abstract_tuple {
object_array(); object_array();
object_array(object_array&&) = default; object_array(object_array&&) = default;
object_array(const object_array&) = default; object_array(const object_array&);
void push_back(object&& what); ~object_array();
void push_back(const object& what); void push_back(uniform_value what);
void* mutable_at(size_t pos) override; void* mutable_at(size_t pos) override;
...@@ -58,7 +58,7 @@ class object_array : public abstract_tuple { ...@@ -58,7 +58,7 @@ class object_array : public abstract_tuple {
private: private:
std::vector<object> m_elements; std::vector<uniform_value> m_elements;
}; };
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <typeinfo> #include <typeinfo>
#include <exception> #include <exception>
#include "cppa/object.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
namespace cppa { namespace cppa {
...@@ -36,29 +35,7 @@ namespace cppa { ...@@ -36,29 +35,7 @@ namespace cppa {
* @returns An {@link cppa::object object} instance that contains * @returns An {@link cppa::object object} instance that contains
* the deserialized value. * the deserialized value.
*/ */
object from_string(const std::string& what); uniform_value from_string(const std::string& what);
/**
* @brief Convenience function that deserializes a value from @p what and
* converts the result to @p T.
* @throws std::logic_error if the result is not of type @p T.
* @returns The deserialized value as instance of @p T.
*/
template<typename T>
T from_string(const std::string& what) {
object o = from_string(what);
const std::type_info& tinfo = typeid(T);
if (tinfo == *(o.type())) {
return std::move(get_ref<T>(o));
}
else {
std::string error_msg = "expected type name ";
error_msg += uniform_typeid(tinfo)->name();
error_msg += " found ";
error_msg += o.type()->name();
throw std::logic_error(error_msg);
}
}
} // namespace cppa } // namespace cppa
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <map> #include <map>
#include "cppa/extend.hpp" #include "cppa/extend.hpp"
#include "cppa/exception.hpp"
#include "cppa/local_actor.hpp" #include "cppa/local_actor.hpp"
#include "cppa/behavior_stack_based.hpp" #include "cppa/behavior_stack_based.hpp"
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011 - 2014 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the Boost Software License, Version 1.0. See *
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#ifndef CPPA_OBJECT_HPP
#define CPPA_OBJECT_HPP
#include <string>
#include <typeinfo>
#include <stdexcept>
#include <type_traits>
#include "cppa/exception.hpp"
#include "cppa/util/type_traits.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace cppa {
// forward declarations
class object;
/**
* @relates object
*/
bool operator==(const object& lhs, const object& rhs);
class uniform_type_info;
const uniform_type_info* uniform_typeid(const std::type_info&);
bool operator==(const uniform_type_info& lhs, const std::type_info& rhs);
/**
* @brief Grants mutable access to the stored value of @p obj.
* @param obj {@link object Object} with <tt>obj.type() == typeid(T)</tt>.
* @returns A mutable reference to the value stored in @p obj.
* @relates object
* @throws std::invalid_argument if <tt>obj.type() != typeid(T)</tt>
*/
template<typename T>
T& get_ref(object& obj);
/**
* @brief Grants const access to the stored value of @p obj.
* @param obj {@link object Object} with <tt>obj.type() == typeid(T)</tt>.
* @returns A const reference to the value stored in @p obj.
* @relates object
* @throws std::invalid_argument if <tt>obj.type() != typeid(T)</tt>
*/
template<typename T>
const T& get(const object& obj);
/**
* @brief An abstraction class that stores an instance of
* an announced type.
*/
class object {
friend bool operator==(const object& lhs, const object& rhs);
public:
~object();
/**
* @brief Creates an object of type @p utinfo with value @p val.
* @warning {@link object} takes ownership of @p val.
* @pre {@code val != nullptr && utinfo != nullptr}
*/
object(void* val, const uniform_type_info* utinfo);
/**
* @brief Creates an empty object.
* @post {type() == *uniform_typeid<unit_t>()}
*/
object();
/**
* @brief Creates an object and moves type and value
* from @p other to @c this.
*/
object(object&& other);
/**
* @brief Creates a (deep) copy of @p other.
* @post {*this == other}
*/
object(const object& other);
/**
* @brief Moves the content from @p other to this.
* @returns @p *this
*/
object& operator=(object&& other);
/**
* @brief Creates a (deep) copy of @p other and assigns it to @p this.
* @returns @p *this
*/
object& operator=(const object& other);
/**
* @brief Gets the RTTI of this object.
* @returns A {@link uniform_type_info} describing the current
* type of @p this.
*/
const uniform_type_info* type() const;
/**
* @brief Gets the stored value.
* @returns A const pointer to the currently stored value.
* @see get(const object&)
*/
const void* value() const;
/**
* @brief Gets the stored value.
* @returns A mutable pointer to the currently stored value.
* @see get_ref(object&)
*/
void* mutable_value();
/**
* @brief Creates an object from @p what.
* @param what Value of an announced type.
* @returns An object whose value was initialized with @p what.
* @post {@code type() == *uniform_typeid<T>()}
* @throws std::runtime_error if @p T is not announced.
*/
template<typename T>
static object from(T what);
private:
void* m_value;
const uniform_type_info* m_type;
void swap(object& other);
};
template<typename T>
object object::from(T what) {
typedef typename util::rm_const_and_ref<T>::type plain_type;
typedef typename detail::implicit_conversions<plain_type>::type value_type;
auto rtti = uniform_typeid(typeid(value_type)); // throws on error
return { new value_type(std::move(what)), rtti };
}
inline bool operator!=(const object& lhs, const object& rhs) {
return !(lhs == rhs);
}
template<typename T>
T& get_ref(object& obj) {
static_assert(!std::is_pointer<T>::value && !std::is_reference<T>::value,
"T is a reference or a pointer type.");
if (!(*(obj.type()) == typeid(T))) {
throw std::invalid_argument("obj.type() != typeid(T)");
}
return *reinterpret_cast<T*>(obj.mutable_value());
}
template<typename T>
const T& get(const object& obj) {
static_assert(!std::is_pointer<T>::value && !std::is_reference<T>::value,
"T is a reference or a pointer type.");
if (!(*(obj.type()) == typeid(T))) {
throw std::invalid_argument("obj.type() != typeid(T)");
}
return *reinterpret_cast<const T*>(obj.value());
}
} // namespace cppa
#endif // CPPA_OBJECT_HPP
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include "cppa/atom.hpp" // included for to_string(atom_value) #include "cppa/atom.hpp" // included for to_string(atom_value)
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/group.hpp" #include "cppa/group.hpp"
#include "cppa/object.hpp"
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/node_id.hpp" #include "cppa/node_id.hpp"
#include "cppa/anything.hpp" #include "cppa/anything.hpp"
...@@ -80,10 +79,6 @@ std::string to_string(const node_id& what); ...@@ -80,10 +79,6 @@ std::string to_string(const node_id& what);
// implemented in node_id.cpp // implemented in node_id.cpp
std::string to_string(const node_id_ptr& what); std::string to_string(const node_id_ptr& what);
inline std::string to_string(const object& what) {
return detail::to_string_impl(what.value(), what.type());
}
/** /**
* @brief Converts @p e to a string including the demangled type of e * @brief Converts @p e to a string including the demangled type of e
* and @p e.what(). * and @p e.what().
......
...@@ -27,8 +27,6 @@ ...@@ -27,8 +27,6 @@
#include <typeinfo> #include <typeinfo>
#include <type_traits> #include <type_traits>
#include "cppa/object.hpp"
#include "cppa/util/comparable.hpp" #include "cppa/util/comparable.hpp"
#include "cppa/util/type_traits.hpp" #include "cppa/util/type_traits.hpp"
...@@ -43,6 +41,32 @@ class uniform_type_info; ...@@ -43,6 +41,32 @@ class uniform_type_info;
const uniform_type_info* uniform_typeid(const std::type_info&); const uniform_type_info* uniform_typeid(const std::type_info&);
struct uniform_value_t;
typedef std::unique_ptr<uniform_value_t> uniform_value;
struct uniform_value_t {
const uniform_type_info* ti;
void* val;
virtual uniform_value copy() = 0;
virtual ~uniform_value_t();
};
template<typename T, typename... Ts>
uniform_value make_uniform_value(const uniform_type_info* ti, Ts&&... args) {
struct container : uniform_value_t {
T value;
container(const uniform_type_info* ptr, T arg) : value(std::move(arg)) {
ti = ptr;
val = &value;
}
uniform_value copy() override {
return uniform_value{new container(ti, value)};
}
};
return uniform_value{new container(ti, T(std::forward<Ts>(args)...))};
}
/** /**
* @defgroup TypeSystem libcppa's platform-independent type system. * @defgroup TypeSystem libcppa's platform-independent type system.
* *
...@@ -136,8 +160,6 @@ const uniform_type_info* uniform_typeid(const std::type_info&); ...@@ -136,8 +160,6 @@ const uniform_type_info* uniform_typeid(const std::type_info&);
*/ */
class uniform_type_info { class uniform_type_info {
friend class object;
friend bool operator==(const uniform_type_info& lhs, friend bool operator==(const uniform_type_info& lhs,
const uniform_type_info& rhs); const uniform_type_info& rhs);
...@@ -176,14 +198,14 @@ class uniform_type_info { ...@@ -176,14 +198,14 @@ class uniform_type_info {
static std::vector<const uniform_type_info*> instances(); static std::vector<const uniform_type_info*> instances();
/** /**
* @brief Creates an object of this type. * @brief Creates a copy of @p other.
*/ */
object create() const; virtual uniform_value create(const uniform_value& other = uniform_value{}) const = 0;
/** /**
* @brief Deserializes an object of this type from @p source. * @brief Deserializes an object of this type from @p source.
*/ */
object deserialize(deserializer* source) const; uniform_value deserialize(deserializer* source) const;
/** /**
* @brief Get the internal @p libcppa name for this type. * @brief Get the internal @p libcppa name for this type.
...@@ -223,24 +245,6 @@ class uniform_type_info { ...@@ -223,24 +245,6 @@ class uniform_type_info {
*/ */
virtual void deserialize(void* instance, deserializer* source) const = 0; virtual void deserialize(void* instance, deserializer* source) const = 0;
/**
* @brief Casts @p instance to the native type and deletes it.
* @param instance Instance of this type.
* @pre @p instance has the type of @p this.
*/
virtual void delete_instance(void* instance) const = 0;
/**
* @brief Creates an instance of this type, either as a copy of
* @p instance or initialized with the default constructor
* if <tt>instance == nullptr</tt>.
* @param instance Optional instance of this type.
* @returns Either a copy of @p instance or a new instance, initialized
* with the default constructor.
* @pre @p instance has the type of @p this or is set to @p nullptr.
*/
virtual void* new_instance(const void* instance = nullptr) const = 0;
/** /**
* @brief Returns @p instance encapsulated as an @p any_tuple. * @brief Returns @p instance encapsulated as an @p any_tuple.
*/ */
...@@ -250,6 +254,16 @@ class uniform_type_info { ...@@ -250,6 +254,16 @@ class uniform_type_info {
uniform_type_info() = default; uniform_type_info() = default;
template<typename T>
uniform_value create_impl(const uniform_value& other) const {
if (other) {
CPPA_REQUIRE(other->ti == this);
auto ptr = reinterpret_cast<const T*>(other->val);
return make_uniform_value<T>(this, *ptr);
}
return make_uniform_value<T>(this);
}
}; };
/** /**
......
...@@ -57,12 +57,8 @@ class abstract_uniform_type_info : public uniform_type_info { ...@@ -57,12 +57,8 @@ class abstract_uniform_type_info : public uniform_type_info {
return eq(deref(lhs), deref(rhs)); return eq(deref(lhs), deref(rhs));
} }
void* new_instance(const void* ptr) const override { uniform_value create(const uniform_value& other) const override {
return (ptr) ? new T(deref(ptr)) : new T(); return create_impl<T>(other);
}
void delete_instance(void* instance) const override {
delete reinterpret_cast<T*>(instance);
} }
protected: protected:
...@@ -100,7 +96,7 @@ class abstract_uniform_type_info : public uniform_type_info { ...@@ -100,7 +96,7 @@ class abstract_uniform_type_info : public uniform_type_info {
template<class C> template<class C>
typename std::enable_if< typename std::enable_if<
!std::is_empty<C>::value && util::is_comparable<C, C>::value, !std::is_empty<C>::value && is_comparable<C, C>::value,
bool bool
>::type >::type
eq(const C& lhs, const C& rhs) const { eq(const C& lhs, const C& rhs) const {
...@@ -111,7 +107,7 @@ class abstract_uniform_type_info : public uniform_type_info { ...@@ -111,7 +107,7 @@ class abstract_uniform_type_info : public uniform_type_info {
typename std::enable_if< typename std::enable_if<
!std::is_empty<C>::value !std::is_empty<C>::value
&& std::is_pod<C>::value && std::is_pod<C>::value
&& !util::is_comparable<C, C>::value, && !is_comparable<C, C>::value,
bool bool
>::type >::type
eq(const C& lhs, const C& rhs) const { eq(const C& lhs, const C& rhs) const {
......
...@@ -95,7 +95,7 @@ void testee(event_based_actor* self, size_t remaining) { ...@@ -95,7 +95,7 @@ void testee(event_based_actor* self, size_t remaining) {
}, },
on<baz>() >> [=](const baz& val) { on<baz>() >> [=](const baz& val) {
// prints: baz ( foo ( 1, 2 ), bar ( foo ( 3, 4 ), 5 ) ) // prints: baz ( foo ( 1, 2 ), bar ( foo ( 3, 4 ), 5 ) )
aout(self) << to_string(object::from(val)) << endl; //aout(self) << to_string(object::from(val)) << endl;
set_next_behavior(); set_next_behavior();
} }
); );
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <string> #include <string>
#include "cppa/object.hpp"
#include "cppa/deserializer.hpp" #include "cppa/deserializer.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011 - 2014 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the Boost Software License, Version 1.0. See *
* accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt *
\******************************************************************************/
#include <algorithm>
#include "cppa/unit.hpp"
#include "cppa/config.hpp"
#include "cppa/object.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/detail/types_array.hpp"
namespace {
cppa::unit_t s_unit;
inline const cppa::uniform_type_info* unit_type() {
return cppa::detail::static_types_array<cppa::unit_t>::arr[0];
}
} // namespace <anonymous>
namespace cppa {
void object::swap(object& other) {
std::swap(m_value, other.m_value);
std::swap(m_type, other.m_type);
}
object::object(void* val, const uniform_type_info* utype)
: m_value(val), m_type(utype) {
CPPA_REQUIRE(val != nullptr);
CPPA_REQUIRE(utype != nullptr);
}
object::object() : m_value(&s_unit), m_type(unit_type()) {
}
object::~object() {
if (m_value != &s_unit) m_type->delete_instance(m_value);
}
object::object(const object& other) {
m_type = other.m_type;
m_value = (other.m_value == &s_unit) ? other.m_value
: m_type->new_instance(other.m_value);
}
object::object(object&& other) : m_value(&s_unit), m_type(unit_type()) {
swap(other);
}
object& object::operator=(object&& other) {
object tmp(std::move(other));
swap(tmp);
return *this;
}
object& object::operator=(const object& other) {
object tmp(other);
swap(tmp);
return *this;
}
bool operator==(const object& lhs, const object& rhs) {
if (lhs.type() == rhs.type()) {
// values might both point to s_void if lhs and rhs are "empty"
return lhs.value() == rhs.value()
|| lhs.type()->equals(lhs.value(), rhs.value());
}
return false;
}
const uniform_type_info* object::type() const {
return m_type;
}
const void* object::value() const {
return m_value;
}
void* object::mutable_value() {
return m_value;
}
} // namespace cppa
...@@ -22,18 +22,27 @@ ...@@ -22,18 +22,27 @@
namespace cppa { namespace cppa {
namespace detail { namespace detail {
object_array::object_array() : super(true) { } object_array::object_array() : super(true) {
// nop
}
object_array::object_array(const object_array& other) : super(true) {
m_elements.reserve(other.m_elements.size());
for (auto& e : other.m_elements) m_elements.push_back(e->copy());
}
void object_array::push_back(const object& what) { object_array::~object_array() {
m_elements.push_back(what); // nop
} }
void object_array::push_back(object&& what) { void object_array::push_back(uniform_value what) {
CPPA_REQUIRE(what && what->val != nullptr && what->ti != nullptr);
m_elements.push_back(std::move(what)); m_elements.push_back(std::move(what));
} }
void* object_array::mutable_at(size_t pos) { void* object_array::mutable_at(size_t pos) {
return m_elements[pos].mutable_value(); CPPA_REQUIRE(pos < size());
return m_elements[pos]->val;
} }
size_t object_array::size() const { size_t object_array::size() const {
...@@ -45,11 +54,13 @@ object_array* object_array::copy() const { ...@@ -45,11 +54,13 @@ object_array* object_array::copy() const {
} }
const void* object_array::at(size_t pos) const { const void* object_array::at(size_t pos) const {
return m_elements[pos].value(); CPPA_REQUIRE(pos < size());
return m_elements[pos]->val;
} }
const uniform_type_info* object_array::type_at(size_t pos) const { const uniform_type_info* object_array::type_at(size_t pos) const {
return m_elements[pos].type(); CPPA_REQUIRE(pos < size());
return m_elements[pos]->ti;
} }
const std::string* object_array::tuple_type_names() const { const std::string* object_array::tuple_type_names() const {
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <algorithm> #include <algorithm>
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/object.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/serializer.hpp" #include "cppa/serializer.hpp"
#include "cppa/singletons.hpp" #include "cppa/singletons.hpp"
...@@ -491,7 +490,7 @@ class string_deserializer : public deserializer { ...@@ -491,7 +490,7 @@ class string_deserializer : public deserializer {
} // namespace <anonymous> } // namespace <anonymous>
object from_string(const string& what) { uniform_value from_string(const string& what) {
string_deserializer strd(what); string_deserializer strd(what);
auto utype = strd.begin_object(); auto utype = strd.begin_object();
auto result = utype->deserialize(&strd); auto result = utype->deserialize(&strd);
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/object.hpp"
#include "cppa/logging.hpp" #include "cppa/logging.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/announce.hpp" #include "cppa/announce.hpp"
...@@ -58,10 +57,12 @@ const uniform_type_info* announce(const std::type_info&, ...@@ -58,10 +57,12 @@ const uniform_type_info* announce(const std::type_info&,
return uti_map().insert(std::move(utype)); return uti_map().insert(std::move(utype));
} }
uniform_type_info::~uniform_type_info() { } uniform_type_info::~uniform_type_info() {
// nop
}
object uniform_type_info::create() const { uniform_value_t::~uniform_value_t() {
return {new_instance(), this}; // nop
} }
const uniform_type_info* uniform_type_info::from(const std::type_info& tinf) { const uniform_type_info* uniform_type_info::from(const std::type_info& tinf) {
...@@ -84,10 +85,10 @@ const uniform_type_info* uniform_type_info::from(const std::string& name) { ...@@ -84,10 +85,10 @@ const uniform_type_info* uniform_type_info::from(const std::string& name) {
return result; return result;
} }
object uniform_type_info::deserialize(deserializer* from) const { uniform_value uniform_type_info::deserialize(deserializer* from) const {
auto ptr = new_instance(); auto uval = create();
deserialize(ptr, from); deserialize(uval->val, from);
return {ptr, this}; return uval;
} }
std::vector<const uniform_type_info*> uniform_type_info::instances() { std::vector<const uniform_type_info*> uniform_type_info::instances() {
......
...@@ -303,13 +303,10 @@ void serialize_impl(const any_tuple& tup, serializer* sink) { ...@@ -303,13 +303,10 @@ void serialize_impl(const any_tuple& tup, serializer* sink) {
void deserialize_impl(any_tuple& atref, deserializer* source) { void deserialize_impl(any_tuple& atref, deserializer* source) {
auto uti = source->begin_object(); auto uti = source->begin_object();
auto ptr = uti->new_instance(); auto uval = uti->create();
auto ptr_guard = util::make_scope_guard([&] { uti->deserialize(uval->val, source);
uti->delete_instance(ptr);
});
uti->deserialize(ptr, source);
source->end_object(); source->end_object();
atref = uti->as_any_tuple(ptr); atref = uti->as_any_tuple(uval->val);
} }
void serialize_impl(msg_hdr_cref hdr, serializer* sink) { void serialize_impl(msg_hdr_cref hdr, serializer* sink) {
...@@ -491,12 +488,8 @@ class uti_base : public uniform_type_info { ...@@ -491,12 +488,8 @@ class uti_base : public uniform_type_info {
return eq(deref(lhs), deref(rhs)); return eq(deref(lhs), deref(rhs));
} }
void* new_instance(const void* ptr) const override { uniform_value create(const uniform_value& other) const override {
return (ptr) ? new T(deref(ptr)) : new T; return create_impl<T>(other);
}
void delete_instance(void* instance) const override {
delete reinterpret_cast<T*>(instance);
} }
any_tuple as_any_tuple(void* instance) const override { any_tuple as_any_tuple(void* instance) const override {
...@@ -605,12 +598,8 @@ class int_tinfo : public abstract_int_tinfo { ...@@ -605,12 +598,8 @@ class int_tinfo : public abstract_int_tinfo {
return deref(lhs) == deref(rhs); return deref(lhs) == deref(rhs);
} }
void* new_instance(const void* ptr) const override { uniform_value create(const uniform_value& other) const override {
return (ptr) ? new T(deref(ptr)) : new T; return create_impl<T>(other);
}
void delete_instance(void* instance) const override {
delete reinterpret_cast<T*>(instance);
} }
private: private:
...@@ -666,12 +655,8 @@ class buffer_type_info_impl : public uniform_type_info { ...@@ -666,12 +655,8 @@ class buffer_type_info_impl : public uniform_type_info {
&& memcmp(lhs.data(), rhs.data(), lhs.size()) == 0); && memcmp(lhs.data(), rhs.data(), lhs.size()) == 0);
} }
void* new_instance(const void* ptr) const override { uniform_value create(const uniform_value& other) const override {
return (ptr) ? new util::buffer(deref(ptr)) : new util::buffer; return create_impl<util::buffer>(other);
}
void delete_instance(void* instance) const override {
delete reinterpret_cast<util::buffer*>(instance);
} }
private: private:
...@@ -708,19 +693,14 @@ class default_meta_tuple : public uniform_type_info { ...@@ -708,19 +693,14 @@ class default_meta_tuple : public uniform_type_info {
} }
} }
void* new_instance(const void* instance = nullptr) const override { uniform_value create(const uniform_value& other) const override {
object_array* result = nullptr; auto res = create_impl<object_array>(other);
if (instance) result = new object_array{*cast(instance)}; if (!other) {
else { // res is not a copy => fill it with values
result = new object_array; auto& oarr = *cast(res->val);
for (auto uti : m_elements) result->push_back(uti->create()); for (auto uti : m_elements) oarr.push_back(uti->create());
}
result->ref();
return result;
} }
return res;
void delete_instance(void* ptr) const override {
cast(ptr)->deref();
} }
any_tuple as_any_tuple(void* ptr) const override { any_tuple as_any_tuple(void* ptr) const override {
......
...@@ -358,7 +358,9 @@ inline void make_dynamically_typed_impl(detail::object_array&) { } ...@@ -358,7 +358,9 @@ inline void make_dynamically_typed_impl(detail::object_array&) { }
template<typename T0, typename... Ts> template<typename T0, typename... Ts>
void make_dynamically_typed_impl(detail::object_array& arr, T0&& arg0, Ts&&... args) { void make_dynamically_typed_impl(detail::object_array& arr, T0&& arg0, Ts&&... args) {
arr.push_back(object::from(std::forward<T0>(arg0))); using type = typename detail::strip_and_convert<T0>::type;
arr.push_back(make_uniform_value<type>(uniform_typeid<type>(),
std::forward<T0>(arg0)));
make_dynamically_typed_impl(arr, std::forward<Ts>(args)...); make_dynamically_typed_impl(arr, std::forward<Ts>(args)...);
} }
......
...@@ -145,6 +145,8 @@ int main() { ...@@ -145,6 +145,8 @@ int main() {
cout << "process id: " << to_string(get_middleman()->node()) << endl; cout << "process id: " << to_string(get_middleman()->node()) << endl;
auto atuple1 = make_tuple(uint32_t{42}, "foo");
/*
auto oarr = new detail::object_array; auto oarr = new detail::object_array;
oarr->push_back(object::from(static_cast<uint32_t>(42))); oarr->push_back(object::from(static_cast<uint32_t>(42)));
oarr->push_back(object::from("foo" )); oarr->push_back(object::from("foo" ));
...@@ -198,8 +200,9 @@ int main() { ...@@ -198,8 +200,9 @@ int main() {
CPPA_CHECK_EQUAL(rs2.str, rs.str); CPPA_CHECK_EQUAL(rs2.str, rs.str);
} }
catch (exception& e) { CPPA_FAILURE(to_verbose_string(e)); } catch (exception& e) { CPPA_FAILURE(to_verbose_string(e)); }
*/
try { //try {
scoped_actor self; scoped_actor self;
auto ttup = make_any_tuple(1, 2, actor{self.get()}); auto ttup = make_any_tuple(1, 2, actor{self.get()});
util::buffer wr_buf; util::buffer wr_buf;
...@@ -209,8 +212,8 @@ int main() { ...@@ -209,8 +212,8 @@ int main() {
any_tuple ttup2; any_tuple ttup2;
uniform_typeid<any_tuple>()->deserialize(&ttup2, &bd); uniform_typeid<any_tuple>()->deserialize(&ttup2, &bd);
CPPA_CHECK(ttup == ttup2); CPPA_CHECK(ttup == ttup2);
} //}
catch (exception& e) { CPPA_FAILURE(to_verbose_string(e)); } //catch (exception& e) { CPPA_FAILURE(to_verbose_string(e)); }
try { try {
scoped_actor self; scoped_actor self;
...@@ -255,6 +258,7 @@ int main() { ...@@ -255,6 +258,7 @@ int main() {
CPPA_CHECK((is_iterable<string>::value) == false); CPPA_CHECK((is_iterable<string>::value) == false);
CPPA_CHECK((is_iterable<list<int>>::value) == true); CPPA_CHECK((is_iterable<list<int>>::value) == true);
CPPA_CHECK((is_iterable<map<int, int>>::value) == true); CPPA_CHECK((is_iterable<map<int, int>>::value) == true);
/*
try { // test meta_object implementation for primitive types try { // test meta_object implementation for primitive types
auto meta_int = uniform_typeid<uint32_t>(); auto meta_int = uniform_typeid<uint32_t>();
CPPA_CHECK(meta_int != nullptr); CPPA_CHECK(meta_int != nullptr);
...@@ -266,6 +270,7 @@ int main() { ...@@ -266,6 +270,7 @@ int main() {
} }
} }
catch (exception& e) { CPPA_FAILURE(to_verbose_string(e)); } catch (exception& e) { CPPA_FAILURE(to_verbose_string(e)); }
*/
// test serialization of enums // test serialization of enums
try { try {
......
...@@ -54,16 +54,6 @@ int main() { ...@@ -54,16 +54,6 @@ int main() {
CPPA_CHECK(announce1 == announce3); CPPA_CHECK(announce1 == announce3);
CPPA_CHECK(announce1 == announce4); CPPA_CHECK(announce1 == announce4);
CPPA_CHECK_EQUAL(announce1->name(), "$::foo"); CPPA_CHECK_EQUAL(announce1->name(), "$::foo");
{
//bar.create_object();
object obj1 = uniform_typeid<foo>()->create();
object obj2(obj1);
CPPA_CHECK(obj1 == obj2);
get_ref<foo>(obj1).value = 42;
CPPA_CHECK(obj1 != obj2);
CPPA_CHECK_EQUAL(get<foo>(obj1).value, 42);
CPPA_CHECK_EQUAL(get<foo>(obj2).value, 0);
}
{ {
auto uti = uniform_typeid<atom_value>(); auto uti = uniform_typeid<atom_value>();
CPPA_CHECK(uti != nullptr); CPPA_CHECK(uti != nullptr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment