Commit 3f194ef3 authored by neverlord's avatar neverlord

maintenance

parent f0cd281c
...@@ -136,6 +136,7 @@ nobase_library_include_HEADERS = \ ...@@ -136,6 +136,7 @@ nobase_library_include_HEADERS = \
cppa/detail/tdata.hpp \ cppa/detail/tdata.hpp \
cppa/detail/thread_pool_scheduler.hpp \ cppa/detail/thread_pool_scheduler.hpp \
cppa/detail/to_uniform_name.hpp \ cppa/detail/to_uniform_name.hpp \
cppa/detail/tuple_cast_impl.hpp \
cppa/detail/tuple_vals.hpp \ cppa/detail/tuple_vals.hpp \
cppa/detail/type_to_ptype.hpp \ cppa/detail/type_to_ptype.hpp \
cppa/detail/types_array.hpp \ cppa/detail/types_array.hpp \
......
...@@ -244,12 +244,10 @@ cppa/util/type_pair.hpp ...@@ -244,12 +244,10 @@ cppa/util/type_pair.hpp
cppa/util/tbind.hpp cppa/util/tbind.hpp
cppa/option.hpp cppa/option.hpp
cppa/tuple_cast.hpp cppa/tuple_cast.hpp
cppa/detail/matches.hpp
cppa/util/is_mutable_ref.hpp cppa/util/is_mutable_ref.hpp
cppa/util/is_manipulator.hpp cppa/util/is_manipulator.hpp
cppa/util/apply_tuple.hpp cppa/util/apply_tuple.hpp
cppa/any_tuple_view.hpp cppa/any_tuple_view.hpp
cppa/match.hpp
benchmarks/Matching.scala benchmarks/Matching.scala
benchmarks/matching.cpp benchmarks/matching.cpp
benchmarks/matching.erl benchmarks/matching.erl
...@@ -262,3 +260,5 @@ cppa/type_value_pair.hpp ...@@ -262,3 +260,5 @@ cppa/type_value_pair.hpp
examples/dining_philosophers.cpp examples/dining_philosophers.cpp
cppa/detail/disablable_delete.hpp cppa/detail/disablable_delete.hpp
unit_testing/test__fixed_vector.cpp unit_testing/test__fixed_vector.cpp
cppa/detail/tuple_cast_impl.hpp
cppa/match.hpp
...@@ -101,13 +101,34 @@ struct abstract_tuple : ref_counted ...@@ -101,13 +101,34 @@ struct abstract_tuple : ref_counted
return {m_tuple, m_pos + offset}; return {m_tuple, m_pos + offset};
} }
inline const_iterator& operator+=(size_t offset)
{
m_pos += offset;
return *this;
}
inline const_iterator operator-(size_t offset)
{
CPPA_REQUIRE(m_pos >= offset);
return {m_tuple, m_pos - offset};
}
inline const_iterator& operator-=(size_t offset)
{
CPPA_REQUIRE(m_pos >= offset);
m_pos -= offset;
return *this;
}
inline size_t position() const { return m_pos; } inline size_t position() const { return m_pos; }
void const* value() const { return m_tuple.at(m_pos); } void const* value() const { return m_tuple.at(m_pos); }
uniform_type_info const* type() const { return m_tuple.type_at(m_pos); } uniform_type_info const* type() const { return m_tuple.type_at(m_pos); }
type_value_pair operator*() { return {type(), value()}; } const_iterator& operator*() { return *this; }
operator type_value_pair() const { return {type(), value()}; }
}; };
...@@ -117,6 +138,27 @@ struct abstract_tuple : ref_counted ...@@ -117,6 +138,27 @@ struct abstract_tuple : ref_counted
}; };
inline bool full_eq(abstract_tuple::const_iterator const& lhs,
type_value_pair const& rhs)
{
return lhs.type() == rhs.first
&& ( rhs.second == nullptr
|| lhs.type()->equals(lhs.value(), rhs.second));
}
inline bool values_only_eq(abstract_tuple::const_iterator const& lhs,
type_value_pair const& rhs)
{
return rhs.second == nullptr
|| lhs.type()->equals(lhs.value(), rhs.second);
}
inline bool types_only_eq(abstract_tuple::const_iterator const& lhs,
type_value_pair const& rhs)
{
return lhs.type() == rhs.first;
}
} } // namespace cppa::detail } } // namespace cppa::detail
#endif // ABSTRACT_TUPLE_HPP #endif // ABSTRACT_TUPLE_HPP
...@@ -40,8 +40,10 @@ ...@@ -40,8 +40,10 @@
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/apply_tuple.hpp"
#include "cppa/util/fixed_vector.hpp" #include "cppa/util/fixed_vector.hpp"
#include "cppa/detail/tuple_vals.hpp"
#include "cppa/detail/abstract_tuple.hpp" #include "cppa/detail/abstract_tuple.hpp"
#include "cppa/detail/serialize_tuple.hpp" #include "cppa/detail/serialize_tuple.hpp"
...@@ -71,11 +73,16 @@ class decorated_tuple : public abstract_tuple ...@@ -71,11 +73,16 @@ class decorated_tuple : public abstract_tuple
return {(new decorated_tuple(std::move(d)))->init()}; return {(new decorated_tuple(std::move(d)))->init()};
} }
// creates a subtuple form @p d with an offset
static cow_pointer_type create(cow_pointer_type d, size_t offset)
{
return {(new decorated_tuple(std::move(d)))->init(offset)};
}
virtual void* mutable_at(size_t pos) virtual void* mutable_at(size_t pos)
{ {
CPPA_REQUIRE(pos < size()); CPPA_REQUIRE(pos < size());
// const_cast is safe because decorated_tuple is used in cow_ptrs only return m_decorated->mutable_at(m_mapping[pos]);
return const_cast<void*>(m_data[pos].second);
} }
virtual size_t size() const virtual size_t size() const
...@@ -91,13 +98,13 @@ class decorated_tuple : public abstract_tuple ...@@ -91,13 +98,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_data[pos].second; return m_decorated->at(m_mapping[pos]);
} }
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_data[pos].first; return m_decorated->type_at(m_mapping[pos]);
} }
virtual std::type_info const& impl_type() const virtual std::type_info const& impl_type() const
...@@ -108,7 +115,7 @@ class decorated_tuple : public abstract_tuple ...@@ -108,7 +115,7 @@ class decorated_tuple : public abstract_tuple
private: private:
cow_pointer_type m_decorated; cow_pointer_type m_decorated;
type_value_pair m_data[sizeof...(ElementTypes)]; vector_type m_mapping;
decorated_tuple(cow_pointer_type const& d) : m_decorated(d) { } decorated_tuple(cow_pointer_type const& d) : m_decorated(d) { }
...@@ -117,9 +124,8 @@ class decorated_tuple : public abstract_tuple ...@@ -117,9 +124,8 @@ class decorated_tuple : public abstract_tuple
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_mapping(other.m_mapping)
{ {
// both instances point to the same data
std::copy(other.begin(), other.end(), m_data);
} }
decorated_tuple* init(vector_type const& v) decorated_tuple* init(vector_type const& v)
...@@ -127,24 +133,26 @@ class decorated_tuple : public abstract_tuple ...@@ -127,24 +133,26 @@ class decorated_tuple : public abstract_tuple
CPPA_REQUIRE(m_decorated->size() >= sizeof...(ElementTypes)); CPPA_REQUIRE(m_decorated->size() >= sizeof...(ElementTypes));
CPPA_REQUIRE(v.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())) < m_decorated->size());
for (size_t i = 0; i < sizeof...(ElementTypes); ++i) m_mapping.resize(v.size());
{ std::copy(v.begin(), v.end(), m_mapping.begin());
auto x = v[i];
m_data[i].first = m_decorated->type_at(x);
m_data[i].second = m_decorated->at(x);
}
return this; return this;
} }
decorated_tuple* init() decorated_tuple* init()
{ {
CPPA_REQUIRE(m_decorated->size() >= sizeof...(ElementTypes)); CPPA_REQUIRE(m_decorated->size() >= sizeof...(ElementTypes));
// copy first n elements size_t i = 0;
for (size_t i = 0; i < sizeof...(ElementTypes); ++i) m_mapping.resize(sizeof...(ElementTypes));
{ std::generate(m_mapping.begin(), m_mapping.end(), [&](){return i++;});
m_data[i].first = m_decorated->type_at(i); return this;
m_data[i].second = m_decorated->at(i);
} }
decorated_tuple* init(size_t offset)
{
CPPA_REQUIRE((m_decorated->size() - offset) == sizeof...(ElementTypes));
size_t i = offset;
m_mapping.resize(sizeof...(ElementTypes));
std::generate(m_mapping.begin(), m_mapping.end(), [&](){return i++;});
return this; return this;
} }
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include "cppa/match.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/tuple_cast.hpp" #include "cppa/tuple_cast.hpp"
#include "cppa/util/duration.hpp" #include "cppa/util/duration.hpp"
...@@ -42,7 +43,6 @@ ...@@ -42,7 +43,6 @@
#include "cppa/util/fixed_vector.hpp" #include "cppa/util/fixed_vector.hpp"
#include "cppa/util/callable_trait.hpp" #include "cppa/util/callable_trait.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/intermediate.hpp" #include "cppa/detail/intermediate.hpp"
// forward declaration // forward declaration
...@@ -183,7 +183,7 @@ class invokable_impl<0, Fun, Tuple, Pattern> : public invokable ...@@ -183,7 +183,7 @@ class invokable_impl<0, Fun, Tuple, Pattern> : public invokable
template<typename T> template<typename T>
bool invoke_impl(T const& data) const bool invoke_impl(T const& data) const
{ {
if (matches(data, *m_pattern)) if (match(data, *m_pattern))
{ {
m_iimpl.m_fun(); m_iimpl.m_fun();
return true; return true;
...@@ -206,7 +206,7 @@ class invokable_impl<0, Fun, Tuple, Pattern> : public invokable ...@@ -206,7 +206,7 @@ class invokable_impl<0, Fun, Tuple, Pattern> : public invokable
intermediate* get_intermediate(any_tuple const& data) intermediate* get_intermediate(any_tuple const& data)
{ {
return matches(data, *m_pattern) ? &m_iimpl : nullptr; return match(data, *m_pattern) ? &m_iimpl : nullptr;
} }
}; };
......
This diff is collapsed.
This diff is collapsed.
...@@ -74,11 +74,6 @@ class tuple_vals : public abstract_tuple ...@@ -74,11 +74,6 @@ class tuple_vals : public abstract_tuple
return m_data; return m_data;
} }
inline data_type& data_ref()
{
return m_data;
}
size_t size() const size_t size() const
{ {
return sizeof...(ElementTypes); return sizeof...(ElementTypes);
......
This diff is collapsed.
...@@ -119,24 +119,32 @@ class tuple ...@@ -119,24 +119,32 @@ class tuple
tuple& operator=(tuple&&) = default; tuple& operator=(tuple&&) = default;
tuple& operator=(tuple const&) = default; tuple& operator=(tuple const&) = default;
static tuple from(cow_ptr_type ptr) inline static tuple from(cow_ptr_type ptr)
{ {
if (ptr->size() == sizeof...(ElementTypes))
{
// *this == *ptr
return {priv_ctor(), std::move(ptr)}; return {priv_ctor(), std::move(ptr)};
} }
else
inline static tuple from(cow_ptr_type ptr,
util::fixed_vector<size_t, num_elements> const& mv)
{ {
// *this is a subtuple of *ptr return {priv_ctor(), decorated_type::create(std::move(ptr), mv)};
return {priv_ctor(), decorated_type::create(std::move(ptr))};
} }
// *this is a [0, N) subtuple
inline static tuple subtuple(cow_ptr_type ptr)
{
// N == ptr->size() ?
if (ptr->size() == num_elements) return from(std::move(ptr));
// no, create subtuple
return {priv_ctor(), decorated_type::create(std::move(ptr))};
} }
static tuple from(cow_ptr_type ptr, inline static tuple offset_subtuple(cow_ptr_type ptr, size_t offset)
util::fixed_vector<size_t, num_elements> const& mv)
{ {
return {priv_ctor(), decorated_type::create(std::move(ptr), mv)}; // N == ptr->size() ?
if (ptr->size() == num_elements) return from(std::move(ptr));
// no, create subtuple
return {priv_ctor(), decorated_type::create(std::move(ptr), offset)};
} }
/** /**
......
...@@ -35,93 +35,23 @@ ...@@ -35,93 +35,23 @@
#include "cppa/option.hpp" #include "cppa/option.hpp"
#include "cppa/pattern.hpp" #include "cppa/pattern.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/types_array.hpp"
#include "cppa/detail/decorated_tuple.hpp"
#include "cppa/detail/implicit_conversions.hpp"
namespace cppa { #include "cppa/detail/tuple_cast_impl.hpp"
// cast using a pattern namespace cppa {
template<class ResultTuple, class Tuple, typename... P>
option<ResultTuple> tuple_cast_impl(Tuple const& tup, pattern<P...> const& p)
{
typedef util::type_list<P...> types;
static constexpr int apos = util::tl_find<types, anything>::value;
// no anything in given template parameter pack
// or anything at end of template parameter pack
if (apos == -1 || apos == (sizeof...(P) - 1))
{
if (detail::matches(tup, p))
{
return {ResultTuple::from(tup.vals())};
}
}
else
{
typename pattern<P...>::mapping_vector mv;
if (detail::matches(tup, p, &mv))
{
if (mv.size() == tup.size()) // perfect match
{
return {ResultTuple::from(tup.vals())};
}
else
{
return {ResultTuple::from(tup.vals(), mv)};
}
}
}
return { };
}
// cast using types
template<class ResultTuple, class Tuple, typename... T>
option<ResultTuple> tuple_cast_impl(Tuple const& tup)
{
typedef util::type_list<T...> types;
static constexpr int apos = util::tl_find<types, anything>::value;
// no anything in given template parameter pack
// or anything at end of template parameter pack
if (apos == -1 || apos == (sizeof...(T) - 1))
{
if (tup.size() >= sizeof...(T))
{
auto& tarr = detail::static_types_array<T...>::arr;
static constexpr int end = (apos == -1) ? sizeof...(T) : apos;
for (int i = 0; i < end; ++i)
{
if (tarr[i] != tup.type_at(i)) return { };
}
// always a perfect match or subtuple
return {ResultTuple::from(tup.vals())};
}
}
else
{
util::fixed_vector<size_t, ResultTuple::num_elements> mv;
if (detail::matches(tup, detail::static_types_array<T...>::arr, &mv))
{
// never a perfect match
return {ResultTuple::from(tup.vals(), mv)};
}
}
return { };
}
// cast using a pattern // cast using a pattern
template<typename... P> template<typename... T>
auto tuple_cast(any_tuple const& tup, pattern<P...> const& p) auto tuple_cast(any_tuple const& tup, pattern<T...> const& p)
-> option< -> option<
typename tuple_from_type_list< typename tuple_from_type_list<
typename pattern<P...>::filtered_types typename pattern<T...>::filtered_types
>::type> >::type>
{ {
typedef typename pattern<P...>::filtered_types filtered_types; typedef typename pattern<T...>::filtered_types filtered_types;
typedef typename tuple_from_type_list<filtered_types>::type tuple_type; typedef typename tuple_from_type_list<filtered_types>::type tuple_type;
return tuple_cast_impl<tuple_type, any_tuple, P...>(tup, p); static constexpr auto impl = detail::select_tuple_cast_impl<T...>::value;
return detail::tuple_cast_impl<impl, tuple_type, T...>::_(tup, p);
} }
// cast using types // cast using types
...@@ -137,38 +67,9 @@ auto tuple_cast(any_tuple const& tup) ...@@ -137,38 +67,9 @@ auto tuple_cast(any_tuple const& tup)
{ {
typedef decltype(tuple_cast<T...>(tup)) result_type; typedef decltype(tuple_cast<T...>(tup)) result_type;
typedef typename result_type::value_type tuple_type; typedef typename result_type::value_type tuple_type;
return tuple_cast_impl<tuple_type, any_tuple, T...>(tup); static constexpr auto impl = detail::select_tuple_cast_impl<T...>::value;
} return detail::tuple_cast_impl<impl, tuple_type, T...>::_(tup);
/*
template<typename... P>
auto tuple_cast(any_tuple_view const& tup, pattern<P...> const& p)
-> option<
typename tuple_view_from_type_list<
typename pattern<P...>::filtered_types
>::type>
{
typedef typename pattern<P...>::filtered_types filtered_types;
typedef typename tuple_view_from_type_list<filtered_types>::type tuple_type;
return tuple_cast_impl<tuple_type, any_tuple_view, P...>(tup, p);
}
// cast using types
template<typename... T>
auto tuple_cast(any_tuple_view const& tup)
-> option<
typename tuple_view_from_type_list<
typename util::tl_filter_not<
util::type_list<T...>,
util::tbind<std::is_same, anything>::type
>::type
>::type>
{
typedef decltype(tuple_cast<T...>(tup)) result_type;
typedef typename result_type::value_type tuple_type;
return tuple_cast_impl<tuple_type, any_tuple_view, T...>(tup);
} }
*/
} // namespace cppa } // namespace cppa
......
...@@ -84,18 +84,9 @@ class fixed_vector ...@@ -84,18 +84,9 @@ class fixed_vector
void resize(size_type s) void resize(size_type s)
{ {
CPPA_REQUIRE(s < MaxSize); 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; m_size = s;
} }
}
fixed_vector(std::initializer_list<T> init) : m_size(init.size()) fixed_vector(std::initializer_list<T> init) : m_size(init.size())
{ {
......
...@@ -135,14 +135,21 @@ template<typename What, int Pos> ...@@ -135,14 +135,21 @@ template<typename What, int Pos>
struct tl_find<type_list<>, What, Pos> struct tl_find<type_list<>, What, Pos>
{ {
static constexpr int value = -1; static constexpr int value = -1;
typedef type_list<> rest_list;
};
template<typename What, int Pos, typename... Tail>
struct tl_find<type_list<What, Tail...>, What, Pos>
{
static constexpr int value = Pos;
typedef type_list<Tail...> rest_list;
}; };
template<typename What, int Pos, typename Head, typename... Tail> template<typename What, int Pos, typename Head, typename... Tail>
struct tl_find<type_list<Head, Tail...>, What, Pos> struct tl_find<type_list<Head, Tail...>, What, Pos>
{ {
static constexpr int value = std::is_same<Head, What>::value static constexpr int value = tl_find<type_list<Tail...>, What, Pos+1>::value;
? Pos typedef typename tl_find<type_list<Tail...>, What, Pos+1>::rest_list rest_list;
: tl_find<type_list<Tail...>, What, Pos+1>::value;
}; };
// list list::first_n(size_t) // list list::first_n(size_t)
...@@ -209,6 +216,45 @@ struct tl_exists<type_list<>, Predicate> ...@@ -209,6 +216,45 @@ struct tl_exists<type_list<>, Predicate>
static constexpr bool value = false; static constexpr bool value = false;
}; };
// size_t list::count(predicate)
/**
* @brief Counts the number of elements in the list which satisfy a predicate.
*/
template<class List, template <typename> class Predicate>
struct tl_count
{
static constexpr size_t value =
(Predicate<typename List::head>::value ? 1 : 0)
+ tl_count<typename List::tail, Predicate>::value;
};
template<template <typename> class Predicate>
struct tl_count<type_list<>, Predicate>
{
static constexpr size_t value = 0;
};
// size_t list::count_not(predicate)
/**
* @brief Counts the number of elements in the list which satisfy a predicate.
*/
template<class List, template <typename> class Predicate>
struct tl_count_not
{
static constexpr size_t value =
(Predicate<typename List::head>::value ? 0 : 1)
+ tl_count_not<typename List::tail, Predicate>::value;
};
template<template <typename> class Predicate>
struct tl_count_not<type_list<>, Predicate>
{
static constexpr size_t value = 0;
};
// bool list::zipped_forall(predicate) // bool list::zipped_forall(predicate)
/** /**
......
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
#include <algorithm> #include <algorithm>
#include "cppa/self.hpp" #include "cppa/self.hpp"
#include "cppa/match.hpp"
#include "cppa/exception.hpp" #include "cppa/exception.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/invokable.hpp" #include "cppa/detail/invokable.hpp"
#include "cppa/detail/intermediate.hpp" #include "cppa/detail/intermediate.hpp"
#include "cppa/detail/converted_thread_context.hpp" #include "cppa/detail/converted_thread_context.hpp"
...@@ -100,10 +100,11 @@ void converted_thread_context::dequeue(timed_invoke_rules& rules) /*override*/ ...@@ -100,10 +100,11 @@ void converted_thread_context::dequeue(timed_invoke_rules& rules) /*override*/
} }
while (dq(node, rules, buffer) == false); while (dq(node, rules, buffer) == false);
} }
converted_thread_context::throw_on_exit_result converted_thread_context::throw_on_exit_result
converted_thread_context::throw_on_exit(any_tuple const& msg) converted_thread_context::throw_on_exit(any_tuple const& msg)
{ {
if (matches(msg, m_exit_msg_pattern)) if (match(msg, m_exit_msg_pattern))
{ {
auto reason = msg.get_as<std::uint32_t>(1); auto reason = msg.get_as<std::uint32_t>(1);
if (reason != exit_reason::normal) if (reason != exit_reason::normal)
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#include "cppa/on.hpp" #include "cppa/on.hpp"
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/tuple.hpp"
#include "cppa/match.hpp" #include "cppa/match.hpp"
#include "cppa/tuple.hpp"
#include "cppa/option.hpp" #include "cppa/option.hpp"
#include "cppa/pattern.hpp" #include "cppa/pattern.hpp"
#include "cppa/announce.hpp" #include "cppa/announce.hpp"
......
...@@ -39,30 +39,14 @@ size_t test__tuple() ...@@ -39,30 +39,14 @@ size_t test__tuple()
CPPA_CHECK((std::is_same<decltype(t0_1), int>::value)); CPPA_CHECK((std::is_same<decltype(t0_1), int>::value));
CPPA_CHECK_EQUAL(t0_0, "1"); CPPA_CHECK_EQUAL(t0_0, "1");
CPPA_CHECK_EQUAL(t0_1, 2); CPPA_CHECK_EQUAL(t0_1, 2);
// get a view of t0
any_tuple atup0(t0);
CPPA_CHECK(atup0.size() == 2 && atup0.at(0) == &get<0>(t0));
/*
auto v1opt = tuple_cast<std::string, anything>(any_tuple_view(atup0));
// the tuple_view forces atup0 to detach from t0
CPPA_CHECK(atup0.size() == 2 && atup0.at(0) != &get<0>(t0));
CPPA_CHECK((v1opt));
if (v1opt)
{
auto& v1 = *v1opt;
CPPA_CHECK((std::is_same<decltype(v1), tuple_view<std::string>&>::value));
CPPA_CHECK_EQUAL(v1.size(), 1);
auto& v1_0 = get<0>(v1);
CPPA_CHECK_EQUAL(v1_0, "1");
CPPA_CHECK_EQUAL(atup0.at(0), &(get<0>(v1))); // point to the same
}
*/
// use tuple cast to get a subtuple // use tuple cast to get a subtuple
any_tuple at0(t0); any_tuple at0(t0);
auto v0opt = tuple_cast<std::string, anything>(at0); auto v0opt = tuple_cast<std::string, anything>(at0);
CPPA_CHECK((std::is_same<decltype(v0opt), option<tuple<std::string>>>::value)); CPPA_CHECK((std::is_same<decltype(v0opt), option<tuple<std::string>>>::value));
CPPA_CHECK((v0opt)); CPPA_CHECK((v0opt));
CPPA_CHECK(at0.size() == 2 && at0.at(0) == &get<0>(t0)); CPPA_CHECK( at0.size() == 2
&& at0.at(0) == &get<0>(t0)
&& at0.at(1) == &get<1>(t0));
if (v0opt) if (v0opt)
{ {
auto& v0 = *v0opt; auto& v0 = *v0opt;
...@@ -84,5 +68,24 @@ size_t test__tuple() ...@@ -84,5 +68,24 @@ size_t test__tuple()
CPPA_CHECK_EQUAL(lhs, rhs); CPPA_CHECK_EQUAL(lhs, rhs);
CPPA_CHECK_EQUAL(rhs, lhs); CPPA_CHECK_EQUAL(rhs, lhs);
} }
any_tuple at1 = make_tuple("one", 2, 3.f, 4.0);
{
// perfect match
auto opt0 = tuple_cast<std::string, int, float, double>(at1);
CPPA_CHECK(opt0);
if (opt0) { CPPA_CHECK_EQUAL(*opt0, make_tuple("one", 2, 3.f, 4.0)); }
// leading wildcard
auto opt1 = tuple_cast<anything, double>(at1);
CPPA_CHECK(opt1);
if (opt1) { CPPA_CHECK_EQUAL(get<0>(*opt1), 4.0); }
// trailing wildcard
auto opt2 = tuple_cast<std::string, anything>(at1);
CPPA_CHECK(opt2);
if (opt2) { CPPA_CHECK_EQUAL(get<0>(*opt2), "one"); }
// wildcard in between
auto opt3 = tuple_cast<std::string, anything, double>(at1);
CPPA_CHECK(opt3);
if (opt3) { CPPA_CHECK_EQUAL(*opt3, make_tuple("one", 4.0)); }
}
return CPPA_TEST_RESULT; 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