Commit 5a61e5da authored by Dominik Charousset's avatar Dominik Charousset

Move to_string and from_string to a single header

parent 0a440521
......@@ -25,7 +25,6 @@ set (LIBCAF_CORE_SRCS
src/actor_ostream.cpp
src/actor_proxy.cpp
src/actor_registry.cpp
src/atom.cpp
src/attachable.cpp
src/behavior.cpp
src/behavior_stack.cpp
......
......@@ -36,11 +36,6 @@ enum class atom_value : uint64_t {
};
/**
* Returns `what` as a string representation.
*/
std::string to_string(const atom_value& what);
/**
* Creates an atom from given string literal.
*/
......
......@@ -20,41 +20,6 @@
#ifndef CAF_FROM_STRING_HPP
#define CAF_FROM_STRING_HPP
#include <string>
#include <typeinfo>
#include <exception>
#include "caf/uniform_type_info.hpp"
namespace caf {
/**
* Converts a string created by `to_string` to its original value.
*/
uniform_value from_string_impl(const std::string& what);
/**
* Convenience function that tries to deserializes a value from
* `what` and converts the result to `T`.
*/
template <class T>
optional<T> from_string(const std::string& what) {
auto uti = uniform_typeid<T>();
auto uv = from_string_impl(what);
if (!uv || (*uv->ti) != typeid(T)) {
// try again using the type name
std::string tmp = uti->name();
tmp += " ( ";
tmp += what;
tmp += " )";
uv = from_string_impl(tmp);
}
if (uv && (*uv->ti) == typeid(T)) {
return T{std::move(*reinterpret_cast<T*>(uv->val))};
}
return none;
}
} // namespace caf
#include "caf/string_serialization.hpp"
#endif // CAF_FROM_STRING_HPP
......@@ -159,11 +159,6 @@ class node_id : detail::comparable<node_id>,
};
/**
* @relates node_id
*/
std::string to_string(const node_id& what);
} // namespace caf
#endif // CAF_PROCESS_INFORMATION_HPP
......@@ -17,26 +17,80 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/atom.hpp"
#ifndef CAF_STRING_SERIALIZATION_HPP
#define CAF_STRING_SERIALIZATION_HPP
#include <string>
#include "caf/fwd.hpp"
#include "caf/optional.hpp"
#include "caf/uniform_type_info.hpp"
namespace std {
class exception;
}
namespace caf {
std::string to_string(const atom_value& what) {
auto x = static_cast<uint64_t>(what);
std::string result;
result.reserve(11);
// don't read characters before we found the leading 0xF
// first four bits set?
bool read_chars = ((x & 0xF000000000000000) >> 60) == 0xF;
uint64_t mask = 0x0FC0000000000000;
for (int bitshift = 54; bitshift >= 0; bitshift -= 6, mask >>= 6) {
if (read_chars) {
result += detail::decoding_table[(x & mask) >> bitshift];
} else if (((x & mask) >> bitshift) == 0xF) {
read_chars = true;
}
std::string to_string(const message& what);
std::string to_string(const group& what);
std::string to_string(const channel& what);
std::string to_string(const message_id& what);
std::string to_string(const actor_addr& what);
std::string to_string(const actor& what);
/**
* @relates node_id
*/
//std::string to_string(const node_id::host_id_type& node_id);
/**
* @relates node_id
*/
std::string to_string(const node_id& what);
/**
* Returns `what` as a string representation.
*/
std::string to_string(const atom_value& what);
/**
* Converts `e` to a string including the demangled type of `e` and `e.what()`.
*/
std::string to_verbose_string(const std::exception& e);
/**
* Converts a string created by `to_string` to its original value.
*/
uniform_value from_string_impl(const std::string& what);
/**
* Convenience function that tries to deserializes a value from
* `what` and converts the result to `T`.
*/
template <class T>
optional<T> from_string(const std::string& what) {
auto uti = uniform_typeid<T>();
auto uv = from_string_impl(what);
if (!uv || (*uv->ti) != typeid(T)) {
// try again using the type name
std::string tmp = uti->name();
tmp += " ( ";
tmp += what;
tmp += " )";
uv = from_string_impl(tmp);
}
return result;
if (uv && (*uv->ti) == typeid(T)) {
return T{std::move(*reinterpret_cast<T*>(uv->val))};
}
return none;
}
} // namespace caf
#endif // CAF_STRING_SERIALIZATION_HPP
......@@ -20,76 +20,6 @@
#ifndef CAF_TO_STRING_HPP
#define CAF_TO_STRING_HPP
#include <type_traits>
#include "caf/intrusive_ptr.hpp"
#include "caf/atom.hpp" // included for to_string(atom_value)
#include "caf/actor.hpp"
#include "caf/group.hpp"
#include "caf/channel.hpp"
#include "caf/node_id.hpp"
#include "caf/message.hpp"
#include "caf/anything.hpp"
#include "caf/actor_addr.hpp"
#include "caf/abstract_group.hpp"
#include "caf/uniform_type_info.hpp"
namespace std {
class exception;
}
namespace caf {
namespace detail {
std::string to_string_impl(const void* what, const uniform_type_info* utype);
template <class T>
inline std::string to_string_impl(const T& what) {
return to_string_impl(&what, uniform_typeid<T>());
}
} // namespace detail
std::string to_string(const actor_addr& what);
inline std::string to_string(const actor& what) {
return to_string(what.address());
}
inline std::string to_string(const message& what) {
return detail::to_string_impl(what);
}
inline std::string to_string(const group& what) {
return detail::to_string_impl(what);
}
inline std::string to_string(const channel& what) {
return detail::to_string_impl(what);
}
inline std::string to_string(const message_id& what) {
return detail::to_string_impl(what);
}
// implemented in node_id.cpp
std::string to_string(const node_id& what);
// implemented in node_id.cpp
std::string to_string(const node_id& what);
template <class T, class U, class... Us>
std::string to_string(const T& a1, const U& a2, const Us&... as) {
return to_string(a1) + ", " + to_string(a2, as...);
}
/**
* Converts `e` to a string including the demangled type of `e` and `e.what()`.
*/
std::string to_verbose_string(const std::exception& e);
} // namespace caf
#include "caf/string_serialization.hpp"
#endif // CAF_TO_STRING_HPP
......@@ -123,17 +123,6 @@ node_id::node_id(uint32_t a, const host_id_type& b) : m_data(new data{a, b}) {
// nop
}
std::string to_string(const node_id::host_id_type& node_id) {
std::ostringstream oss;
oss << std::hex;
oss.fill('0');
for (size_t i = 0; i < node_id::host_id_size; ++i) {
oss.width(2);
oss << static_cast<uint32_t>(node_id[i]);
}
return oss.str();
}
int node_id::compare(const invalid_node_id_t&) const {
return m_data ? 1 : 0; // invalid instances are always smaller
}
......@@ -162,12 +151,6 @@ int node_id::compare(const node_id& other) const {
return tmp;
}
std::string to_string(const node_id& what) {
std::ostringstream oss;
oss << to_string(what.host_id()) << ":" << what.process_id();
return oss.str();
}
node_id::data::data(uint32_t procid, host_id_type hid)
: process_id(procid), host_id(hid) {
// nop
......
......@@ -26,7 +26,12 @@
#include "caf/string_algorithms.hpp"
#include "caf/atom.hpp"
#include "caf/actor.hpp"
#include "caf/channel.hpp"
#include "caf/message.hpp"
#include "caf/node_id.hpp"
#include "caf/to_string.hpp"
#include "caf/actor_addr.hpp"
#include "caf/serializer.hpp"
#include "caf/from_string.hpp"
#include "caf/deserializer.hpp"
......@@ -144,7 +149,7 @@ class string_serializer : public serializer, public dummy_backend {
if (!isbuiltin(tname))
out << tname;
else if (tname.compare(0, 3, "@<>") == 0) {
std::vector<std::string> subtypes;
std::vector<string> subtypes;
split(subtypes, tname, is_any_of("+"), token_compress_on);
}
m_obj_just_opened = true;
......@@ -412,7 +417,7 @@ class string_deserializer : public deserializer, public dummy_backend {
}
char c = *m_pos++;
if (!isxdigit(c)) {
std::string errmsg = "unexpected character: '";
string errmsg = "unexpected character: '";
errmsg += c;
errmsg += "', expected [0-9a-f]";
throw_malformed(errmsg);
......@@ -510,9 +515,30 @@ string to_string_impl(const void* what, const uniform_type_info* utype) {
return osstr.str();
}
template <class T>
inline string to_string_impl(const T& what) {
return to_string_impl(&what, uniform_typeid<T>());
}
} // namespace detail
std::string to_string(const actor_addr& what) {
string to_string(const message& what) {
return detail::to_string_impl(what);
}
string to_string(const group& what) {
return detail::to_string_impl(what);
}
string to_string(const channel& what) {
return detail::to_string_impl(what);
}
string to_string(const message_id& what) {
return detail::to_string_impl(what);
}
string to_string(const actor_addr& what) {
if (what == invalid_actor_addr) {
return "0@00000000000000000000:0";
}
......@@ -521,6 +547,45 @@ std::string to_string(const actor_addr& what) {
return oss.str();
}
string to_string(const actor& what) {
return to_string(what.address());
}
string to_string(const atom_value& what) {
auto x = static_cast<uint64_t>(what);
string result;
result.reserve(11);
// don't read characters before we found the leading 0xF
// first four bits set?
bool read_chars = ((x & 0xF000000000000000) >> 60) == 0xF;
uint64_t mask = 0x0FC0000000000000;
for (int bitshift = 54; bitshift >= 0; bitshift -= 6, mask >>= 6) {
if (read_chars) {
result += detail::decoding_table[(x & mask) >> bitshift];
} else if (((x & mask) >> bitshift) == 0xF) {
read_chars = true;
}
}
return result;
}
string to_string(const node_id::host_id_type& node_id) {
std::ostringstream oss;
oss << std::hex;
oss.fill('0');
for (size_t i = 0; i < node_id::host_id_size; ++i) {
oss.width(2);
oss << static_cast<uint32_t>(node_id[i]);
}
return oss.str();
}
string to_string(const node_id& what) {
std::ostringstream oss;
oss << to_string(what.host_id()) << ":" << what.process_id();
return oss.str();
}
string to_verbose_string(const std::exception& e) {
std::ostringstream oss;
oss << detail::demangle(typeid(e)) << ": " << e.what();
......
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