Commit 6b4784ad authored by Dominik Charousset's avatar Dominik Charousset

Remove `detail::types_array`

parent 78bcec72
......@@ -30,7 +30,6 @@
#include "caf/deserializer.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/types_array.hpp"
#include "caf/detail/abstract_uniform_type_info.hpp"
......@@ -164,7 +163,7 @@ class default_serialize_policy {
template <class T>
void simpl(const T& val, serializer* s, recursive_impl) const {
static_types_array<T>::arr[0]->serialize(&val, s);
uniform_typeid<T>()->serialize(&val, s);
}
template <class T>
......@@ -217,7 +216,7 @@ class default_serialize_policy {
template <class T>
void dimpl(T& storage, deserializer* d, recursive_impl) const {
static_types_array<T>::arr[0]->deserialize(&storage, d);
uniform_typeid<T>()->deserialize(&storage, d);
}
};
......
......@@ -25,7 +25,6 @@
#include "caf/detail/type_list.hpp"
#include "caf/detail/types_array.hpp"
#include "caf/detail/message_data.hpp"
namespace caf {
......@@ -64,12 +63,12 @@ class tuple_vals : public message_data {
using data_type = std::tuple<Ts...>;
using element_types = types_array<Ts...>;
tuple_vals(const tuple_vals&) = default;
template <class... Us>
tuple_vals(Us&&... args) : m_data(std::forward<Us>(args)...) {
tuple_vals(Us&&... args)
: m_data(std::forward<Us>(args)...),
m_types{{uniform_typeid<Ts>()...}} {
// nop
}
......@@ -116,16 +115,10 @@ class tuple_vals : public message_data {
}
private:
data_type m_data;
static types_array<Ts...> m_types;
std::array<const uniform_type_info*, sizeof...(Ts)> m_types;
};
template <class... Ts>
types_array<Ts...> tuple_vals<Ts...>::m_types;
} // namespace detail
} // namespace caf
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2014 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_DETAIL_TYPES_ARRAY_HPP
#define CAF_DETAIL_TYPES_ARRAY_HPP
#include <atomic>
#include <typeinfo>
#include "caf/uniform_typeid.hpp"
#include "caf/detail/type_list.hpp"
#include "caf/detail/type_traits.hpp"
namespace caf {
namespace detail {
enum type_info_impl {
std_tinf,
caf_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 const std::type_info* get() {
return &(typeid(T));
}
};
template <>
struct ta_util<std_tinf, true, anything> {
static inline const std::type_info* get() {
return nullptr;
}
};
template <class T>
struct ta_util<caf_tinf, true, T> {
static inline const uniform_type_info* get() {
return uniform_typeid(typeid(T));
}
};
template <>
struct ta_util<caf_tinf, true, anything> {
static inline const uniform_type_info* get() {
return nullptr;
}
};
template <class T>
struct ta_util<caf_tinf, false, T> {
static inline const uniform_type_info* get() {
return nullptr;
}
};
// only built-in types are guaranteed to be available at static initialization
// time, other types are announced at runtime
// implements types_array
template <bool BuiltinOnlyTypes, class... T>
struct types_array_impl {
static constexpr bool builtin_only = true;
inline bool is_pure() const { return true; }
// all types are builtin, perform lookup on constuction
const uniform_type_info* data[sizeof...(T) == 0 ? 1 : sizeof...(T)];
types_array_impl() : data{ta_util<caf_tinf, true, T>::get()...} {}
inline const uniform_type_info* operator[](size_t p) const {
return data[p];
}
using const_iterator = const uniform_type_info* const*;
inline const_iterator begin() const { return std::begin(data); }
inline const_iterator end() const { return std::end(data); }
};
template <class... T>
struct types_array_impl<false, T...> {
static constexpr bool builtin_only = false;
inline bool is_pure() const { return false; }
// contains std::type_info for all non-builtin types
const std::type_info* tinfo_data[sizeof...(T) == 0 ? 1 : sizeof...(T)];
// contains uniform_type_infos for builtin types and lazy initializes
// non-builtin types at runtime
mutable std::atomic<const uniform_type_info*> data[sizeof...(T)];
mutable std::atomic<const uniform_type_info**> pairs;
// pairs[sizeof...(T)];
types_array_impl()
: tinfo_data{ta_util<std_tinf, is_builtin<T>::value, T>::get()...} {
bool static_init[sizeof...(T)] = {!std::is_same<T, anything>::value &&
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 const uniform_type_info* 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;
}
using const_iterator = const uniform_type_info* const*;
inline const_iterator begin() const {
auto result = pairs.load();
if (result == nullptr) {
auto parr = new const uniform_type_info* [sizeof...(T)];
for (size_t i = 0; i < sizeof...(T); ++i) {
parr[i] = (*this)[i];
}
if (!pairs.compare_exchange_weak(result, parr,
std::memory_order_relaxed)) {
delete[] parr;
} else {
result = parr;
}
}
return result;
}
inline const_iterator end() const { return begin() + sizeof...(T); }
};
// a container for uniform_type_information singletons with optimization
// for builtin types; can act as pattern
template <class... Ts>
struct types_array :
types_array_impl<tl_forall<type_list<Ts...>, is_builtin>::value, Ts...> {
static constexpr size_t size = sizeof...(Ts);
using types = type_list<Ts...>;
using filtered_types = typename tl_filter_not<types, is_anything>::type;
static constexpr size_t filtered_size = tl_size<filtered_types>::value;
inline bool has_values() const { return false; }
};
// utility for singleton-like access to a types_array
template <class... T>
struct static_types_array {
static types_array<T...> arr;
};
template <class... T>
types_array<T...> static_types_array<T...>::arr;
template <class TypeList>
struct static_types_array_from_type_list;
template <class... T>
struct static_types_array_from_type_list<type_list<T...>> {
using type = static_types_array<T...>;
};
template <class... T>
struct static_type_list;
template <class T>
struct static_type_list<T> {
static const std::type_info* list;
static inline const std::type_info* by_offset(size_t offset) {
return offset == 0 ? list : &typeid(type_list<>);
}
};
template <class T>
const std::type_info* static_type_list<T>::list = &typeid(type_list<T>);
// utility for singleton-like access to a type_info instance of a type_list
template <class T0, typename T1, class... Ts>
struct static_type_list<T0, T1, Ts...> {
static const std::type_info* list;
static inline const std::type_info* by_offset(size_t offset) {
return offset == 0 ? list : static_type_list<T1, Ts...>::list;
}
};
template <class T0, typename T1, class... Ts>
const std::type_info* static_type_list<T0, T1, Ts...>::list =
&typeid(type_list<T0, T1, Ts...>);
} // namespace detail
} // namespace caf
#endif // CAF_DETAIL_TYPES_ARRAY_HPP
......@@ -132,23 +132,6 @@ class message {
*/
const uniform_type_info* type_at(size_t p) const;
/**
* Returns true if this message has the types @p Ts.
*/
template <class... Ts>
bool has_types() const {
if (size() != sizeof...(Ts)) {
return false;
}
const std::type_info* ts[] = {&typeid(Ts)...};
for (size_t i = 0; i < sizeof...(Ts); ++i) {
if (!type_at(i)->equal_to(*ts[i])) {
return false;
}
}
return true;
}
/**
* Returns @c true if `*this == other, otherwise false.
*/
......
......@@ -147,7 +147,9 @@ class invoke_policy {
}
} else {
CAF_LOGF_DEBUG("res = " << to_string(*res));
if (res->template has_types<atom_value, uint64_t>()
if (res->size() == 2
&& res->type_at(0) == uniform_typeid<atom_value>()
&& res->type_at(1) == uniform_typeid<uint64_t>()
&& res->template get_as<atom_value>(0) == atom("MESSAGE_ID")) {
CAF_LOG_DEBUG("message handler returned a message id wrapper");
auto id = res->template get_as<uint64_t>(1);
......
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