Commit 2b617824 authored by neverlord's avatar neverlord

tl_find

parent db465f8c
......@@ -96,7 +96,7 @@ class invoke_rule_builder
util::wrapped<raw_types> >::type
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()");
typedef typename util::type_list_apply<types,
......
......@@ -55,11 +55,6 @@ struct type_list<>
typedef void_type back_type;
typedef type_list<> tail_type;
static const size_t size = 0;
template<typename, int = 0>
struct find
{
static const int value = -1;
};
};
template<typename Head, typename... 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:
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
#endif // LIBCPPA_UTIL_TYPE_LIST_HPP
......@@ -6,40 +6,67 @@
#include "cppa/atom.hpp"
#include "cppa/tuple.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;
static uniform_type_info const* iinfo = uniform_typeid<int>();
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<>
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>
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<>
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>
struct type_arr_base
struct types_array_impl
{
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
......@@ -49,16 +76,55 @@ struct type_arr_base
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>
struct type_arr_base<false, T...>
struct types_array_impl<false, T...>
{
std::type_info const* data[sizeof...(T)];
type_arr_base() : data({tinfo_util<T>::get()...})
std::type_info const* tinfo_data[sizeof...(T)];
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
{
......@@ -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>
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)
cout << " }" << endl;
}
class foobar { };
typedef std::pair<int,int> foobar;
static type_arr_base<true,int,anything,float> arr1;
static type_arr_base<false,int,anything,foobar> arr2;
static types_array_impl<true,int,anything,float> arr1;
static types_array_impl<false,int,anything,foobar> arr2;
size_t test__pattern()
{
announce<foobar>(&foobar::first, &foobar::second);
cout << "iinfo->name() = " << iinfo->name() << endl;
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