Commit 26190694 authored by neverlord's avatar neverlord

fixed unnecessary copy during tuple_cast

parent 6d6c97a8
...@@ -81,7 +81,7 @@ class cow_ptr ...@@ -81,7 +81,7 @@ class cow_ptr
intrusive_ptr<T> m_ptr; intrusive_ptr<T> m_ptr;
T* detach_ptr() T* detached_ptr()
{ {
T* ptr = m_ptr.get(); T* ptr = m_ptr.get();
if (!ptr->unique()) if (!ptr->unique())
...@@ -94,12 +94,14 @@ class cow_ptr ...@@ -94,12 +94,14 @@ class cow_ptr
return ptr; return ptr;
} }
inline T const* ptr() const { return m_ptr.get(); }
public: public:
template<typename Y> template<typename Y>
cow_ptr(Y* raw_ptr) : m_ptr(raw_ptr) { } explicit cow_ptr(Y* raw_ptr) : m_ptr(raw_ptr) { }
cow_ptr(T* raw_ptr) : m_ptr(raw_ptr) { } explicit cow_ptr(T* raw_ptr) : m_ptr(raw_ptr) { }
cow_ptr(cow_ptr&& other) : m_ptr(std::move(other.m_ptr)) { } cow_ptr(cow_ptr&& other) : m_ptr(std::move(other.m_ptr)) { }
...@@ -134,17 +136,17 @@ class cow_ptr ...@@ -134,17 +136,17 @@ class cow_ptr
return *this; return *this;
} }
inline T* get() { return detach_ptr(); } inline T* get() { return detached_ptr(); }
inline T const* get() const { return m_ptr.get(); } inline T& operator*() { return *detached_ptr(); }
inline T* operator->() { return detach_ptr(); } inline T* operator->() { return detached_ptr(); }
inline T& operator*() { return detach_ptr(); } inline T const* get() const { return ptr(); }
inline T const* operator->() const { return m_ptr.get(); } inline T const& operator*() const { return *ptr(); }
inline T const& operator*() const { return *m_ptr.get(); } inline T const* operator->() const { return ptr(); }
inline explicit operator bool() const { return static_cast<bool>(m_ptr); } inline explicit operator bool() const { return static_cast<bool>(m_ptr); }
......
...@@ -65,13 +65,13 @@ class decorated_tuple : public abstract_tuple ...@@ -65,13 +65,13 @@ class decorated_tuple : public abstract_tuple
static inline cow_pointer_type create(cow_pointer_type d, static inline cow_pointer_type create(cow_pointer_type d,
vector_type const& v) vector_type const& v)
{ {
return {new decorated_tuple(std::move(d), v)}; return cow_pointer_type{new decorated_tuple(std::move(d), v)};
} }
// creates a subtuple form @p d with an offset // creates a subtuple form @p d with an offset
static inline cow_pointer_type create(cow_pointer_type d, size_t offset) static inline cow_pointer_type create(cow_pointer_type d, size_t offset)
{ {
return {new decorated_tuple(std::move(d), offset)}; return cow_pointer_type{new decorated_tuple(std::move(d), offset)};
} }
virtual void* mutable_at(size_t pos) virtual void* mutable_at(size_t pos)
...@@ -125,16 +125,21 @@ class decorated_tuple : public abstract_tuple ...@@ -125,16 +125,21 @@ class decorated_tuple : public abstract_tuple
decorated_tuple(cow_pointer_type d, vector_type const& v) decorated_tuple(cow_pointer_type d, vector_type const& v)
: m_decorated(std::move(d)), m_mapping(v) : m_decorated(std::move(d)), m_mapping(v)
{ {
CPPA_REQUIRE(m_decorated->size() >= sizeof...(ElementTypes)); # ifdef CPPA_DEBUG
cow_pointer_type const& ptr = m_decorated; // prevent detaching
# endif
CPPA_REQUIRE(ptr->size() >= sizeof...(ElementTypes));
CPPA_REQUIRE(v.size() == sizeof...(ElementTypes)); CPPA_REQUIRE(v.size() == sizeof...(ElementTypes));
CPPA_REQUIRE( *(std::max_element(v.begin(), v.end())) CPPA_REQUIRE(*(std::max_element(v.begin(), v.end())) < ptr->size());
< m_decorated->size());
} }
decorated_tuple(cow_pointer_type d, size_t offset) decorated_tuple(cow_pointer_type d, size_t offset)
: m_decorated(std::move(d)) : m_decorated(std::move(d))
{ {
CPPA_REQUIRE((m_decorated->size() - offset) >= sizeof...(ElementTypes)); # ifdef CPPA_DEBUG
cow_pointer_type const& ptr = m_decorated; // prevent detaching
# endif
CPPA_REQUIRE((ptr->size() - offset) >= sizeof...(ElementTypes));
CPPA_REQUIRE(offset > 0); CPPA_REQUIRE(offset > 0);
size_t i = offset; size_t i = offset;
m_mapping.resize(sizeof...(ElementTypes)); m_mapping.resize(sizeof...(ElementTypes));
......
...@@ -73,17 +73,13 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T const*>, ...@@ -73,17 +73,13 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T const*>,
intrusive_ptr(T* raw_ptr) { set_ptr(raw_ptr); } intrusive_ptr(T* raw_ptr) { set_ptr(raw_ptr); }
intrusive_ptr(intrusive_ptr const& other) intrusive_ptr(intrusive_ptr const& other) { set_ptr(other.m_ptr); }
{
set_ptr(other.m_ptr);
}
intrusive_ptr(intrusive_ptr&& other) : m_ptr(other.take()) intrusive_ptr(intrusive_ptr&& other) : m_ptr(other.take()) { }
{
}
// enables "actor_ptr s = self"
template<typename From> template<typename From>
intrusive_ptr(const convertible<From, T*>& from) intrusive_ptr(convertible<From, T*> const& from)
{ {
set_ptr(from.convert()); set_ptr(from.convert());
} }
...@@ -180,14 +176,14 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T const*>, ...@@ -180,14 +176,14 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T const*>,
return *this; return *this;
} }
inline T* operator->() { return m_ptr; }
inline T& operator*() { return *m_ptr; } inline T& operator*() { return *m_ptr; }
inline T const* operator->() const { return m_ptr; } inline T* operator->() { return m_ptr; }
inline T const& operator*() const { return *m_ptr; } inline T const& operator*() const { return *m_ptr; }
inline T const* operator->() const { return m_ptr; }
inline explicit operator bool() const { return m_ptr != nullptr; } inline explicit operator bool() const { return m_ptr != nullptr; }
inline ptrdiff_t compare(T const* ptr) const inline ptrdiff_t compare(T const* ptr) const
...@@ -203,15 +199,13 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T const*>, ...@@ -203,15 +199,13 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T const*>,
template<class C> template<class C>
intrusive_ptr<C> downcast() const intrusive_ptr<C> downcast() const
{ {
if (m_ptr) return dynamic_cast<C*>(const_cast<T*>(m_ptr)); return (m_ptr) ? dynamic_cast<C*>(const_cast<T*>(m_ptr)) : nullptr;
return nullptr;
} }
template<class C> template<class C>
intrusive_ptr<C> upcast() const intrusive_ptr<C> upcast() const
{ {
if (m_ptr) return static_cast<C*>(const_cast<T*>(m_ptr)); return (m_ptr) ? static_cast<C*>(const_cast<T*>(m_ptr)) : nullptr;
return nullptr;
} }
}; };
......
...@@ -30,15 +30,22 @@ ...@@ -30,15 +30,22 @@
#include <algorithm> #include <algorithm>
#include "cppa/config.hpp"
#include "cppa/object.hpp" #include "cppa/object.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/void_type.hpp" #include "cppa/util/void_type.hpp"
#include "cppa/detail/types_array.hpp"
namespace { namespace {
cppa::util::void_type s_void; cppa::util::void_type s_void;
inline cppa::uniform_type_info const* tvoid()
{
return cppa::detail::static_types_array<cppa::util::void_type>::arr[0];
}
} // namespace <anonymous> } // namespace <anonymous>
namespace cppa { namespace cppa {
...@@ -49,16 +56,14 @@ void object::swap(object& other) ...@@ -49,16 +56,14 @@ void object::swap(object& other)
std::swap(m_type, other.m_type); std::swap(m_type, other.m_type);
} }
object::object(void* val, const uniform_type_info* utype) object::object(void* val, uniform_type_info const* utype)
: m_value(val), m_type(utype) : m_value(val), m_type(utype)
{ {
if (val && !utype) CPPA_REQUIRE(val != nullptr);
{ CPPA_REQUIRE(utype != nullptr);
throw std::invalid_argument("val && !utype");
}
} }
object::object() : m_value(&s_void), m_type(uniform_typeid<util::void_type>()) object::object() : m_value(&s_void), m_type(tvoid())
{ {
} }
...@@ -67,17 +72,14 @@ object::~object() ...@@ -67,17 +72,14 @@ object::~object()
if (m_value != &s_void) m_type->delete_instance(m_value); if (m_value != &s_void) m_type->delete_instance(m_value);
} }
object::object(object const& other)
object::object(const object& other) : m_value(&s_void), m_type(uniform_typeid<util::void_type>())
{ {
if (other.value() != &s_void) m_type = other.m_type;
{ m_value = (other.m_value == &s_void) ? other.m_value
m_value = other.m_type->new_instance(other.m_value); : m_type->new_instance(other.m_value);
m_type = other.m_type;
}
} }
object::object(object&& other) : m_value(&s_void), m_type(uniform_typeid<util::void_type>()) object::object(object&& other) : m_value(&s_void), m_type(tvoid())
{ {
swap(other); swap(other);
} }
...@@ -89,15 +91,14 @@ object& object::operator=(object&& other) ...@@ -89,15 +91,14 @@ object& object::operator=(object&& other)
return *this; return *this;
} }
object& object::operator=(const object& other) object& object::operator=(object const& other)
{ {
// use copy ctor and then swap
object tmp(other); object tmp(other);
swap(tmp); swap(tmp);
return *this; return *this;
} }
bool operator==(const object& lhs, const object& rhs) bool operator==(object const& lhs, object const& rhs)
{ {
if (lhs.type() == rhs.type()) if (lhs.type() == rhs.type())
{ {
...@@ -113,7 +114,7 @@ uniform_type_info const* object::type() const ...@@ -113,7 +114,7 @@ uniform_type_info const* object::type() const
return m_type; return m_type;
} }
const void* object::value() const void const* object::value() const
{ {
return m_value; return m_value;
} }
......
...@@ -57,19 +57,6 @@ size_t test__tuple() ...@@ -57,19 +57,6 @@ size_t test__tuple()
CPPA_CHECK_EQUAL(get<0>(v0), "1"); CPPA_CHECK_EQUAL(get<0>(v0), "1");
CPPA_CHECK_EQUAL(get<0>(t0), get<0>(v0)); CPPA_CHECK_EQUAL(get<0>(t0), get<0>(v0));
// check cow semantics // check cow semantics
cout << " t0: " << t0.vals().get() << endl
<< " v0: " << v0.vals().get() << endl
//<< "*v0: " << dynamic_cast<detail::decorated_tuple<std::string> const*>(v0.vals().get())->decorated().get() << endl
<< "at0: " << at0.vals().get() << endl;
cout << "&get<0>(t0): " << (&get<0>(t0)) << endl
<< "&get<0>(v0): " << (&get<0>(v0)) << endl
<< " at0.at(0): " << (at0.at(0)) << endl;
CPPA_CHECK_EQUAL(&get<0>(t0), &get<0>(v0)); // point to the same CPPA_CHECK_EQUAL(&get<0>(t0), &get<0>(v0)); // point to the same
get_ref<0>(t0) = "hello world"; // detaches t0 from v0 get_ref<0>(t0) = "hello world"; // detaches t0 from v0
CPPA_CHECK_EQUAL(get<0>(t0), "hello world"); // t0 contains new value CPPA_CHECK_EQUAL(get<0>(t0), "hello world"); // t0 contains new value
......
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