Commit 00f1e528 authored by neverlord's avatar neverlord

any_tuple::tail

parent ffd73d2a
......@@ -3,6 +3,7 @@ ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES = libcppa.la
libcppa_la_SOURCES = \
src/abstract_tuple.cpp \
src/abstract_type_list.cpp \
src/actor_behavior.cpp \
src/actor_count.cpp \
......
......@@ -211,3 +211,4 @@ cppa/detail/unboxed.hpp
cppa/detail/matcher_arguments.hpp
src/matcher_arguments.cpp
src/invoke_rules.cpp
src/abstract_tuple.cpp
......@@ -18,6 +18,8 @@ class any_tuple
cow_ptr<detail::abstract_tuple> m_vals;
explicit any_tuple(const cow_ptr<detail::abstract_tuple>& vals);
public:
//typedef cow_ptr<detail::abstract_tuple> vals_ptr;
......@@ -54,6 +56,8 @@ class any_tuple
bool equal_to(const any_tuple& other) const;
any_tuple tail() const;
};
inline bool operator==(const any_tuple& lhs, const any_tuple& rhs)
......
......@@ -19,9 +19,10 @@ struct abstract_tuple : ref_counted
virtual abstract_tuple* copy() const = 0;
virtual const void* at(size_t pos) const = 0;
virtual const util::abstract_type_list& types() const = 0;
virtual bool equal_to(const abstract_tuple& other) const = 0;
virtual const uniform_type_info& utype_info_at(size_t pos) const = 0;
virtual bool equal_to(const abstract_tuple& other) const;
};
} } // namespace cppa::detail
......
......@@ -49,44 +49,45 @@ class tuple_vals : public abstract_tuple
inline data_type& data_ref() { return m_data; }
virtual void* mutable_at(size_t pos)
void* mutable_at(size_t pos)
{
return tdata_mutable_at(m_data, pos);
}
virtual size_t size() const
size_t size() const
{
return sizeof...(ElementTypes);
}
virtual tuple_vals* copy() const
tuple_vals* copy() const
{
return new tuple_vals(*this);
}
virtual const void* at(size_t pos) const
const void* at(size_t pos) const
{
return tdata_at(m_data, pos);
}
virtual const uniform_type_info& utype_info_at(size_t pos) const
const uniform_type_info& utype_info_at(size_t pos) const
{
return m_types.at(pos);
}
virtual const util::abstract_type_list& types() const
const util::abstract_type_list& types() const
{
return m_types;
}
virtual bool equal_to(const abstract_tuple& other) const
bool equal_to(const abstract_tuple& other) const
{
if (size() != other.size()) return false;
const tuple_vals* o = dynamic_cast<const tuple_vals*>(&other);
if (o)
{
return m_data == (o->m_data);
}
return false;
return abstract_tuple::equal_to(other);
}
};
......
#include "cppa/detail/abstract_tuple.hpp"
namespace cppa { namespace detail {
bool abstract_tuple::equal_to(const abstract_tuple &other) const
{
if (this == &other) return true;
if (size() != other.size()) return false;
for (size_t i = 0; i < size(); ++i)
{
const cppa::uniform_type_info& uti = utype_info_at(i);
if (uti != other.utype_info_at(i)) return false;
auto lhs = at(i);
auto rhs = other.at(i);
// compare first addresses, then values
if (lhs != rhs && !(uti.equal(lhs, rhs))) return false;
}
return true;
}
} } // namespace cppa::detail
......@@ -70,6 +70,77 @@ const cppa::cow_ptr<cppa::detail::abstract_tuple>& s_empty_tuple()
return ptr;
}
struct offset_type_list : cppa::util::abstract_type_list
{
const_iterator begin() const
{
return m_begin;
}
offset_type_list(const cppa::util::abstract_type_list& decorated)
{
auto i = decorated.begin();
if (i != decorated.end())
{
++i;
}
m_begin = i;
}
private:
cppa::util::abstract_type_list::const_iterator m_begin;
};
struct offset_decorator : cppa::detail::abstract_tuple
{
typedef cppa::cow_ptr<cppa::detail::abstract_tuple> ptr_type;
offset_decorator(const ptr_type& decorated)
: m_decorated(decorated), m_type_list(decorated->types())
{
}
void* mutable_at(size_t pos)
{
return m_decorated->mutable_at(pos + 1);
}
size_t size() const
{
return m_decorated->size() - 1;
}
abstract_tuple* copy() const
{
return new offset_decorator(m_decorated);
}
const void* at(size_t pos) const
{
return m_decorated->at(pos + 1);
}
const cppa::util::abstract_type_list& types() const
{
return m_type_list;
}
const cppa::uniform_type_info& utype_info_at(size_t pos) const
{
return m_decorated->utype_info_at(pos + 1);
}
private:
ptr_type m_decorated;
offset_type_list m_type_list;
};
} // namespace <anonymous>
namespace cppa {
......@@ -87,12 +158,22 @@ any_tuple::any_tuple(any_tuple&& other) : m_vals(s_empty_tuple())
m_vals.swap(other.m_vals);
}
any_tuple::any_tuple(const cow_ptr<detail::abstract_tuple>& vals) : m_vals(vals)
{
}
any_tuple& any_tuple::operator=(any_tuple&& other)
{
m_vals.swap(other.m_vals);
return *this;
}
any_tuple any_tuple::tail() const
{
if (size() <= 1) return any_tuple(s_empty_tuple());
return any_tuple(new offset_decorator(m_vals));
}
size_t any_tuple::size() const
{
return m_vals->size();
......
......@@ -14,6 +14,7 @@
#include "cppa/invoke.hpp"
#include "cppa/get_view.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/to_string.hpp"
#include "cppa/tuple_view.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/intrusive_ptr.hpp"
......@@ -235,6 +236,19 @@ size_t test__tuple()
CPPA_CHECK(get<3>(t1_copy) == get<3>(t1));
CPPA_CHECK(t1 == t4);
// test any_tuple::tail
any_tuple at1 = make_tuple(1, 2, 3, 4.0, "5");
any_tuple at2 = make_tuple(2, 3, 4.0, "5");
any_tuple at1_tail = at1.tail();
CPPA_CHECK_EQUAL(at1.size(), (at1_tail.size() + 1));
CPPA_CHECK_EQUAL(at1_tail.size(), at2.size());
CPPA_CHECK_EQUAL(at1_tail.utype_info_at(0), at2.utype_info_at(0));
CPPA_CHECK((at2.utype_info_at(0).equal(at1_tail.at(0), at2.at(0))));
CPPA_CHECK_EQUAL(at2, at1_tail);
CPPA_CHECK_EQUAL(at1_tail, at2);
return CPPA_TEST_RESULT;
}
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