Commit 4b51aa95 authored by Dominik Charousset's avatar Dominik Charousset

added atoms to the list of primitive types

parent f741432a
...@@ -43,6 +43,9 @@ namespace cppa { namespace detail { ...@@ -43,6 +43,9 @@ namespace cppa { namespace detail {
template<primitive_type PT> template<primitive_type PT>
struct ptype_to_type : util::wrapped<void> { }; struct ptype_to_type : util::wrapped<void> { };
// libcppa types
template<> struct ptype_to_type<pt_atom > : util::wrapped<atom_value > { };
// integer types // integer types
template<> struct ptype_to_type<pt_int8 > : util::wrapped<std::int8_t > { }; template<> struct ptype_to_type<pt_int8 > : util::wrapped<std::int8_t > { };
template<> struct ptype_to_type<pt_uint8 > : util::wrapped<std::uint8_t > { }; template<> struct ptype_to_type<pt_uint8 > : util::wrapped<std::uint8_t > { };
......
...@@ -88,6 +88,7 @@ struct type_to_ptype_impl { ...@@ -88,6 +88,7 @@ struct type_to_ptype_impl {
template<> struct type_to_ptype_impl<float> : wrapped_ptype<pt_float > { }; template<> struct type_to_ptype_impl<float> : wrapped_ptype<pt_float > { };
template<> struct type_to_ptype_impl<double> : wrapped_ptype<pt_double > { }; template<> struct type_to_ptype_impl<double> : wrapped_ptype<pt_double > { };
template<> struct type_to_ptype_impl<long double> : wrapped_ptype<pt_long_double> { }; template<> struct type_to_ptype_impl<long double> : wrapped_ptype<pt_long_double> { };
template<> struct type_to_ptype_impl<atom_value> : wrapped_ptype<pt_atom > { };
template<typename T> template<typename T>
struct type_to_ptype : type_to_ptype_impl<typename util::rm_const_and_ref<T>::type> { }; struct type_to_ptype : type_to_ptype_impl<typename util::rm_const_and_ref<T>::type> { };
......
...@@ -57,6 +57,7 @@ enum primitive_type : unsigned char { ...@@ -57,6 +57,7 @@ enum primitive_type : unsigned char {
pt_u8string, /**< equivalent of @p std::string */ pt_u8string, /**< equivalent of @p std::string */
pt_u16string, /**< equivalent of @p std::u16string */ pt_u16string, /**< equivalent of @p std::u16string */
pt_u32string, /**< equivalent of @p std::u32string */ pt_u32string, /**< equivalent of @p std::u32string */
pt_atom, /**< equivalent of @p atom_value */
pt_null /**< equivalent of @p void */ pt_null /**< equivalent of @p void */
}; };
...@@ -65,7 +66,7 @@ constexpr const char* primitive_type_names[] = { ...@@ -65,7 +66,7 @@ constexpr const char* primitive_type_names[] = {
"pt_uint8", "pt_uint16", "pt_uint32", "pt_uint64", "pt_uint8", "pt_uint16", "pt_uint32", "pt_uint64",
"pt_float", "pt_double", "pt_long_double", "pt_float", "pt_double", "pt_long_double",
"pt_u8string", "pt_u16string", "pt_u32string", "pt_u8string", "pt_u16string", "pt_u32string",
"pt_null" "pt_atom", "pt_null"
}; };
/** /**
......
...@@ -100,6 +100,7 @@ class primitive_variant { ...@@ -100,6 +100,7 @@ class primitive_variant {
std::string s8; std::string s8;
std::u16string s16; std::u16string s16;
std::u32string s32; std::u32string s32;
atom_value av;
}; };
// use static call dispatching to select member // use static call dispatching to select member
...@@ -117,6 +118,7 @@ class primitive_variant { ...@@ -117,6 +118,7 @@ class primitive_variant {
inline std::string& get(util::pt_token<pt_u8string>) { return s8; } inline std::string& get(util::pt_token<pt_u8string>) { return s8; }
inline std::u16string& get(util::pt_token<pt_u16string>) { return s16; } inline std::u16string& get(util::pt_token<pt_u16string>) { return s16; }
inline std::u32string& get(util::pt_token<pt_u32string>) { return s32; } inline std::u32string& get(util::pt_token<pt_u32string>) { return s32; }
inline atom_value& get(util::pt_token<pt_atom>) { return av; }
// get(...) const overload // get(...) const overload
template<primitive_type PT> template<primitive_type PT>
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#ifndef CPPA_PT_DISPATCH_HPP #ifndef CPPA_PT_DISPATCH_HPP
#define CPPA_PT_DISPATCH_HPP #define CPPA_PT_DISPATCH_HPP
#include "cppa/primitive_type.hpp"
#include "cppa/util/pt_token.hpp"
namespace cppa { namespace util { namespace cppa { namespace util {
/** /**
...@@ -55,6 +58,7 @@ void pt_dispatch(primitive_type ptype, Fun&& f) { ...@@ -55,6 +58,7 @@ void pt_dispatch(primitive_type ptype, Fun&& f) {
case pt_u8string: f(pt_token<pt_u8string>()); break; case pt_u8string: f(pt_token<pt_u8string>()); break;
case pt_u16string: f(pt_token<pt_u16string>()); break; case pt_u16string: f(pt_token<pt_u16string>()); break;
case pt_u32string: f(pt_token<pt_u32string>()); break; case pt_u32string: f(pt_token<pt_u32string>()); break;
case pt_atom: f(pt_token<pt_atom>()); break;
default: break; default: break;
} }
} }
......
...@@ -180,7 +180,8 @@ struct is_primitive { ...@@ -180,7 +180,8 @@ struct is_primitive {
static constexpr bool value = std::is_arithmetic<T>::value static constexpr bool value = std::is_arithmetic<T>::value
|| std::is_convertible<T, std::string>::value || std::is_convertible<T, std::string>::value
|| std::is_convertible<T, std::u16string>::value || std::is_convertible<T, std::u16string>::value
|| std::is_convertible<T, std::u32string>::value; || std::is_convertible<T, std::u32string>::value
|| std::is_convertible<T, atom_value>::value;
}; };
/** /**
......
...@@ -101,19 +101,12 @@ pointer read_unicode_string(pointer begin, pointer end, StringType& str) { ...@@ -101,19 +101,12 @@ pointer read_unicode_string(pointer begin, pointer end, StringType& str) {
return begin; return begin;
} }
/* pointer read_range(pointer begin, pointer end, atom_value& storage) {
// @returns the next iterator position std::uint64_t tmp;
template<typename T> auto result = read_range(begin, end, tmp);
pointer read_range(pointer begin, pointer end, T& value, storage = static_cast<atom_value>(tmp);
typename enable_if<is_floating_point<T>::value>::type* = 0) {
// floating points are written as strings
string str;
auto result = read_unicode_string<char>(begin, end, str);
istringstream iss(str);
iss >> value;
return result; return result;
} }
*/
pointer read_range(pointer begin, pointer end, u16string& storage) { pointer read_range(pointer begin, pointer end, u16string& storage) {
// char16_t is guaranteed to has *at least* 16 bytes, // char16_t is guaranteed to has *at least* 16 bytes,
......
...@@ -69,22 +69,13 @@ class binary_writer { ...@@ -69,22 +69,13 @@ class binary_writer {
template<typename T> template<typename T>
void operator()(const T& value, void operator()(const T& value,
// typename enable_if<std::is_integral<T>::value>::type* = 0) {
typename enable_if<std::is_arithmetic<T>::value>::type* = 0) { typename enable_if<std::is_arithmetic<T>::value>::type* = 0) {
write_int(m_sink, value); write_int(m_sink, value);
} }
/* void operator()(const atom_value& val) {
template<typename T> (*this)(static_cast<uint64_t>(val));
void operator()(const T& value,
typename enable_if<std::is_floating_point<T>::value>::type* = 0) {
// write floating points as strings
std::ostringstream iss;
iss.precision(std::numeric_limits<T>::max_digits10);
iss << value;
(*this)(iss.str());
} }
*/
void operator()(const std::string& str) { void operator()(const std::string& str) {
write_string(m_sink, str); write_string(m_sink, str);
......
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
#include "cppa/primitive_variant.hpp" #include "cppa/primitive_variant.hpp"
#include "cppa/uniform_type_info.hpp" #include "cppa/uniform_type_info.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/io/default_actor_addressing.hpp" #include "cppa/io/default_actor_addressing.hpp"
#include "cppa/detail/uniform_type_info_map.hpp" #include "cppa/detail/uniform_type_info_map.hpp"
...@@ -95,10 +97,15 @@ class string_serializer : public serializer { ...@@ -95,10 +97,15 @@ class string_serializer : public serializer {
void operator()(const u32string&) { } void operator()(const u32string&) { }
void operator()(const atom_value& value) {
out << "'" << to_string(value) << "'";
}
}; };
bool m_after_value; bool m_after_value;
bool m_obj_just_opened; bool m_obj_just_opened;
stack<size_t> m_object_pos;
stack<string> m_open_objects; stack<string> m_open_objects;
inline void clear() { inline void clear() {
...@@ -117,7 +124,8 @@ class string_serializer : public serializer { ...@@ -117,7 +124,8 @@ class string_serializer : public serializer {
public: public:
string_serializer(ostream& mout) string_serializer(ostream& mout)
: super(&m_addressing), out(mout), m_after_value(false), m_obj_just_opened(false) { } : super(&m_addressing), out(mout), m_after_value(false)
, m_obj_just_opened(false) { }
void begin_object(const uniform_type_info* uti) { void begin_object(const uniform_type_info* uti) {
clear(); clear();
...@@ -125,6 +133,10 @@ class string_serializer : public serializer { ...@@ -125,6 +133,10 @@ class string_serializer : public serializer {
m_open_objects.push(tname); m_open_objects.push(tname);
// do not print type names for strings and atoms // do not print type names for strings and atoms
if (!isbuiltin(tname)) out << tname; if (!isbuiltin(tname)) out << tname;
else if (tname.compare(0, 3, "@<>") == 0) {
auto subtypes = util::split(tname, '+', false);
}
m_obj_just_opened = true; m_obj_just_opened = true;
} }
...@@ -157,19 +169,7 @@ class string_serializer : public serializer { ...@@ -157,19 +169,7 @@ class string_serializer : public serializer {
if (m_open_objects.empty()) { if (m_open_objects.empty()) {
throw runtime_error("write_value(): m_open_objects.empty()"); throw runtime_error("write_value(): m_open_objects.empty()");
} }
if (m_open_objects.top() == "@atom") { value.apply(pt_writer(out));
if (value.ptype() != pt_uint64) {
throw runtime_error("expected uint64 value after @atom");
}
// write atoms as strings instead of integer values
auto av = static_cast<atom_value>(get<uint64_t>(value));
out << "'";
(pt_writer(out, true))(to_string(av));
out << "'";
}
else {
value.apply(pt_writer(out));
}
m_after_value = true; m_after_value = true;
} }
...@@ -348,28 +348,15 @@ class string_deserializer : public deserializer { ...@@ -348,28 +348,15 @@ class string_deserializer : public deserializer {
void operator()(string& what) { void operator()(string& what) {
what = str; what = str;
} }
void operator()(atom_value& what) {
what = static_cast<atom_value>(detail::atom_val(str.c_str(), 0xF));
}
void operator()(u16string&) { } void operator()(u16string&) { }
void operator()(u32string&) { } void operator()(u32string&) { }
}; };
primitive_variant read_value(primitive_type ptype) { primitive_variant read_value(primitive_type ptype) {
integrity_check(); integrity_check();
if (m_open_objects.top() == "@atom") {
if (ptype != pt_uint64) {
throw_malformed("expected read of pt_uint64 after @atom");
}
consume('\'');
auto substr_end = find(m_pos, m_str.end(), '\'');
if (substr_end == m_str.end()) {
throw_malformed("couldn't find trailing ' for atom");
}
else if ((substr_end - m_pos) > 10) {
throw_malformed("atom string size > 10");
}
string substr(m_pos, substr_end);
m_pos += substr.size() + 1;
return detail::atom_val(substr.c_str(), 0xF);
}
skip_space_and_comma(); skip_space_and_comma();
string::iterator substr_end; string::iterator substr_end;
auto find_if_cond = [] (char c) -> bool { auto find_if_cond = [] (char c) -> bool {
...@@ -381,13 +368,14 @@ class string_deserializer : public deserializer { ...@@ -381,13 +368,14 @@ class string_deserializer : public deserializer {
default : return false; default : return false;
} }
}; };
if (ptype == pt_u8string) { if (ptype == pt_u8string || ptype == pt_atom) {
if (*m_pos == '"') { char needle = (ptype == pt_u8string) ? '"' : '\'';
if (*m_pos == needle) {
// skip leading " // skip leading "
++m_pos; ++m_pos;
char last_char = '"'; char last_char = needle;
auto find_if_str_cond = [&last_char] (char c) -> bool { auto find_if_str_cond = [&last_char, needle] (char c) -> bool {
if (c == '"' && last_char != '\\') { if (c == needle && last_char != '\\') {
return true; return true;
} }
last_char = c; last_char = c;
...@@ -407,11 +395,14 @@ class string_deserializer : public deserializer { ...@@ -407,11 +395,14 @@ class string_deserializer : public deserializer {
} }
string substr(m_pos, substr_end); string substr(m_pos, substr_end);
m_pos += substr.size(); m_pos += substr.size();
if (ptype == pt_u8string) { if (ptype == pt_u8string || ptype == pt_atom) {
char needle = (ptype == pt_u8string) ? '"' : '\'';
// skip trailing " // skip trailing "
if (*m_pos != '"') { if (*m_pos != needle) {
string error_msg; string error_msg;
error_msg = "malformed string, expected '\"' found '"; error_msg = "malformed string, expected '";
error_msg += needle;
error_msg += "' found '";
error_msg += *m_pos; error_msg += *m_pos;
error_msg += "'"; error_msg += "'";
throw logic_error(error_msg); throw logic_error(error_msg);
...@@ -419,8 +410,8 @@ class string_deserializer : public deserializer { ...@@ -419,8 +410,8 @@ class string_deserializer : public deserializer {
++m_pos; ++m_pos;
// replace '\"' by '"' // replace '\"' by '"'
char last_char = ' '; char last_char = ' ';
auto cond = [&last_char] (char c) -> bool { auto cond = [&last_char, needle] (char c) -> bool {
if (c == '"' && last_char == '\\') { if (c == needle && last_char == '\\') {
return true; return true;
} }
last_char = c; last_char = c;
...@@ -434,7 +425,7 @@ class string_deserializer : public deserializer { ...@@ -434,7 +425,7 @@ class string_deserializer : public deserializer {
i = find_if(i, send, cond)) { i = find_if(i, send, cond)) {
--i; --i;
tmp.append(sbegin, i); tmp.append(sbegin, i);
tmp += '"'; tmp += needle;
i += 2; i += 2;
sbegin = i; sbegin = i;
} }
......
...@@ -315,11 +315,11 @@ void deserialize_impl(process_information_ptr& ptr, deserializer* source) { ...@@ -315,11 +315,11 @@ void deserialize_impl(process_information_ptr& ptr, deserializer* source) {
} }
inline void serialize_impl(const atom_value& val, serializer* sink) { inline void serialize_impl(const atom_value& val, serializer* sink) {
sink->write_value(static_cast<uint64_t>(val)); sink->write_value(val);
} }
inline void deserialize_impl(atom_value& val, deserializer* source) { inline void deserialize_impl(atom_value& val, deserializer* source) {
val = static_cast<atom_value>(source->read<uint64_t>()); val = source->read<atom_value>();
} }
inline void serialize_impl(const util::duration& val, serializer* sink) { inline void serialize_impl(const util::duration& val, serializer* sink) {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#include "cppa/primitive_variant.hpp" #include "cppa/primitive_variant.hpp"
#include "cppa/detail/to_uniform_name.hpp"
namespace { namespace {
struct streamer { struct streamer {
...@@ -49,6 +51,9 @@ int main() { ...@@ -49,6 +51,9 @@ int main() {
CPPA_CHECK(equal(v1, v2)); CPPA_CHECK(equal(v1, v2));
v2 = u"Hello World"; v2 = u"Hello World";
CPPA_CHECK(!equal(v1, v2)); CPPA_CHECK(!equal(v1, v2));
primitive_variant v3{atom("hello")};
CPPA_CHECK(v3.type() == typeid(atom_value));
CPPA_CHECK(get<atom_value>(v3) == atom("hello"));
return CPPA_TEST_RESULT(); return CPPA_TEST_RESULT();
} }
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