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