Commit 19dca133 authored by Dominik Charousset's avatar Dominik Charousset

types_array

parent 2b617824
...@@ -137,6 +137,7 @@ nobase_library_include_HEADERS = \ ...@@ -137,6 +137,7 @@ nobase_library_include_HEADERS = \
cppa/detail/to_uniform_name.hpp \ cppa/detail/to_uniform_name.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/unboxed.hpp \ cppa/detail/unboxed.hpp \
cppa/detail/uniform_type_info_map.hpp \ cppa/detail/uniform_type_info_map.hpp \
cppa/detail/yield_interface.hpp \ cppa/detail/yield_interface.hpp \
......
...@@ -256,3 +256,5 @@ benchmarks/MixedCase.scala ...@@ -256,3 +256,5 @@ benchmarks/MixedCase.scala
cppa/util/default_deallocator.hpp cppa/util/default_deallocator.hpp
cppa/util/producer_consumer_list.hpp cppa/util/producer_consumer_list.hpp
cppa/util/arg_match_t.hpp cppa/util/arg_match_t.hpp
cppa/detail/types_array.hpp
cppa/util/is_builtin.hpp
#ifndef TYPES_ARRAY_HPP
#define TYPES_ARRAY_HPP
#include <typeinfo>
#include "cppa/util/type_list.hpp"
#include "cppa/util/is_builtin.hpp"
// forward declarations
namespace cppa {
class uniform_type_info;
uniform_type_info const* uniform_typeid(std::type_info const&);
} // namespace cppa
namespace cppa { namespace detail {
enum type_info_impl { std_tinf, cppa_tinf };
// some metaprogramming utility
template<type_info_impl What, bool IsBuiltin, typename T>
struct ta_util;
template<bool IsBuiltin, typename T>
struct ta_util<std_tinf, IsBuiltin, T>
{
static inline std::type_info const* get() { return &(typeid(T)); }
};
template<>
struct ta_util<std_tinf, true, anything>
{
static inline std::type_info const* get() { return nullptr; }
};
template<typename T>
struct ta_util<cppa_tinf, true, T>
{
static inline uniform_type_info const* get()
{
return uniform_typeid(typeid(T));
}
};
template<>
struct ta_util<cppa_tinf, true, anything>
{
static inline uniform_type_info const* get() { return nullptr; }
};
template<typename T>
struct ta_util<cppa_tinf, false, T>
{
static inline uniform_type_info const* get() { return nullptr; }
};
// implements types_array
template<bool BuiltinOnlyTypes, typename... T>
struct types_array_impl
{
// all types are builtin, perform lookup on constuction
uniform_type_info const* data[sizeof...(T)];
types_array_impl()
: data({ta_util<cppa_tinf,util::is_builtin<T>::value,T>::get()...})
{
}
inline size_t size() const { return sizeof...(T); }
inline uniform_type_info const* operator[](size_t p) const
{
return data[p];
}
};
template<typename... T>
struct types_array_impl<false, T...>
{
// contains std::type_info for all non-builtin types
std::type_info const* tinfo_data[sizeof...(T)];
// contains uniform_type_infos for builtin types and lazy initializes
// non-builtin types at runtime
mutable std::atomic<uniform_type_info const*> data[sizeof...(T)];
types_array_impl()
: tinfo_data({ta_util<std_tinf,util::is_builtin<T>::value,T>::get()...})
{
bool static_init[sizeof...(T)] = { !std::is_same<T,anything>::value
&& util::is_builtin<T>::value ... };
for (size_t i = 0; i < sizeof...(T); ++i)
{
if (static_init[i])
{
data[i].store(uniform_typeid(*(tinfo_data[i])),
std::memory_order_relaxed);
}
}
}
inline size_t size() const { return sizeof...(T); }
inline uniform_type_info const* operator[](size_t p) const
{
auto result = data[p].load();
if (result == nullptr)
{
auto tinfo = tinfo_data[p];
if (tinfo != nullptr)
{
result = uniform_typeid(*tinfo);
data[p].store(result, std::memory_order_relaxed);
}
}
return result;
}
};
template<typename... T>
struct types_array : types_array_impl<util::tl_forall<util::type_list<T...>,
util::is_builtin>::value,
T...>
{
};
} } // namespace cppa::detail
#endif // TYPES_ARRAY_HPP
#ifndef IS_BUILTIN_HPP
#define IS_BUILTIN_HPP
#include <type_traits>
#include "cppa/anything.hpp"
namespace cppa { namespace util {
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;
};
} } // namespace cppa::util
#endif // IS_BUILTIN_HPP
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include "cppa/detail/task_scheduler.hpp" #include "cppa/detail/task_scheduler.hpp"
#include "cppa/detail/thread_pool_scheduler.hpp" #include "cppa/detail/thread_pool_scheduler.hpp"
// header for experimental stuff // header for experimental stuff
#include "cppa/util/filter_type_list.hpp" #include "cppa/util/filter_type_list.hpp"
#include "cppa/util/any_tuple_iterator.hpp" #include "cppa/util/any_tuple_iterator.hpp"
...@@ -162,14 +161,13 @@ int main(int argc, char** argv) ...@@ -162,14 +161,13 @@ int main(int argc, char** argv)
} }
} }
//print_node_id(); //print_node_id();
//cout << endl << endl;
std::cout << std::boolalpha; std::cout << std::boolalpha;
size_t errors = 0; size_t errors = 0;
RUN_TEST(test__uniform_type);
RUN_TEST(test__pattern); RUN_TEST(test__pattern);
RUN_TEST(test__yield_interface); RUN_TEST(test__yield_interface);
RUN_TEST(test__ripemd_160); RUN_TEST(test__ripemd_160);
RUN_TEST(test__primitive_variant); RUN_TEST(test__primitive_variant);
RUN_TEST(test__uniform_type);
RUN_TEST(test__intrusive_ptr); RUN_TEST(test__intrusive_ptr);
RUN_TEST(test__type_list); RUN_TEST(test__type_list);
RUN_TEST(test__tuple); RUN_TEST(test__tuple);
......
...@@ -13,132 +13,9 @@ ...@@ -13,132 +13,9 @@
#include "cppa/util/conjunction.hpp" #include "cppa/util/conjunction.hpp"
#include "cppa/util/is_primitive.hpp" #include "cppa/util/is_primitive.hpp"
using namespace cppa; #include "cppa/detail/types_array.hpp"
static uniform_type_info const* iinfo = uniform_typeid<int>();
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<bool IsBuiltIn, typename T>
struct uti_util_impl
{
static inline uniform_type_info const* get()
{
return uniform_typeid<T>();
}
};
template<typename T>
struct uti_util_impl<false, T>
{
static inline uniform_type_info const* get()
{
return nullptr;
}
};
template<> using namespace cppa;
struct uti_util_impl<true, anything>
{
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 types_array_impl
{
uniform_type_info const* data[sizeof...(T)];
types_array_impl() : data({get_uti_static<T>()...})
{
}
inline uniform_type_info const* operator[](size_t p) const
{
return data[p];
}
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 types_array_impl<false, T...>
{
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 uniform_type_info const* operator[](size_t p) const
{
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
{
return sizeof...(T);
}
};
template<typename... T>
struct types_array : types_array_impl<util::tl_forall<util::type_list<T...>,
is_builtin>::value,
T...>
{
};
void subtest() void subtest()
{ {
...@@ -164,15 +41,13 @@ void plot(Arr const& arr) ...@@ -164,15 +41,13 @@ void plot(Arr const& arr)
typedef std::pair<int,int> foobar; typedef std::pair<int,int> foobar;
static types_array_impl<true,int,anything,float> arr1; static detail::types_array<int,anything,float> arr1;
static types_array_impl<false,int,anything,foobar> arr2; static detail::types_array<int,anything,foobar> arr2;
size_t test__pattern() size_t test__pattern()
{ {
announce<foobar>(&foobar::first, &foobar::second); announce<foobar>(&foobar::first, &foobar::second);
cout << "iinfo->name() = " << iinfo->name() << endl;
plot(arr1); plot(arr1);
plot(arr2); plot(arr2);
......
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