Commit 2b617824 authored by neverlord's avatar neverlord

tl_find

parent db465f8c
...@@ -96,7 +96,7 @@ class invoke_rule_builder ...@@ -96,7 +96,7 @@ class invoke_rule_builder
util::wrapped<raw_types> >::type util::wrapped<raw_types> >::type
types; types;
static_assert(types::template find<arg_match_t>::value == -1, static_assert(util::tl_find<types, arg_match_t>::value == -1,
"arg_match is allowed only as last parameter for on()"); "arg_match is allowed only as last parameter for on()");
typedef typename util::type_list_apply<types, typedef typename util::type_list_apply<types,
......
...@@ -55,11 +55,6 @@ struct type_list<> ...@@ -55,11 +55,6 @@ struct type_list<>
typedef void_type back_type; typedef void_type back_type;
typedef type_list<> tail_type; typedef type_list<> tail_type;
static const size_t size = 0; static const size_t size = 0;
template<typename, int = 0>
struct find
{
static const int value = -1;
};
}; };
template<typename Head, typename... Tail> template<typename Head, typename... Tail>
...@@ -100,20 +95,53 @@ struct type_list<Head, Tail...> ...@@ -100,20 +95,53 @@ struct type_list<Head, Tail...>
} }
} }
template<typename What, int Pos = 0>
struct find
{
static const int value = std::is_same<What,Head>::value
? Pos
: type_list<Tail...>::template find<What,Pos+1>::value;
};
private: private:
uti_ptr m_arr[size]; uti_ptr m_arr[size];
}; };
// type_list::find
template<class List, typename What, int Pos = 0>
struct tl_find;
template<typename What, int Pos>
struct tl_find<type_list<>, What, Pos>
{
static constexpr int value = -1;
};
template<typename What, int Pos, typename Head, typename... Tail>
struct tl_find<type_list<Head, Tail...>, What, Pos>
{
static constexpr int value = std::is_same<Head, What>::value
? Pos
: tl_find<type_list<Tail...>, What, Pos+1>::value;
};
// type_list::forall
/**
* @brief Tests whether a predicate holds for all elements of a list.
*/
template<class List, template <typename> class Predicate>
struct tl_forall
{
typedef typename List::head_type head_type;
typedef typename List::tail_type tail_type;
static const bool value =
Predicate<head_type>::value
&& tl_forall<tail_type, Predicate>::value;
};
template<template <typename> class Predicate>
struct tl_forall<type_list<>, Predicate>
{
static const bool value = true;
};
} } // namespace cppa::util } } // namespace cppa::util
#endif // LIBCPPA_UTIL_TYPE_LIST_HPP #endif // LIBCPPA_UTIL_TYPE_LIST_HPP
...@@ -6,40 +6,67 @@ ...@@ -6,40 +6,67 @@
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/pattern.hpp" #include "cppa/pattern.hpp"
#include "cppa/announce.hpp"
#include "cppa/util/enable_if.hpp"
#include "cppa/util/disable_if.hpp"
#include "cppa/util/conjunction.hpp"
#include "cppa/util/is_primitive.hpp"
using namespace cppa; using namespace cppa;
static uniform_type_info const* iinfo = uniform_typeid<int>(); static uniform_type_info const* iinfo = uniform_typeid<int>();
template<typename T> template<typename T>
struct uti_util struct is_builtin
{ {
static inline uniform_type_info const* get() { return uniform_typeid<T>(); } static constexpr bool value = std::is_arithmetic<T>::value;
}; };
template<> template<>
struct uti_util<anything> struct is_builtin<anything>
{ {
static inline uniform_type_info const* get() { return nullptr; } static constexpr bool value = true;
};
template<bool IsBuiltIn, typename T>
struct uti_util_impl
{
static inline uniform_type_info const* get()
{
return uniform_typeid<T>();
}
}; };
template<typename T> template<typename T>
struct tinfo_util struct uti_util_impl<false, T>
{ {
static inline std::type_info const* get() { return &(typeid(T)); } static inline uniform_type_info const* get()
{
return nullptr;
}
}; };
template<> template<>
struct tinfo_util<anything> struct uti_util_impl<true, anything>
{ {
static inline std::type_info const* get() { return nullptr; } static inline uniform_type_info const* get()
{
return nullptr;
}
}; };
template<typename T>
inline uniform_type_info const* get_uti_static()
{
return uti_util_impl<is_builtin<T>::value, T>::get();
}
template<bool BuiltinOnlyTypes, typename... T> template<bool BuiltinOnlyTypes, typename... T>
struct type_arr_base struct types_array_impl
{ {
uniform_type_info const* data[sizeof...(T)]; uniform_type_info const* data[sizeof...(T)];
type_arr_base() : data({uti_util<T>::get()...}) types_array_impl() : data({get_uti_static<T>()...})
{ {
} }
inline uniform_type_info const* operator[](size_t p) const inline uniform_type_info const* operator[](size_t p) const
...@@ -49,16 +76,55 @@ struct type_arr_base ...@@ -49,16 +76,55 @@ struct type_arr_base
inline size_t size() const { return sizeof...(T); } inline size_t size() const { return sizeof...(T); }
}; };
template<typename T>
struct tinfo_util
{
static inline std::type_info const* get()
{
return &(typeid(T));
}
};
template<>
struct tinfo_util<anything>
{
static inline std::type_info const* get()
{
return nullptr;
}
};
template<typename... T> template<typename... T>
struct type_arr_base<false, T...> struct types_array_impl<false, T...>
{ {
std::type_info const* data[sizeof...(T)]; std::type_info const* tinfo_data[sizeof...(T)];
type_arr_base() : data({tinfo_util<T>::get()...}) mutable std::atomic<uniform_type_info const*> data[sizeof...(T)];
types_array_impl() : tinfo_data({tinfo_util<T>::get()...})
{
bool static_init[sizeof...(T)] = { is_builtin<T>::value... };
for (size_t i = 0; i < sizeof...(T); ++i)
{
if (static_init[i])
{ {
auto x = tinfo_data[i];
if (x) data[i].store(uniform_typeid(*x));
} }
inline std::type_info const* operator[](size_t p) const }
}
inline uniform_type_info const* operator[](size_t p) const
{ {
return data[p]; auto x = data[p].load();
if (!x)
{
auto y = tinfo_data[p];
if (y)
{
auto result = uniform_typeid(*y);
data[p].store(result, std::memory_order_relaxed);
return result;
}
}
return x;
} }
inline size_t size() const inline size_t size() const
{ {
...@@ -66,20 +132,10 @@ struct type_arr_base<false, T...> ...@@ -66,20 +132,10 @@ struct type_arr_base<false, T...>
} }
}; };
template<typename T>
struct is_builtin
{
static constexpr bool value = std::is_arithmetic<T>::value;
};
template<>
struct is_builtin<anything>
{
static constexpr bool value = true;
};
template<typename... T> template<typename... T>
struct type_arr : type_arr_base<util::eval_type_list<util::type_list<T...>,is_builtin>::value, T...> struct types_array : types_array_impl<util::tl_forall<util::type_list<T...>,
is_builtin>::value,
T...>
{ {
}; };
...@@ -106,13 +162,15 @@ void plot(Arr const& arr) ...@@ -106,13 +162,15 @@ void plot(Arr const& arr)
cout << " }" << endl; cout << " }" << endl;
} }
class foobar { }; typedef std::pair<int,int> foobar;
static type_arr_base<true,int,anything,float> arr1; static types_array_impl<true,int,anything,float> arr1;
static type_arr_base<false,int,anything,foobar> arr2; static types_array_impl<false,int,anything,foobar> arr2;
size_t test__pattern() size_t test__pattern()
{ {
announce<foobar>(&foobar::first, &foobar::second);
cout << "iinfo->name() = " << iinfo->name() << endl; cout << "iinfo->name() = " << iinfo->name() << endl;
plot(arr1); plot(arr1);
......
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