Commit 26190694 authored by neverlord's avatar neverlord

fixed unnecessary copy during tuple_cast

parent 6d6c97a8
......@@ -81,7 +81,7 @@ class cow_ptr
intrusive_ptr<T> m_ptr;
T* detach_ptr()
T* detached_ptr()
{
T* ptr = m_ptr.get();
if (!ptr->unique())
......@@ -94,12 +94,14 @@ class cow_ptr
return ptr;
}
inline T const* ptr() const { return m_ptr.get(); }
public:
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)) { }
......@@ -134,17 +136,17 @@ class cow_ptr
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); }
......
......@@ -65,13 +65,13 @@ class decorated_tuple : public abstract_tuple
static inline cow_pointer_type create(cow_pointer_type d,
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
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)
......@@ -125,16 +125,21 @@ class decorated_tuple : public abstract_tuple
decorated_tuple(cow_pointer_type d, vector_type const& 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( *(std::max_element(v.begin(), v.end()))
< m_decorated->size());
CPPA_REQUIRE(*(std::max_element(v.begin(), v.end())) < ptr->size());
}
decorated_tuple(cow_pointer_type d, size_t offset)
: 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);
size_t i = offset;
m_mapping.resize(sizeof...(ElementTypes));
......
......@@ -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(intrusive_ptr const& other)
{
set_ptr(other.m_ptr);
}
intrusive_ptr(intrusive_ptr const& other) { 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>
intrusive_ptr(const convertible<From, T*>& from)
intrusive_ptr(convertible<From, T*> const& from)
{
set_ptr(from.convert());
}
......@@ -180,14 +176,14 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T const*>,
return *this;
}
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 explicit operator bool() const { return m_ptr != nullptr; }
inline ptrdiff_t compare(T const* ptr) const
......@@ -203,15 +199,13 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, T const*>,
template<class C>
intrusive_ptr<C> downcast() const
{
if (m_ptr) return dynamic_cast<C*>(const_cast<T*>(m_ptr));
return nullptr;
return (m_ptr) ? dynamic_cast<C*>(const_cast<T*>(m_ptr)) : nullptr;
}
template<class C>
intrusive_ptr<C> upcast() const
{
if (m_ptr) return static_cast<C*>(const_cast<T*>(m_ptr));
return nullptr;
return (m_ptr) ? static_cast<C*>(const_cast<T*>(m_ptr)) : nullptr;
}
};
......
......@@ -30,15 +30,22 @@
#include <algorithm>
#include "cppa/config.hpp"
#include "cppa/object.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/void_type.hpp"
#include "cppa/detail/types_array.hpp"
namespace {
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 cppa {
......@@ -49,16 +56,14 @@ void object::swap(object& other)
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)
{
if (val && !utype)
{
throw std::invalid_argument("val && !utype");
}
CPPA_REQUIRE(val != nullptr);
CPPA_REQUIRE(utype != nullptr);
}
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()
if (m_value != &s_void) m_type->delete_instance(m_value);
}
object::object(const object& other) : m_value(&s_void), m_type(uniform_typeid<util::void_type>())
object::object(object const& other)
{
if (other.value() != &s_void)
{
m_value = other.m_type->new_instance(other.m_value);
m_type = other.m_type;
}
m_type = other.m_type;
m_value = (other.m_value == &s_void) ? other.m_value
: m_type->new_instance(other.m_value);
}
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);
}
......@@ -89,15 +91,14 @@ object& object::operator=(object&& other)
return *this;
}
object& object::operator=(const object& other)
object& object::operator=(object const& other)
{
// use copy ctor and then swap
object tmp(other);
swap(tmp);
return *this;
}
bool operator==(const object& lhs, const object& rhs)
bool operator==(object const& lhs, object const& rhs)
{
if (lhs.type() == rhs.type())
{
......@@ -113,7 +114,7 @@ uniform_type_info const* object::type() const
return m_type;
}
const void* object::value() const
void const* object::value() const
{
return m_value;
}
......
......@@ -57,19 +57,6 @@ size_t test__tuple()
CPPA_CHECK_EQUAL(get<0>(v0), "1");
CPPA_CHECK_EQUAL(get<0>(t0), get<0>(v0));
// 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
get_ref<0>(t0) = "hello world"; // detaches t0 from v0
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