Commit d31dbe5d authored by Dominik Charousset's avatar Dominik Charousset

new iterator interface

parent b453aabb
...@@ -31,15 +31,16 @@ ...@@ -31,15 +31,16 @@
#ifndef ANY_TUPLE_HPP #ifndef ANY_TUPLE_HPP
#define ANY_TUPLE_HPP #define ANY_TUPLE_HPP
#include "cppa/cow_ptr.hpp"
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/config.hpp"
#include "cppa/cow_ptr.hpp"
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/detail/abstract_tuple.hpp"
namespace cppa { namespace cppa {
/** /**
* @brief Describes a fixed-length tuple with elements of any type. * @brief Describes a fixed-length copy-on-write tuple
* with elements of any type.
*/ */
class any_tuple class any_tuple
{ {
...@@ -61,6 +62,12 @@ class any_tuple ...@@ -61,6 +62,12 @@ class any_tuple
template<typename... Args> template<typename... Args>
any_tuple(tuple<Args...> const& t) : m_vals(t.vals()) { } any_tuple(tuple<Args...> const& t) : m_vals(t.vals()) { }
/**
* @brief Creates a tuple and moves the content from @p t.
*/
template<typename... Args>
any_tuple(tuple<Args...>&& t) : m_vals(std::move(t.m_vals)) { }
explicit any_tuple(detail::abstract_tuple*); explicit any_tuple(detail::abstract_tuple*);
/** /**
...@@ -83,45 +90,60 @@ class any_tuple ...@@ -83,45 +90,60 @@ class any_tuple
*/ */
any_tuple& operator=(any_tuple const&) = default; any_tuple& operator=(any_tuple const&) = default;
/**
* @brief Gets the size of this tuple.
*/
size_t size() const; size_t size() const;
/**
* @brief Gets a mutable pointer to the element at position @p p.
*/
void* mutable_at(size_t p); void* mutable_at(size_t p);
/**
* @brief Gets a const pointer to the element at position @p p.
*/
void const* at(size_t p) const; void const* at(size_t p) const;
/**
* @brief Gets {@link uniform_type_info uniform type information}
* of the element at position @p p.
*/
uniform_type_info const* type_at(size_t p) const; uniform_type_info const* type_at(size_t p) const;
cow_ptr<detail::abstract_tuple> const& vals() const; /**
* @brief Returns @c true if <tt>*this == other</tt>, otherwise false.
*/
bool equals(any_tuple const& other) const; bool equals(any_tuple const& other) const;
std::type_info const& impl_type() const; /**
* @brief Returns true if <tt>size() == 0</tt>, otherwise false.
*/
inline bool empty() const { return size() == 0; }
inline bool empty() const template<typename T>
inline T const& get_as(size_t p) const
{ {
return size() == 0; CPPA_REQUIRE(type_at(p) == typeid(T));
return *reinterpret_cast<T const*>(at(p));
} }
template<typename T> template<typename T>
inline T const& get_as(size_t p) const; inline T& get_mutable_as(size_t p)
{
CPPA_REQUIRE(type_at(p) == typeid(T));
return *reinterpret_cast<T*>(mutable_at(p));
}
template<typename T> typedef type_value_pair const* const_iterator;
inline T& get_mutable_as(size_t p);
class const_iterator inline const_iterator begin() const { return m_vals->begin(); }
{
any_tuple const& ref; inline const_iterator end() const { return m_vals->end(); }
size_t p;
public: std::type_info const& impl_type() const;
inline const_iterator(any_tuple const& data, size_t pos = 0)
: ref(data), p(pos) { } cow_ptr<detail::abstract_tuple> const& vals() const;
inline void next() { ++p; }
inline bool at_end() const { return p >= ref.size(); }
inline void const* value() const { return ref.at(p); }
inline uniform_type_info const* type() const { return ref.type_at(p); }
};
inline const_iterator begin() const { return {*this}; }
}; };
...@@ -135,18 +157,6 @@ inline bool operator!=(any_tuple const& lhs, any_tuple const& rhs) ...@@ -135,18 +157,6 @@ inline bool operator!=(any_tuple const& lhs, any_tuple const& rhs)
return !(lhs == rhs); return !(lhs == rhs);
} }
template<typename T>
inline T const& any_tuple::get_as(size_t p) const
{
return *reinterpret_cast<T const*>(at(p));
}
template<typename T>
inline T& any_tuple::get_mutable_as(size_t p)
{
return *reinterpret_cast<T*>(mutable_at(p));
}
} // namespace cppa } // namespace cppa
#endif // ANY_TUPLE_HPP #endif // ANY_TUPLE_HPP
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include <list> #include <list>
#include <vector> #include <vector>
#include <utility> #include <utility>
#include <iterator>
#include <algorithm>
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
...@@ -52,8 +54,7 @@ namespace cppa { ...@@ -52,8 +54,7 @@ namespace cppa {
class any_tuple_view class any_tuple_view
{ {
typedef std::vector< std::pair<uniform_type_info const*, void*> > typedef std::vector<type_value_pair> vector_type;
vector_type;
vector_type m_values; vector_type m_values;
...@@ -80,22 +81,14 @@ class any_tuple_view ...@@ -80,22 +81,14 @@ class any_tuple_view
any_tuple_view(any_tuple& tup) any_tuple_view(any_tuple& tup)
{ {
for (size_t i = 0; i < tup.size(); ++i) if (tup.size() > 0)
{
m_values.push_back(std::make_pair(tup.type_at(i), tup.mutable_at(i)));
}
}
/*
template<typename... T>
explicit any_tuple_view(tuple<T...> const& tup)
{
for (size_t i = 0; i < tup.size(); ++i)
{ {
m_values.push_back(std::make_pair(tup.type_at(i), tup.at(i))); // force tuple to detach
tup.mutable_at(0);
std::back_insert_iterator<vector_type> back_iter{m_values};
std::copy(tup.begin(), tup.end(), back_iter);
} }
} }
*/
template<typename... T> template<typename... T>
any_tuple_view(tuple_view<T...> const& tup) any_tuple_view(tuple_view<T...> const& tup)
...@@ -137,7 +130,7 @@ class any_tuple_view ...@@ -137,7 +130,7 @@ class any_tuple_view
inline void const* at(size_t p) const { return m_values[p].second; } inline void const* at(size_t p) const { return m_values[p].second; }
void* mutable_at(size_t p) { return m_values[p].second; } void* mutable_at(size_t p) { return const_cast<void*>(m_values[p].second); }
inline uniform_type_info const* type_at(size_t p) const inline uniform_type_info const* type_at(size_t p) const
{ {
...@@ -159,21 +152,11 @@ class any_tuple_view ...@@ -159,21 +152,11 @@ class any_tuple_view
return typeid(detail::object_array); return typeid(detail::object_array);
} }
class const_iterator typedef type_value_pair const* const_iterator;
{
typedef typename vector_type::const_iterator vec_iterator; inline const_iterator begin() const { return m_values.data(); }
vec_iterator pos;
vec_iterator end; inline const_iterator end() const { return begin() + m_values.size(); }
public:
inline const_iterator(any_tuple_view const& view)
: pos(view.m_values.begin()), end(view.m_values.end()) { }
inline void next() { ++pos; }
inline bool at_end() const { return pos == end; }
inline void const* value() const { return pos->second; }
inline uniform_type_info const* type() const { return pos->first; }
};
inline const_iterator begin() const { return {*this}; }
}; };
......
...@@ -48,6 +48,8 @@ struct abstract_tuple : ref_counted ...@@ -48,6 +48,8 @@ struct abstract_tuple : ref_counted
virtual void* mutable_at(size_t pos) = 0; virtual void* mutable_at(size_t pos) = 0;
// accessors // accessors
virtual const_iterator begin() const = 0;
virtual const_iterator end() const = 0;
virtual size_t size() const = 0; virtual size_t size() const = 0;
virtual abstract_tuple* copy() const = 0; virtual abstract_tuple* copy() const = 0;
virtual void const* at(size_t pos) const = 0; virtual void const* at(size_t pos) const = 0;
......
...@@ -51,30 +51,42 @@ template<typename... ElementTypes> ...@@ -51,30 +51,42 @@ template<typename... ElementTypes>
class decorated_tuple : public abstract_tuple class decorated_tuple : public abstract_tuple
{ {
static_assert(sizeof...(ElementTypes) > 0,
"decorated_tuple is not allowed to be empty");
public: public:
typedef util::fixed_vector<size_t, sizeof...(ElementTypes)> vector_type; typedef util::fixed_vector<size_t, sizeof...(ElementTypes)> vector_type;
typedef cow_ptr<abstract_tuple> ptr_type; typedef cow_ptr<abstract_tuple> ptr_type;
decorated_tuple(ptr_type&& d, vector_type const& v) using abstract_tuple::const_iterator;
: m_decorated(std::move(d)), m_mappings(v)
decorated_tuple(ptr_type&& d, vector_type const& v) : m_decorated(std::move(d))
{ {
CPPA_REQUIRE(v.size() == sizeof...(ElementTypes)); init(v);
CPPA_REQUIRE(std::max_element(v.begin(), v.end()) < m_decorated->size());
} }
decorated_tuple(ptr_type const& d, vector_type const& v) decorated_tuple(ptr_type const& d, vector_type const& v) : m_decorated(d)
: m_decorated(d), m_mappings(v)
{ {
CPPA_REQUIRE(v.size() == sizeof...(ElementTypes)); init(v);
CPPA_REQUIRE(v.empty() || *(std::max_element(v.begin(), v.end())) < m_decorated->size()); }
virtual const_iterator begin() const
{
return m_data;
}
virtual const_iterator end() const
{
return static_cast<const_iterator>(m_data) + sizeof...(ElementTypes);
} }
virtual void* mutable_at(size_t pos) virtual void* mutable_at(size_t pos)
{ {
CPPA_REQUIRE(pos < size()); CPPA_REQUIRE(pos < size());
return m_decorated->mutable_at(m_mappings[pos]); // const_cast is safe because decorated_tuple is used in cow_ptrs only
return const_cast<void*>(m_data[pos].second);
} }
virtual size_t size() const virtual size_t size() const
...@@ -90,18 +102,13 @@ class decorated_tuple : public abstract_tuple ...@@ -90,18 +102,13 @@ class decorated_tuple : public abstract_tuple
virtual void const* at(size_t pos) const virtual void const* at(size_t pos) const
{ {
CPPA_REQUIRE(pos < size()); CPPA_REQUIRE(pos < size());
return m_decorated->at(m_mappings[pos]); return m_data[pos].second;
} }
virtual uniform_type_info const* type_at(size_t pos) const virtual uniform_type_info const* type_at(size_t pos) const
{ {
CPPA_REQUIRE(pos < size()); CPPA_REQUIRE(pos < size());
return m_decorated->type_at(m_mappings[pos]); return m_data[pos].first;
}
virtual bool equals(abstract_tuple const&) const
{
return false;
} }
virtual std::type_info const& impl_type() const virtual std::type_info const& impl_type() const
...@@ -109,17 +116,29 @@ class decorated_tuple : public abstract_tuple ...@@ -109,17 +116,29 @@ class decorated_tuple : public abstract_tuple
return typeid(decorated_tuple); return typeid(decorated_tuple);
} }
private: private:
ptr_type m_decorated; ptr_type m_decorated;
vector_type m_mappings; type_value_pair m_data[sizeof...(ElementTypes)];
decorated_tuple(decorated_tuple const& other) decorated_tuple(decorated_tuple const& other)
: abstract_tuple() : abstract_tuple()
, m_decorated(other.m_decorated) , m_decorated(other.m_decorated)
, m_mappings(other.m_mappings)
{ {
// both instances point to the same data
std::copy(other.begin(), other.end(), m_data);
}
void init(vector_type const& v)
{
CPPA_REQUIRE(v.size() == sizeof...(ElementTypes));
CPPA_REQUIRE(*(std::max_element(v.begin(), v.end())) < m_decorated->size());
for (size_t i = 0; i < sizeof...(ElementTypes); ++i)
{
auto x = v[i];
m_data[i].first = m_decorated->type_at(x);
m_data[i].second = m_decorated->at(x);
}
} }
decorated_tuple& operator=(decorated_tuple const&) = delete; decorated_tuple& operator=(decorated_tuple const&) = delete;
......
...@@ -35,9 +35,13 @@ ...@@ -35,9 +35,13 @@
namespace cppa { namespace detail { namespace cppa { namespace detail {
struct empty_tuple : cppa::detail::abstract_tuple struct empty_tuple : abstract_tuple
{ {
using abstract_tuple::const_iterator;
const_iterator begin() const;
const_iterator end() const;
size_t size() const; size_t size() const;
void* mutable_at(size_t); void* mutable_at(size_t);
abstract_tuple* copy() const; abstract_tuple* copy() const;
......
This diff is collapsed.
...@@ -34,32 +34,37 @@ ...@@ -34,32 +34,37 @@
#include <vector> #include <vector>
#include "cppa/object.hpp" #include "cppa/object.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/detail/abstract_tuple.hpp"
namespace cppa { namespace detail { namespace cppa { namespace detail {
class object_array : public detail::abstract_tuple class object_array : public abstract_tuple
{ {
std::vector<object> m_elements; std::vector<object> m_elements;
std::vector<type_value_pair> m_data;
public: public:
using abstract_tuple::const_iterator;
object_array(); object_array();
object_array(object_array&& other); object_array(object_array&& other);
object_array(object_array const& other); object_array(object_array const& other);
/**
* @pre
*/
void push_back(object&& what); void push_back(object&& what);
void push_back(object const& what); void push_back(object const& what);
void* mutable_at(size_t pos); void* mutable_at(size_t pos);
const_iterator begin() const;
const_iterator end() const;
size_t size() const; size_t size() const;
abstract_tuple* copy() const; abstract_tuple* copy() const;
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include <stdexcept> #include <stdexcept>
#include "cppa/type_value_pair.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/detail/tdata.hpp" #include "cppa/detail/tdata.hpp"
...@@ -46,6 +48,9 @@ template<typename... ElementTypes> ...@@ -46,6 +48,9 @@ template<typename... ElementTypes>
class tuple_vals : public abstract_tuple class tuple_vals : public abstract_tuple
{ {
static_assert(sizeof...(ElementTypes) > 0,
"tuple_vals is not allowed to be empty");
typedef abstract_tuple super; typedef abstract_tuple super;
typedef tdata<ElementTypes...> data_type; typedef tdata<ElementTypes...> data_type;
...@@ -56,33 +61,45 @@ class tuple_vals : public abstract_tuple ...@@ -56,33 +61,45 @@ class tuple_vals : public abstract_tuple
static types_array<ElementTypes...> m_types; static types_array<ElementTypes...> m_types;
template<typename... Types> type_value_pair m_view[sizeof...(ElementTypes)];
void* tdata_mutable_at(tdata<Types...>& d, size_t pos)
{
return (pos == 0) ? &(d.head) : tdata_mutable_at(d.tail(), pos - 1);
}
template<typename... Types> void init_view()
void const* tdata_at(tdata<Types...> const& d, size_t pos) const
{ {
return (pos == 0) ? &(d.head) : tdata_at(d.tail(), pos - 1); for (size_t i = 0; i < sizeof...(ElementTypes); ++i)
{
m_view[i].first = m_types[i];
m_view[i].second = m_data.at(i);
}
} }
public: public:
tuple_vals(tuple_vals const& other) : super(), m_data(other.m_data) { } using abstract_tuple::const_iterator;
tuple_vals() : m_data() { } tuple_vals() : m_data() { init_view(); }
tuple_vals(ElementTypes const&... args) : m_data(args...) { } tuple_vals(tuple_vals const& other) : super(), m_data(other.m_data) { init_view(); }
inline data_type const& data() const { return m_data; } tuple_vals(ElementTypes const&... args) : m_data(args...) { init_view(); }
inline data_type& data_ref() { return m_data; } inline data_type const& data() const
{
return m_data;
}
void* mutable_at(size_t pos) inline data_type& data_ref()
{ {
return tdata_mutable_at(m_data, pos); return m_data;
}
const_iterator begin() const
{
return m_view;
}
const_iterator end() const
{
return begin() + sizeof...(ElementTypes);
} }
size_t size() const size_t size() const
...@@ -97,11 +114,20 @@ class tuple_vals : public abstract_tuple ...@@ -97,11 +114,20 @@ class tuple_vals : public abstract_tuple
void const* at(size_t pos) const void const* at(size_t pos) const
{ {
return tdata_at(m_data, pos); CPPA_REQUIRE(pos < size());
return m_view[pos].second;
}
void* mutable_at(size_t pos)
{
CPPA_REQUIRE(pos < size());
// safe, because tuple_cals is used in cow_ptrs only
return const_cast<void*>(m_view[pos].second);
} }
uniform_type_info const* type_at(size_t pos) const uniform_type_info const* type_at(size_t pos) const
{ {
CPPA_REQUIRE(pos < size());
return m_types[pos]; return m_types[pos];
} }
......
...@@ -73,6 +73,8 @@ class tuple ...@@ -73,6 +73,8 @@ class tuple
"illegal types in tuple definition: " "illegal types in tuple definition: "
"pointers and references are prohibited"); "pointers and references are prohibited");
friend class any_tuple;
typedef detail::tuple_vals<ElementTypes...> data_type; typedef detail::tuple_vals<ElementTypes...> data_type;
cow_ptr<detail::abstract_tuple> m_vals; cow_ptr<detail::abstract_tuple> m_vals;
...@@ -137,7 +139,6 @@ class tuple ...@@ -137,7 +139,6 @@ class tuple
/** /**
* @brief Gets the size of this tuple. * @brief Gets the size of this tuple.
* @returns <tt>sizeof...(ElementTypes)</tt>.
*/ */
inline size_t size() const inline size_t size() const
{ {
...@@ -145,14 +146,16 @@ class tuple ...@@ -145,14 +146,16 @@ class tuple
} }
/** /**
* @brief Gets a pointer to the internal data. * @brief Gets a const pointer to the element at position @p p.
* @returns A const void pointer to the <tt>N</tt>th element.
*/ */
inline void const* at(size_t p) const inline void const* at(size_t p) const
{ {
return m_vals->at(p); return m_vals->at(p);
} }
/**
* @brief Gets a mutable pointer to the element at position @p p.
*/
inline void* mutable_at(size_t p) inline void* mutable_at(size_t p)
{ {
return m_vals->mutable_at(p); return m_vals->mutable_at(p);
...@@ -160,26 +163,17 @@ class tuple ...@@ -160,26 +163,17 @@ class tuple
/** /**
* @brief Gets {@link uniform_type_info uniform type information} * @brief Gets {@link uniform_type_info uniform type information}
* of an element. * of the element at position @p p.
* @returns The uniform type of the <tt>N</tt>th element.
*/ */
inline uniform_type_info const* type_at(size_t p) const inline uniform_type_info const* type_at(size_t p) const
{ {
return m_vals->type_at(p); return m_vals->type_at(p);
} }
# ifdef CPPA_DOCUMENTATION
/**
* @brief Gets the internal data.
* @returns A pointer to the internal data representation.
*/
cow_ptr<InternalData> vals() const;
# else
inline cow_ptr<detail::abstract_tuple> const& vals() const inline cow_ptr<detail::abstract_tuple> const& vals() const
{ {
return m_vals; return m_vals;
} }
# endif
}; };
......
...@@ -70,24 +70,24 @@ class tuple_view ...@@ -70,24 +70,24 @@ class tuple_view
typedef util::type_list<ElementTypes...> types; typedef util::type_list<ElementTypes...> types;
static tuple_view from(std::vector< std::pair<uniform_type_info const*, void*> > const& vec) static tuple_view from(std::vector<type_value_pair> const& vec)
{ {
tuple_view result; tuple_view result;
size_t j = 0; size_t j = 0;
for (auto i = vec.begin(); i != vec.end(); ++i) for (type_value_pair const& tvp : vec)
{ {
result.m_data[j++] = i->second; result.m_data[j++] = const_cast<void*>(tvp.second);
} }
return std::move(result); return std::move(result);
} }
static tuple_view from(std::vector< std::pair<uniform_type_info const*, void*> > const& vec, static tuple_view from(std::vector<type_value_pair> const& vec,
util::fixed_vector<size_t, sizeof...(ElementTypes)> const& mv) util::fixed_vector<size_t, sizeof...(ElementTypes)> const& mv)
{ {
tuple_view result; tuple_view result;
for (size_t i = 0; i < sizeof...(ElementTypes); ++i) for (size_t i = 0; i < sizeof...(ElementTypes); ++i)
{ {
result.m_data[i] = vec[mv[i]].second; result.m_data[i] = const_cast<void*>(vec[mv[i]].second);
} }
return std::move(result); return std::move(result);
} }
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <algorithm> #include <algorithm>
#include <stdexcept> #include <stdexcept>
#include "cppa/config.hpp"
namespace cppa { namespace util { namespace cppa { namespace util {
// @warning does not perform any bound checks // @warning does not perform any bound checks
...@@ -62,7 +64,22 @@ class fixed_vector ...@@ -62,7 +64,22 @@ class fixed_vector
fixed_vector(fixed_vector const& other) : m_size(other.m_size) fixed_vector(fixed_vector const& other) : m_size(other.m_size)
{ {
std::copy(other.m_data, other.m_data + other.m_size, m_data); std::copy(other.begin(), other.end(), m_data);
}
void resize(size_type s)
{
CPPA_REQUIRE(s < MaxSize);
if (s > m_size)
{
auto x = T();
auto old_size = m_size;
for (auto i = old_size; i < s; ++i) push_back(x);
}
else
{
m_size = s;
}
} }
inline size_type size() const inline size_type size() const
...@@ -117,12 +134,12 @@ class fixed_vector ...@@ -117,12 +134,12 @@ class fixed_vector
inline iterator end() inline iterator end()
{ {
return (static_cast<T*>(m_data) + m_size); return (static_cast<iterator>(m_data) + m_size);
} }
inline const_iterator end() const inline const_iterator end() const
{ {
return (static_cast<T const*>(m_data) + m_size); return (static_cast<const_iterator>(m_data) + m_size);
} }
template<class InputIterator> template<class InputIterator>
......
...@@ -67,14 +67,14 @@ OUTPUT_LANGUAGE = English ...@@ -67,14 +67,14 @@ OUTPUT_LANGUAGE = English
# the file and class documentation (similar to JavaDoc). # the file and class documentation (similar to JavaDoc).
# Set to NO to disable this. # Set to NO to disable this.
BRIEF_MEMBER_DESC = NO BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description. # the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed. # brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES REPEAT_BRIEF = NO
# This tag implements a quasi-intelligent brief description abbreviator # This tag implements a quasi-intelligent brief description abbreviator
# that is used to form the text in various listings. Each string # that is used to form the text in various listings. Each string
......
...@@ -33,6 +33,16 @@ ...@@ -33,6 +33,16 @@
namespace cppa { namespace detail { namespace cppa { namespace detail {
abstract_tuple::const_iterator empty_tuple::begin() const
{
return nullptr;
}
abstract_tuple::const_iterator empty_tuple::end() const
{
return nullptr;
}
size_t empty_tuple::size() const size_t empty_tuple::size() const
{ {
return 0; return 0;
......
...@@ -49,11 +49,15 @@ object_array::object_array(object_array const& other) ...@@ -49,11 +49,15 @@ object_array::object_array(object_array const& other)
void object_array::push_back(object const& what) void object_array::push_back(object const& what)
{ {
m_elements.push_back(what); m_elements.push_back(what);
auto& back = m_elements.back();
m_data.push_back({back.type(), back.value()});
} }
void object_array::push_back(object&& what) void object_array::push_back(object&& what)
{ {
m_elements.push_back(std::move(what)); m_elements.push_back(std::move(what));
auto& back = m_elements.back();
m_data.push_back({back.type(), back.value()});
} }
void* object_array::mutable_at(size_t pos) void* object_array::mutable_at(size_t pos)
...@@ -76,6 +80,16 @@ void const* object_array::at(size_t pos) const ...@@ -76,6 +80,16 @@ void const* object_array::at(size_t pos) const
return m_elements[pos].value(); return m_elements[pos].value();
} }
abstract_tuple::const_iterator object_array::begin() const
{
return m_data.data();
}
abstract_tuple::const_iterator object_array::end() const
{
return begin() + m_data.size();
}
bool object_array::equals(cppa::detail::abstract_tuple const& ut) const bool object_array::equals(cppa::detail::abstract_tuple const& ut) const
{ {
if (size() == ut.size()) if (size() == ut.size())
......
...@@ -69,6 +69,7 @@ size_t test__pattern() ...@@ -69,6 +69,7 @@ size_t test__pattern()
pattern<int, anything, int> i3; pattern<int, anything, int> i3;
any_tuple i3_any_tup = make_tuple(1, 2, 3); any_tuple i3_any_tup = make_tuple(1, 2, 3);
/*
auto opt = tuple_cast(i3_any_tup, i3); auto opt = tuple_cast(i3_any_tup, i3);
CPPA_CHECK(opt.valid()); CPPA_CHECK(opt.valid());
if (opt.valid()) if (opt.valid())
...@@ -76,6 +77,7 @@ size_t test__pattern() ...@@ -76,6 +77,7 @@ size_t test__pattern()
CPPA_CHECK_EQUAL(get<0>(*opt), 1); CPPA_CHECK_EQUAL(get<0>(*opt), 1);
CPPA_CHECK_EQUAL(get<1>(*opt), 3); CPPA_CHECK_EQUAL(get<1>(*opt), 3);
} }
*/
announce<foobar>(&foobar::first, &foobar::second); announce<foobar>(&foobar::first, &foobar::second);
......
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