Commit 488ca971 authored by Dominik Charousset's avatar Dominik Charousset

refactored type name mapping

type names are now mapped using a static lookup table; all built-in types
information instances are now members of uniform_type_info_map to get rid
of as much heap allocations as possible
parent 31699f7f
...@@ -102,7 +102,6 @@ set(LIBCPPA_SRC ...@@ -102,7 +102,6 @@ set(LIBCPPA_SRC
src/context_switching_actor.cpp src/context_switching_actor.cpp
src/continuable_reader.cpp src/continuable_reader.cpp
src/continuable_writer.cpp src/continuable_writer.cpp
src/decorated_names_map.cpp
src/default_actor_addressing.cpp src/default_actor_addressing.cpp
src/default_actor_proxy.cpp src/default_actor_proxy.cpp
src/default_peer.cpp src/default_peer.cpp
...@@ -154,6 +153,7 @@ set(LIBCPPA_SRC ...@@ -154,6 +153,7 @@ set(LIBCPPA_SRC
src/to_uniform_name.cpp src/to_uniform_name.cpp
src/unicast_network.cpp src/unicast_network.cpp
src/uniform_type_info.cpp src/uniform_type_info.cpp
src/uniform_type_info_map.cpp
src/weak_ptr_anchor.cpp src/weak_ptr_anchor.cpp
src/yield_interface.cpp) src/yield_interface.cpp)
......
...@@ -25,7 +25,6 @@ cppa/detail/behavior_impl.hpp ...@@ -25,7 +25,6 @@ cppa/detail/behavior_impl.hpp
cppa/detail/behavior_stack.hpp cppa/detail/behavior_stack.hpp
cppa/detail/boxed.hpp cppa/detail/boxed.hpp
cppa/detail/container_tuple_view.hpp cppa/detail/container_tuple_view.hpp
cppa/detail/decorated_names_map.hpp
cppa/detail/decorated_tuple.hpp cppa/detail/decorated_tuple.hpp
cppa/detail/default_uniform_type_info_impl.hpp cppa/detail/default_uniform_type_info_impl.hpp
cppa/detail/demangle.hpp cppa/detail/demangle.hpp
...@@ -122,6 +121,7 @@ cppa/option.hpp ...@@ -122,6 +121,7 @@ cppa/option.hpp
cppa/partial_function.hpp cppa/partial_function.hpp
cppa/primitive_type.hpp cppa/primitive_type.hpp
cppa/primitive_variant.hpp cppa/primitive_variant.hpp
cppa/prioritizing.hpp
cppa/process_information.hpp cppa/process_information.hpp
cppa/qtsupport/actor_widget_mixin.hpp cppa/qtsupport/actor_widget_mixin.hpp
cppa/receive.hpp cppa/receive.hpp
...@@ -131,6 +131,7 @@ cppa/sb_actor.hpp ...@@ -131,6 +131,7 @@ cppa/sb_actor.hpp
cppa/scheduled_actor.hpp cppa/scheduled_actor.hpp
cppa/scheduler.hpp cppa/scheduler.hpp
cppa/self.hpp cppa/self.hpp
cppa/send.hpp
cppa/serializer.hpp cppa/serializer.hpp
cppa/singletons.hpp cppa/singletons.hpp
cppa/spawn_options.hpp cppa/spawn_options.hpp
...@@ -227,7 +228,6 @@ src/channel.cpp ...@@ -227,7 +228,6 @@ src/channel.cpp
src/context_switching_actor.cpp src/context_switching_actor.cpp
src/continuable_reader.cpp src/continuable_reader.cpp
src/continuable_writer.cpp src/continuable_writer.cpp
src/decorated_names_map.cpp
src/default_actor_addressing.cpp src/default_actor_addressing.cpp
src/default_actor_proxy.cpp src/default_actor_proxy.cpp
src/default_peer.cpp src/default_peer.cpp
...@@ -283,6 +283,7 @@ src/thread_pool_scheduler.cpp ...@@ -283,6 +283,7 @@ src/thread_pool_scheduler.cpp
src/to_uniform_name.cpp src/to_uniform_name.cpp
src/unicast_network.cpp src/unicast_network.cpp
src/uniform_type_info.cpp src/uniform_type_info.cpp
src/uniform_type_info_map.cpp
src/weak_ptr_anchor.cpp src/weak_ptr_anchor.cpp
src/yield_interface.cpp src/yield_interface.cpp
unit_testing/ping_pong.cpp unit_testing/ping_pong.cpp
...@@ -306,5 +307,3 @@ unit_testing/test_sync_send.cpp ...@@ -306,5 +307,3 @@ unit_testing/test_sync_send.cpp
unit_testing/test_tuple.cpp unit_testing/test_tuple.cpp
unit_testing/test_uniform_type.cpp unit_testing/test_uniform_type.cpp
unit_testing/test_yield_interface.cpp unit_testing/test_yield_interface.cpp
cppa/prioritizing.hpp
cppa/send.hpp
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_DECORATED_NAMES_MAP_HPP
#define CPPA_DECORATED_NAMES_MAP_HPP
#include <map>
#include <string>
#include "cppa/detail/singleton_mixin.hpp"
namespace cppa { namespace detail {
class decorated_names_map : public singleton_mixin<decorated_names_map> {
friend class singleton_mixin<decorated_names_map>;
public:
// returns either a decorated version of @p demangled_name or
// @p demangled_name itself
const std::string& decorate(const std::string& demangled_name) const;
private:
decorated_names_map();
std::map<std::string, std::string> m_map;
};
} } // namespace cppa::detail
#endif // DECORATED_NAMES_MAP_HPP
...@@ -50,7 +50,6 @@ class empty_tuple; ...@@ -50,7 +50,6 @@ class empty_tuple;
class group_manager; class group_manager;
class abstract_tuple; class abstract_tuple;
class actor_registry; class actor_registry;
class decorated_names_map;
class uniform_type_info_map; class uniform_type_info_map;
class singleton_manager { class singleton_manager {
...@@ -79,8 +78,6 @@ class singleton_manager { ...@@ -79,8 +78,6 @@ class singleton_manager {
static empty_tuple* get_empty_tuple(); static empty_tuple* get_empty_tuple();
static decorated_names_map* get_decorated_names_map();
static opencl::command_dispatcher* get_command_dispatcher(); static opencl::command_dispatcher* get_command_dispatcher();
private: private:
......
...@@ -32,57 +32,93 @@ ...@@ -32,57 +32,93 @@
#define CPPA_UNIFORM_TYPE_INFO_MAP_HPP #define CPPA_UNIFORM_TYPE_INFO_MAP_HPP
#include <set> #include <set>
#include <map>
#include <string> #include <string>
#include <utility> // std::pair #include <utility>
#include <type_traits>
#include "cppa/cppa_fwd.hpp"
#include "cppa/util/duration.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/detail/singleton_mixin.hpp" #include "cppa/detail/singleton_mixin.hpp"
#include "cppa/detail/default_uniform_type_info_impl.hpp"
namespace cppa { class uniform_type_info; } namespace cppa { class uniform_type_info; }
namespace cppa { namespace detail { namespace cppa { namespace detail {
using mapped_type_list = util::type_list<
bool,
any_tuple,
atom_value,
actor_ptr,
channel_ptr,
group_ptr,
process_information_ptr,
message_header,
std::nullptr_t,
util::duration,
util::void_type,
double,
float,
long double,
std::string,
std::u16string,
std::u32string,
std::map<std::string,std::string>
>;
using zipped_type_list = util::tl_zip_with_index<mapped_type_list>::type;
// lookup table for built-in types
extern const char* mapped_type_names[][2];
template<typename T>
constexpr const char* mapped_name() {
return mapped_type_names[util::tl_index_of<zipped_type_list,T>::value][1];
}
const char* mapped_name_by_decorated_name(const char* decorated_type_name);
// lookup table for integer types
extern const char* mapped_int_names[][2];
template<typename T>
constexpr const char* mapped_int_name() {
return mapped_int_names[sizeof(T)][std::is_signed<T>::value ? 1 : 0];
}
class uniform_type_info_map_helper; class uniform_type_info_map_helper;
// note: this class is implemented in uniform_type_info.cpp // note: this class is implemented in uniform_type_info.cpp
class uniform_type_info_map : public singleton_mixin<uniform_type_info_map> { class uniform_type_info_map {
friend class uniform_type_info_map_helper; friend class uniform_type_info_map_helper;
friend class singleton_mixin<uniform_type_info_map>; friend class singleton_mixin<uniform_type_info_map>;
public: public:
typedef std::set<std::string> set_type; typedef const uniform_type_info* pointer;
typedef std::map<std::string, uniform_type_info*> uti_map_type;
typedef std::map<int, std::pair<set_type, set_type> > int_map_type;
inline const int_map_type& int_names() const { virtual ~uniform_type_info_map();
return m_ints;
}
const uniform_type_info* by_raw_name(const std::string& name) const; virtual pointer by_uniform_name(const std::string& name) const = 0;
const uniform_type_info* by_uniform_name(const std::string& name) const; virtual pointer by_rtti(const std::type_info& ti) const = 0;
std::vector<const uniform_type_info*> get_all() const; virtual std::vector<pointer> get_all() const = 0;
// NOT thread safe! // NOT thread safe!
bool insert(const std::set<std::string>& raw_names, uniform_type_info* uti); virtual bool insert(uniform_type_info* uti) = 0;
private:
// maps raw typeid names to uniform type informations
uti_map_type m_by_rname;
// maps uniform names to uniform type informations static uniform_type_info_map* create_singleton();
uti_map_type m_by_uname;
// maps sizeof(-integer_type-) to { signed-names-set, unsigned-names-set } inline void dispose() { delete this; }
int_map_type m_ints;
uniform_type_info_map(); inline void destroy() { delete this; }
~uniform_type_info_map(); virtual void initialize() = 0;
}; };
......
...@@ -67,10 +67,6 @@ inline detail::empty_tuple* get_empty_tuple() { ...@@ -67,10 +67,6 @@ inline detail::empty_tuple* get_empty_tuple() {
return detail::singleton_manager::get_empty_tuple(); return detail::singleton_manager::get_empty_tuple();
} }
inline detail::decorated_names_map* get_decorated_names_map() {
return detail::singleton_manager::get_decorated_names_map();
}
} // namespace cppa } // namespace cppa
#endif // CPPA_SINGLETONS_HPP #endif // CPPA_SINGLETONS_HPP
...@@ -186,12 +186,6 @@ class uniform_type_info { ...@@ -186,12 +186,6 @@ class uniform_type_info {
*/ */
static std::vector<const uniform_type_info*> instances(); static std::vector<const uniform_type_info*> instances();
/**
* @brief Get the internal @p libcppa name for this type.
* @returns A string describing the @p libcppa internal type name.
*/
inline const std::string& name() const { return m_name; }
/** /**
* @brief Creates an object of this type. * @brief Creates an object of this type.
*/ */
...@@ -202,6 +196,12 @@ class uniform_type_info { ...@@ -202,6 +196,12 @@ class uniform_type_info {
*/ */
object deserialize(deserializer* source) const; object deserialize(deserializer* source) const;
/**
* @brief Get the internal @p libcppa name for this type.
* @returns A string describing the @p libcppa internal type name.
*/
virtual const char* name() const = 0;
/** /**
* @brief Determines if this uniform_type_info describes the same * @brief Determines if this uniform_type_info describes the same
* type than @p tinfo. * type than @p tinfo.
...@@ -234,23 +234,9 @@ class uniform_type_info { ...@@ -234,23 +234,9 @@ class uniform_type_info {
*/ */
virtual void deserialize(void* instance, deserializer* source) const = 0; virtual void deserialize(void* instance, deserializer* source) const = 0;
/**
* @brief Checks wheter <tt>src->seek_object()</tt>
* returns @p tname and throws an exception if not.
* @throws std::logic_error
*/
static void assert_type_name(deserializer* src, const std::string& tname);
protected: protected:
/** uniform_type_info() = default;
* @brief Checks wheter <tt>src->seek_object()</tt>
* returns {@link name()} and throws an exception if not.
* @throws std::logic_error
*/
void assert_type_name(deserializer* src) const;
uniform_type_info(const std::string& uniform_name);
/** /**
* @brief Casts @p instance to the native type and deletes it. * @brief Casts @p instance to the native type and deletes it.
...@@ -270,10 +256,6 @@ class uniform_type_info { ...@@ -270,10 +256,6 @@ class uniform_type_info {
*/ */
virtual void* new_instance(const void* instance = nullptr) const = 0; virtual void* new_instance(const void* instance = nullptr) const = 0;
private:
std::string m_name;
}; };
/** /**
......
...@@ -31,8 +31,11 @@ ...@@ -31,8 +31,11 @@
#ifndef CPPA_ABSTRACT_UNIFORM_TYPE_INFO_HPP #ifndef CPPA_ABSTRACT_UNIFORM_TYPE_INFO_HPP
#define CPPA_ABSTRACT_UNIFORM_TYPE_INFO_HPP #define CPPA_ABSTRACT_UNIFORM_TYPE_INFO_HPP
#include "cppa/deserializer.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/detail/to_uniform_name.hpp" #include "cppa/detail/to_uniform_name.hpp"
#include "cppa/detail/uniform_type_info_map.hpp"
namespace cppa { namespace util { namespace cppa { namespace util {
...@@ -43,19 +46,23 @@ namespace cppa { namespace util { ...@@ -43,19 +46,23 @@ namespace cppa { namespace util {
template<typename T> template<typename T>
class abstract_uniform_type_info : public uniform_type_info { class abstract_uniform_type_info : public uniform_type_info {
inline static const T& deref(const void* ptr) { public:
return *reinterpret_cast<const T*>(ptr);
bool equals(const std::type_info& tinfo) const {
return typeid(T) == tinfo;
} }
inline static T& deref(void* ptr) { const char* name() const {
return *reinterpret_cast<T*>(ptr); return m_name.c_str();
} }
protected: protected:
abstract_uniform_type_info(const std::string& uname abstract_uniform_type_info() {
= detail::to_uniform_name(typeid(T))) auto uname = detail::to_uniform_name<T>();
: uniform_type_info(uname) { auto cname = detail::mapped_name_by_decorated_name(uname.c_str());
if (cname == uname.c_str()) m_name = std::move(uname);
else m_name = cname;
} }
bool equals(const void* lhs, const void* rhs) const { bool equals(const void* lhs, const void* rhs) const {
...@@ -70,14 +77,32 @@ class abstract_uniform_type_info : public uniform_type_info { ...@@ -70,14 +77,32 @@ class abstract_uniform_type_info : public uniform_type_info {
delete reinterpret_cast<T*>(instance); delete reinterpret_cast<T*>(instance);
} }
public: void assert_type_name(deserializer* source) const {
auto tname = source->seek_object();
if (tname != name()) {
std::string error_msg = "wrong type name found; expected \"";
error_msg += name();
error_msg += "\", found \"";
error_msg += tname;
error_msg += "\"";
throw std::logic_error(std::move(error_msg));
}
}
bool equals(const std::type_info& tinfo) const { private:
return typeid(T) == tinfo;
static inline const T& deref(const void* ptr) {
return *reinterpret_cast<const T*>(ptr);
} }
static inline T& deref(void* ptr) {
return *reinterpret_cast<T*>(ptr);
}
std::string m_name;
}; };
} } } } // namespace cppa::util
#endif // CPPA_ABSTRACT_UNIFORM_TYPE_INFO_HPP #endif // CPPA_ABSTRACT_UNIFORM_TYPE_INFO_HPP
...@@ -340,6 +340,18 @@ struct tl_zip_with_index<empty_type_list> { ...@@ -340,6 +340,18 @@ struct tl_zip_with_index<empty_type_list> {
typedef empty_type_list type; typedef empty_type_list type;
}; };
// int index_of(list, type)
template<class List, typename T>
struct tl_index_of {
static constexpr size_t value = tl_index_of<typename tl_tail<List>::type,T>::value;
};
template<size_t N, typename T, typename... Ts>
struct tl_index_of<type_list<type_pair<std::integral_constant<size_t,N>,T>,Ts...>,T> {
static constexpr size_t value = N;
};
// list reverse() // list reverse()
template<class From, typename... Elements> template<class From, typename... Elements>
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#include <limits>
#include "cppa/detail/demangle.hpp"
#include "cppa/detail/decorated_names_map.hpp"
using namespace std;
namespace {
using namespace cppa;
using namespace cppa::detail;
constexpr const char* mapped_int_names[][2] = {
{ nullptr, nullptr }, // sizeof 0-> invalid
{ "@i8", "@u8" }, // sizeof 1 -> signed / unsigned int8
{ "@i16", "@u16" }, // sizeof 2 -> signed / unsigned int16
{ nullptr, nullptr }, // sizeof 3-> invalid
{ "@i32", "@u32" }, // sizeof 4 -> signed / unsigned int32
{ nullptr, nullptr }, // sizeof 5-> invalid
{ nullptr, nullptr }, // sizeof 6-> invalid
{ nullptr, nullptr }, // sizeof 7-> invalid
{ "@i64", "@u64" } // sizeof 8 -> signed / unsigned int64
};
template<typename T>
constexpr size_t sign_index() {
static_assert(numeric_limits<T>::is_integer, "T is not an integer");
return numeric_limits<T>::is_signed ? 0 : 1;
}
template<typename T>
inline string demangled() {
return demangle(typeid(T));
}
template<typename T>
constexpr const char* mapped_int_name() {
return mapped_int_names[sizeof(T)][sign_index<T>()];
}
template<typename T>
struct is_signed : integral_constant<bool, numeric_limits<T>::is_signed> { };
} // namespace <anonymous>
namespace cppa { namespace detail {
decorated_names_map::decorated_names_map() {
map<string, string> tmp = {
// integer types
{ demangled<char>(), mapped_int_name<char>() },
{ demangled<signed char>(), mapped_int_name<signed char>() },
{ demangled<unsigned char>(), mapped_int_name<unsigned char>() },
{ demangled<short>(), mapped_int_name<short>() },
{ demangled<signed short>(), mapped_int_name<signed short>() },
{ demangled<unsigned short>(), mapped_int_name<unsigned short>() },
{ demangled<short int>(), mapped_int_name<short int>() },
{ demangled<signed short int>(), mapped_int_name<signed short int>() },
{ demangled<unsigned short int>(), mapped_int_name<unsigned short int>()},
{ demangled<int>(), mapped_int_name<int>() },
{ demangled<signed int>(), mapped_int_name<signed int>() },
{ demangled<unsigned int>(), mapped_int_name<unsigned int>() },
{ demangled<long int>(), mapped_int_name<long int>() },
{ demangled<signed long int>(), mapped_int_name<signed long int>() },
{ demangled<unsigned long int>(), mapped_int_name<unsigned long int>() },
{ demangled<long>(), mapped_int_name<long>() },
{ demangled<signed long>(), mapped_int_name<signed long>() },
{ demangled<unsigned long>(), mapped_int_name<unsigned long>() },
{ demangled<long long>(), mapped_int_name<long long>() },
{ demangled<signed long long>(), mapped_int_name<signed long long>() },
{ demangled<unsigned long long>(), mapped_int_name<unsigned long long>()},
{ demangled<char16_t>(), mapped_int_name<char16_t>() },
{ demangled<char32_t>(), mapped_int_name<char32_t>() },
{ "cppa::atom_value", "@atom" },
{ "cppa::any_tuple", "@<>" },
{ "cppa::message_header", "@hdr" },
{ "cppa::intrusive_ptr<cppa::actor>", "@actor" },
{ "cppa::intrusive_ptr<cppa::group>" ,"@group" },
{ "cppa::intrusive_ptr<cppa::channel>", "@channel" },
{ "cppa::intrusive_ptr<cppa::process_information>", "@process_info" },
{ "std::basic_string<@i8,std::char_traits<@i8>,std::allocator<@i8>>", "@str" },
{ "std::basic_string<@u16,std::char_traits<@u16>,std::allocator<@u16>>", "@u16str" },
{ "std::basic_string<@u32,std::char_traits<@u32>,std::allocator<@u32>>", "@u32str"},
{ "std::map<@str,@str,std::less<@str>,std::allocator<std::pair<const @str,@str>>>", "@strmap" },
{ "std::string", "@str" }, // GCC
{ "cppa::util::void_type", "@0" }
};
m_map = move(tmp);
}
const string& decorated_names_map::decorate(const string& what) const {
auto i = m_map.find(what);
return (i != m_map.end()) ? i->second : what;
}
} } // namespace cppa::detail
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
#include "cppa/detail/group_manager.hpp" #include "cppa/detail/group_manager.hpp"
#include "cppa/detail/actor_registry.hpp" #include "cppa/detail/actor_registry.hpp"
#include "cppa/detail/singleton_manager.hpp" #include "cppa/detail/singleton_manager.hpp"
#include "cppa/detail/decorated_names_map.hpp"
#include "cppa/detail/thread_pool_scheduler.hpp" #include "cppa/detail/thread_pool_scheduler.hpp"
#include "cppa/detail/uniform_type_info_map.hpp" #include "cppa/detail/uniform_type_info_map.hpp"
...@@ -66,7 +65,6 @@ namespace { ...@@ -66,7 +65,6 @@ namespace {
std::atomic<opencl::command_dispatcher*> s_command_dispatcher; std::atomic<opencl::command_dispatcher*> s_command_dispatcher;
std::atomic<uniform_type_info_map*> s_uniform_type_info_map; std::atomic<uniform_type_info_map*> s_uniform_type_info_map;
std::atomic<decorated_names_map*> s_decorated_names_map;
std::atomic<network::middleman*> s_middleman; std::atomic<network::middleman*> s_middleman;
std::atomic<actor_registry*> s_actor_registry; std::atomic<actor_registry*> s_actor_registry;
std::atomic<group_manager*> s_group_manager; std::atomic<group_manager*> s_group_manager;
...@@ -100,8 +98,6 @@ void singleton_manager::shutdown() { ...@@ -100,8 +98,6 @@ void singleton_manager::shutdown() {
destroy(s_empty_tuple); destroy(s_empty_tuple);
CPPA_LOGF(CPPA_DEBUG, nullptr, "clear type info map"); CPPA_LOGF(CPPA_DEBUG, nullptr, "clear type info map");
destroy(s_uniform_type_info_map); destroy(s_uniform_type_info_map);
CPPA_LOGF(CPPA_DEBUG, nullptr, "clear decorated names log");
destroy(s_decorated_names_map);
destroy(s_logger); destroy(s_logger);
} }
...@@ -130,10 +126,6 @@ scheduler* singleton_manager::get_scheduler() { ...@@ -130,10 +126,6 @@ scheduler* singleton_manager::get_scheduler() {
return lazy_get(s_scheduler); return lazy_get(s_scheduler);
} }
decorated_names_map* singleton_manager::get_decorated_names_map() {
return lazy_get(s_decorated_names_map);
}
logging* singleton_manager::get_logger() { logging* singleton_manager::get_logger() {
return lazy_get(s_logger); return lazy_get(s_logger);
} }
......
...@@ -53,7 +53,7 @@ namespace cppa { ...@@ -53,7 +53,7 @@ namespace cppa {
namespace { namespace {
bool isbuiltin(const string& type_name) { bool isbuiltin(const string& type_name) {
return type_name == "@str" || type_name == "@atom" || type_name == "@<>"; return type_name == "@str" || type_name == "@atom" || type_name == "@tuple";
} }
// serializes types as type_name(...) except: // serializes types as type_name(...) except:
...@@ -284,7 +284,7 @@ class string_deserializer : public deserializer { ...@@ -284,7 +284,7 @@ class string_deserializer : public deserializer {
return "@atom"; return "@atom";
} }
else if (*m_pos == '{') { else if (*m_pos == '{') {
return "@<>"; return "@tuple";
} }
// default case // default case
auto substr_end = next_delimiter(); auto substr_end = next_delimiter();
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <cwchar> #include <cwchar>
#include <limits> #include <limits>
#include <vector> #include <vector>
#include <cstring>
#include <typeinfo> #include <typeinfo>
#include <stdexcept> #include <stdexcept>
#include <algorithm> #include <algorithm>
...@@ -42,14 +43,14 @@ ...@@ -42,14 +43,14 @@
#include "cppa/channel.hpp" #include "cppa/channel.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/message_header.hpp"
#include "cppa/util/void_type.hpp" #include "cppa/util/void_type.hpp"
#include "cppa/detail/demangle.hpp" #include "cppa/detail/demangle.hpp"
#include "cppa/detail/to_uniform_name.hpp" #include "cppa/detail/to_uniform_name.hpp"
#include "cppa/message_header.hpp"
#include "cppa/detail/singleton_manager.hpp" #include "cppa/detail/singleton_manager.hpp"
#include "cppa/detail/decorated_names_map.hpp" #include "cppa/detail/uniform_type_info_map.hpp"
namespace { namespace {
...@@ -57,6 +58,47 @@ using namespace std; ...@@ -57,6 +58,47 @@ using namespace std;
using namespace cppa; using namespace cppa;
using namespace detail; using namespace detail;
struct platform_int_mapping { const char* name; size_t size; bool is_signed; };
// WARNING: this list is sorted and searched with std::lower_bound;
// keep ordered when adding elements!
platform_int_mapping platform_dependent_sizes[] = {
{"char", sizeof(char), true},
{"char16_t", sizeof(char16_t), true},
{"char32_t", sizeof(char32_t), true},
{"int", sizeof(int), true},
{"long", sizeof(long), true},
{"long int", sizeof(long int), true},
{"long long", sizeof(long long), true},
{"short", sizeof(short), true},
{"short int", sizeof(short int), true},
{"signed char", sizeof(signed char), true},
{"signed int", sizeof(signed int), true},
{"signed long", sizeof(signed long), true},
{"signed long int", sizeof(signed long int), true},
{"signed long long", sizeof(signed long long), true},
{"signed short", sizeof(signed short), true},
{"signed short int", sizeof(signed short int), true},
{"unsigned char", sizeof(unsigned char), false},
{"unsigned int", sizeof(unsigned int), false},
{"unsigned long", sizeof(unsigned long), false},
{"unsigned long int", sizeof(unsigned long int), false},
{"unsigned long long", sizeof(unsigned long long), false},
{"unsigned short", sizeof(unsigned short), false},
{"unsigned short int", sizeof(unsigned short int), false}
};
string map2decorated(const char* name) {
auto cmp = [](const platform_int_mapping& pim, const char* name) {
return strcmp(pim.name, name) < 0;
};
auto e = end(platform_dependent_sizes);
auto i = lower_bound(begin(platform_dependent_sizes), e, name, cmp);
if (i != e && strcmp(i->name, name) == 0) {
return mapped_int_names[i->size][i->is_signed ? 1 : 0];
}
return mapped_name_by_decorated_name(name);
}
class parse_tree { class parse_tree {
...@@ -67,7 +109,7 @@ class parse_tree { ...@@ -67,7 +109,7 @@ class parse_tree {
if (m_volatile) result += "volatile "; if (m_volatile) result += "volatile ";
if (m_const) result += "const "; if (m_const) result += "const ";
if (!m_template) { if (!m_template) {
result += dmm->decorate(m_name); result += map2decorated(m_name.c_str());
} }
else { else {
string full_name = m_name; string full_name = m_name;
...@@ -79,7 +121,7 @@ class parse_tree { ...@@ -79,7 +121,7 @@ class parse_tree {
} }
full_name += ">"; full_name += ">";
// decorate full name // decorate full name
result += dmm->decorate(full_name); result += map2decorated(full_name.c_str());
} }
if (m_pointer) result += "*"; if (m_pointer) result += "*";
if (m_lvalue_ref) result += "&"; if (m_lvalue_ref) result += "&";
...@@ -167,9 +209,7 @@ class parse_tree { ...@@ -167,9 +209,7 @@ class parse_tree {
parse_tree() parse_tree()
: m_const(false), m_pointer(false), m_volatile(false), m_template(false) : m_const(false), m_pointer(false), m_volatile(false), m_template(false)
, m_lvalue_ref(false), m_rvalue_ref(false) { , m_lvalue_ref(false), m_rvalue_ref(false) { }
dmm = singleton_manager::get_decorated_names_map();
}
bool m_const; bool m_const;
bool m_pointer; bool m_pointer;
...@@ -177,7 +217,6 @@ class parse_tree { ...@@ -177,7 +217,6 @@ class parse_tree {
bool m_template; bool m_template;
bool m_lvalue_ref; bool m_lvalue_ref;
bool m_rvalue_ref; bool m_rvalue_ref;
const decorated_names_map* dmm;
string m_name; string m_name;
vector<parse_tree> m_template_parameters; vector<parse_tree> m_template_parameters;
...@@ -221,7 +260,7 @@ void replace_all(string& str, const char (&before)[RawSize], const char* after) ...@@ -221,7 +260,7 @@ void replace_all(string& str, const char (&before)[RawSize], const char* after)
} }
const char s_rawan[] = "anonymous namespace"; const char s_rawan[] = "anonymous namespace";
const char s_an[] = "@_"; const char s_an[] = "$";
} // namespace <anonymous> } // namespace <anonymous>
......
This diff is collapsed.
This diff is collapsed.
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <cstring>
#include <cstddef> #include <cstddef>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
...@@ -43,7 +44,9 @@ struct both_integral { ...@@ -43,7 +44,9 @@ struct both_integral {
}; };
template<bool V, typename T1, typename T2> template<bool V, typename T1, typename T2>
struct enable_integral : std::enable_if<both_integral<T1,T2>::value == V> { }; struct enable_integral : std::enable_if< both_integral<T1,T2>::value == V
&& not std::is_pointer<T1>::value
&& not std::is_pointer<T2>::value> { };
template<typename T> template<typename T>
const T& cppa_stream_arg(const T& value) { const T& cppa_stream_arg(const T& value) {
...@@ -73,6 +76,15 @@ inline void cppa_failed(const V1& v1, ...@@ -73,6 +76,15 @@ inline void cppa_failed(const V1& v1,
cppa_inc_error_count(); cppa_inc_error_count();
} }
inline void cppa_check_value(const std::string& v1,
const std::string& v2,
const char* fname,
int line,
bool expected = true) {
if ((v1 == v2) == expected) cppa_passed(fname, line);
else cppa_failed(v1, v2, fname, line);
}
template<typename V1, typename V2> template<typename V1, typename V2>
inline void cppa_check_value(const V1& v1, inline void cppa_check_value(const V1& v1,
const V2& v2, const V2& v2,
......
...@@ -229,6 +229,7 @@ int main() { ...@@ -229,6 +229,7 @@ int main() {
if (msg1str != msg1_tostring) { if (msg1str != msg1_tostring) {
CPPA_FAILURE("msg1str != to_string(msg1)"); CPPA_FAILURE("msg1str != to_string(msg1)");
cerr << "to_string(msg1) = " << msg1_tostring << endl; cerr << "to_string(msg1) = " << msg1_tostring << endl;
cerr << "to_string(msg1str) = " << msg1str << endl;
} }
util::buffer wr_buf; util::buffer wr_buf;
binary_serializer bs(&wr_buf, &addressing); binary_serializer bs(&wr_buf, &addressing);
......
...@@ -222,13 +222,13 @@ void check_guards() { ...@@ -222,13 +222,13 @@ void check_guards() {
CPPA_CHECK_EQUAL(f09_any_val.get_as<int>(1), 9); CPPA_CHECK_EQUAL(f09_any_val.get_as<int>(1), 9);
f09_any_val.get_as_mutable<int>(1) = 666; f09_any_val.get_as_mutable<int>(1) = 666;
any_tuple f09_any_val_copy{f09_any_val}; any_tuple f09_any_val_copy{f09_any_val};
CPPA_CHECK_EQUAL(f09_any_val.at(0), f09_any_val_copy.at(0)); CPPA_CHECK(f09_any_val.at(0) == f09_any_val_copy.at(0));
// detaches f09_any_val from f09_any_val_copy // detaches f09_any_val from f09_any_val_copy
CPPA_CHECK(f09.invoke(f09_any_val)); CPPA_CHECK(f09.invoke(f09_any_val));
CPPA_CHECK_EQUAL(f09_any_val.get_as<int>(1), 9); CPPA_CHECK_EQUAL(f09_any_val.get_as<int>(1), 9);
CPPA_CHECK_EQUAL(f09_any_val_copy.get_as<int>(1), 666); CPPA_CHECK_EQUAL(f09_any_val_copy.get_as<int>(1), 666);
// no longer the same data // no longer the same data
CPPA_CHECK_NOT_EQUAL(f09_any_val.at(0), f09_any_val_copy.at(0)); CPPA_CHECK(f09_any_val.at(0) != f09_any_val_copy.at(0));
auto f10 = ( auto f10 = (
on<int>().when(_x1 < 10) >> [&]() { invoked = "f10.0"; }, on<int>().when(_x1 < 10) >> [&]() { invoked = "f10.0"; },
...@@ -351,11 +351,11 @@ void check_wildcards() { ...@@ -351,11 +351,11 @@ void check_wildcards() {
CPPA_CHECK_EQUAL(get<0>(v0), "1"); CPPA_CHECK_EQUAL(get<0>(v0), "1");
CPPA_CHECK_EQUAL(get<0>(t0), get<0>(v0)); CPPA_CHECK_EQUAL(get<0>(t0), get<0>(v0));
// check cow semantics // check cow semantics
CPPA_CHECK_EQUAL(&get<0>(t0), &get<0>(v0)); // point to the same CPPA_CHECK(&get<0>(t0) == &get<0>(v0)); // point to the same
get_ref<0>(t0) = "hello world"; // detaches t0 from v0 get_ref<0>(t0) = "hello world"; // detaches t0 from v0
CPPA_CHECK_EQUAL(get<0>(t0), "hello world"); // t0 contains new value CPPA_CHECK_EQUAL(get<0>(t0), "hello world"); // t0 contains new value
CPPA_CHECK_EQUAL(get<0>(v0), "1"); // v0 contains old value CPPA_CHECK_EQUAL(get<0>(v0), "1"); // v0 contains old value
CPPA_CHECK_NOT_EQUAL(&get<0>(t0), &get<0>(v0)); // no longer the same CPPA_CHECK(&get<0>(t0) != &get<0>(v0)); // no longer the same
// check operator== // check operator==
auto lhs = make_cow_tuple(1,2,3,4); auto lhs = make_cow_tuple(1,2,3,4);
auto rhs = make_cow_tuple(static_cast<std::uint8_t>(1), 2.0, 3, 4); auto rhs = make_cow_tuple(static_cast<std::uint8_t>(1), 2.0, 3, 4);
...@@ -368,24 +368,24 @@ void check_wildcards() { ...@@ -368,24 +368,24 @@ void check_wildcards() {
CPPA_CHECK(opt0); CPPA_CHECK(opt0);
if (opt0) { if (opt0) {
CPPA_CHECK((*opt0 == make_cow_tuple("one", 2, 3.f, 4.0))); CPPA_CHECK((*opt0 == make_cow_tuple("one", 2, 3.f, 4.0)));
CPPA_CHECK_EQUAL(&get<0>(*opt0), at1.at(0)); CPPA_CHECK(&get<0>(*opt0) == at1.at(0));
CPPA_CHECK_EQUAL(&get<1>(*opt0), at1.at(1)); CPPA_CHECK(&get<1>(*opt0) == at1.at(1));
CPPA_CHECK_EQUAL(&get<2>(*opt0), at1.at(2)); CPPA_CHECK(&get<2>(*opt0) == at1.at(2));
CPPA_CHECK_EQUAL(&get<3>(*opt0), at1.at(3)); CPPA_CHECK(&get<3>(*opt0) == at1.at(3));
} }
// leading wildcard // leading wildcard
auto opt1 = tuple_cast<anything, double>(at1); auto opt1 = tuple_cast<anything, double>(at1);
CPPA_CHECK(opt1); CPPA_CHECK(opt1);
if (opt1) { if (opt1) {
CPPA_CHECK_EQUAL(get<0>(*opt1), 4.0); CPPA_CHECK_EQUAL(get<0>(*opt1), 4.0);
CPPA_CHECK_EQUAL(&get<0>(*opt1), at1.at(3)); CPPA_CHECK(&get<0>(*opt1) == at1.at(3));
} }
// trailing wildcard // trailing wildcard
auto opt2 = tuple_cast<std::string, anything>(at1); auto opt2 = tuple_cast<std::string, anything>(at1);
CPPA_CHECK(opt2); CPPA_CHECK(opt2);
if (opt2) { if (opt2) {
CPPA_CHECK_EQUAL(get<0>(*opt2), "one"); CPPA_CHECK_EQUAL(get<0>(*opt2), "one");
CPPA_CHECK_EQUAL(&get<0>(*opt2), at1.at(0)); CPPA_CHECK(&get<0>(*opt2) == at1.at(0));
} }
// wildcard in between // wildcard in between
auto opt3 = tuple_cast<std::string, anything, double>(at1); auto opt3 = tuple_cast<std::string, anything, double>(at1);
...@@ -394,8 +394,8 @@ void check_wildcards() { ...@@ -394,8 +394,8 @@ void check_wildcards() {
CPPA_CHECK((*opt3 == make_cow_tuple("one", 4.0))); CPPA_CHECK((*opt3 == make_cow_tuple("one", 4.0)));
CPPA_CHECK_EQUAL(get<0>(*opt3), "one"); CPPA_CHECK_EQUAL(get<0>(*opt3), "one");
CPPA_CHECK_EQUAL(get<1>(*opt3), 4.0); CPPA_CHECK_EQUAL(get<1>(*opt3), 4.0);
CPPA_CHECK_EQUAL(&get<0>(*opt3), at1.at(0)); CPPA_CHECK(&get<0>(*opt3) == at1.at(0));
CPPA_CHECK_EQUAL(&get<1>(*opt3), at1.at(3)); CPPA_CHECK(&get<1>(*opt3) == at1.at(3));
} }
} }
} }
......
...@@ -70,22 +70,22 @@ int main() { ...@@ -70,22 +70,22 @@ int main() {
// the uniform_type_info implementation is correct // the uniform_type_info implementation is correct
std::set<std::string> expected = { std::set<std::string> expected = {
"bool", "bool",
"@_::foo", // <anonymous namespace>::foo "$::foo", // <anonymous namespace>::foo
"@i8", "@i16", "@i32", "@i64", // signed integer names "@i8", "@i16", "@i32", "@i64", // signed integer names
"@u8", "@u16", "@u32", "@u64", // unsigned integer names "@u8", "@u16", "@u32", "@u64", // unsigned integer names
"@str", "@u16str", "@u32str", // strings "@str", "@u16str", "@u32str", // strings
"@strmap", // string containers "@strmap", // string containers
"float", "double", "long double", // floating points "float", "double", "@ldouble", // floating points
"@0", // cppa::util::void_type "@0", // cppa::util::void_type
// default announced cppa types // default announced cppa types
"@atom", // cppa::atom_value "@atom", // cppa::atom_value
"@<>", // cppa::any_tuple "@tuple", // cppa::any_tuple
"@hdr", // cppa::detail::addressed_message "@header", // cppa::message_header
"@actor", // cppa::actor_ptr "@actor", // cppa::actor_ptr
"@group", // cppa::group_ptr "@group", // cppa::group_ptr
"@channel", // cppa::channel_ptr "@channel", // cppa::channel_ptr
"@process_info", // cppa::intrusive_ptr<cppa::process_information> "@proc", // cppa::intrusive_ptr<cppa::process_information>
"cppa::util::duration" "@duration" // cppa::util::duration
}; };
// holds the type names we see at runtime // holds the type names we see at runtime
std::set<std::string> found; std::set<std::string> found;
......
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