Skip to content

Commit

Permalink
For most purposes, replace to_json() with json_traits<>::make; overlo…
Browse files Browse the repository at this point in the history
…ading

  doesn't work well if you want flexible ordering of declarations.
Also introduce make_json<>() as complement, because why not.
This suggests to_json() is useless and should be removed.
  • Loading branch information
Chip Salzenberg committed Apr 30, 2012
1 parent 88f814f commit 7489973
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 39 deletions.
4 changes: 2 additions & 2 deletions include/ten/jserial.hh
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class json_saver : public json_archive {
}
template <class T, class Enable = typename std::enable_if<json_traits<T>::can_make>::type>
friend void serialize(json_saver &ar, const T &t) {
serialize(ar, to_json(t));
serialize(ar, json_traits<T>::make(t));
}

// kvt<> and const_kvt<> specialization
Expand Down Expand Up @@ -204,7 +204,7 @@ class json_loader : public json_archive {
}
template <class T, class Enable = typename std::enable_if<json_traits<T>::can_cast>::type>
friend void serialize(json_loader &ar, T &t) {
t = json_cast<T>(ar._j);
t = json_traits<T>::cast(ar._j);
}

// kvt<> and const_kvt<> specialization
Expand Down
32 changes: 14 additions & 18 deletions include/ten/jserial_assoc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define LIBTEN_JSERIAL_ASSOC_HH

#include <boost/version.hpp>
#if BOOST_VERSION > 104800
#if BOOST_VERSION >= 104800
#include <boost/container/flat_map.hpp>
#endif
#include <ten/jserial.hh>
Expand Down Expand Up @@ -34,35 +34,31 @@ struct json_traits_assoc : public json_traits<typename Assoc::mapped_type> {
a.insert(value_type(jel.first, json_traits<mapped_type>::cast(jel.second)));
return a;
}
};

template <class Assoc>
inline json to_json_assoc(const Assoc &a) {
json j{};
for (auto const & el : a)
j.set(el.first, to_json(el.second));
return j;
}
static json make(const Assoc &a) {
json j({});
for (auto const & el : a)
j.set(el.first, json_traits<mapped_type>::make(el.second));
return j;
}
};

//
// map<>, unordered_map<>, flat_map<>
//

template <class K, class M, class A>
struct json_traits<map<K, M, A>> : public json_traits_assoc<map<K, M, A>> {};
struct json_traits<map<K, M, A>>
: public json_traits_assoc<map<K, M, A>> {};

template <class K, class M, class A>
struct json_traits<unordered_map<K, M, A>> : public json_traits_assoc<unordered_map<K, M, A>> {};
struct json_traits<unordered_map<K, M, A>>
: public json_traits_assoc<unordered_map<K, M, A>> {};

#if BOOST_VERSION >= 104800
template <class K, class M, class A>
struct json_traits<flat_map<K, M, A>> : public json_traits_assoc<flat_map<K, M, A>> {};
#endif

template <class K, class M, class A> inline json to_json(const map<K, M, A> &m) { return to_json_assoc(m); }
template <class K, class M, class A> inline json to_json(const unordered_map<K, M, A> &m) { return to_json_assoc(m); }
#if BOOST_VERSION >= 104800
template <class K, class M, class A> inline json to_json(const flat_map<K, M, A> &m) { return to_json_assoc(m); }
struct json_traits<flat_map<K, M, A>>
: public json_traits_assoc<flat_map<K, M, A>> {};
#endif

} // ten
Expand Down
2 changes: 1 addition & 1 deletion include/ten/jserial_enum.hh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ using std::string;

namespace detail {
template <class AR, class E, class Iter>
inline void serialize_enum(AR &ar, E &e, Iter names_start, Iter names_end, std::true_type) {
inline void serialize_enum(AR &ar, E &e, Iter names_start, Iter /*names_end*/, std::true_type) {
json j = json::str(*(names_start + (ptrdiff_t)e));
ar & j;
}
Expand Down
6 changes: 2 additions & 4 deletions include/ten/jserial_safeint.hh
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ using std::move;

template <class I>
struct json_traits<SafeInt<I>> : public json_traits_conv<SafeInt<I>> {
static SafeInt<I> cast(const json &j) { return json_cast<I>(j); }
static SafeInt<I> cast(const json &j) { return json_traits<I>::cast(j); }
static json make(SafeInt<I> i) { return json_traits<I>::make(i); }
};
template <class I>
inline json to_json(SafeInt<I> i) { return to_json(i.Ref()); }


#if 0 // This has moved to jserial due to SafeInt<> having an operator &
template <class AR, class I, class X = typename std::enable_if<AR::is_archive>::type>
Expand Down
26 changes: 15 additions & 11 deletions include/ten/jserial_seq.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define LIBTEN_JSERIAL_SEQ_HH

#include <ten/jserial.hh>
#include <array>
#include <vector>

namespace ten {
Expand All @@ -23,23 +24,26 @@ struct json_traits_seq : public json_traits<typename Seq::value_type> {
s.push_back(json_traits<value_type>::cast(jel));
return s;
}

static json make(const Seq &s) {
json j(json::array());
for (auto const & el : s)
j.push(json_traits<value_type>::make(el));
return j;
}
};

template <class Seq>
inline json to_json_seq(const Seq &s) {
json j(json::array());
for (auto const & el : s)
j.push(to_json(el));
return j;
}
// array<>

// vector<>
template <class T, size_t N>
struct json_traits<std::array<T, N>>
: public json_traits_seq<std::array<T, N>> {};

template <class T, class A>
struct json_traits<std::vector<T, A>> : public json_traits_seq<std::vector<T, A>> {};
// vector<>

template <class T, class A>
inline json to_json(const std::vector<T, A> &v) { return to_json_seq(v); }
struct json_traits<std::vector<T, A>>
: public json_traits_seq<std::vector<T, A>> {};

} // ten

Expand Down
19 changes: 16 additions & 3 deletions include/ten/json.hh
Original file line number Diff line number Diff line change
Expand Up @@ -414,27 +414,38 @@ inline json to_json(bool b) { return json(b); }
// conversions do not work for unspecified types
template <class T> struct json_traits {
typedef T type;
static const bool can_make = false; // to_json(T) works
static const bool can_cast = false; // trait<T>::cast() works
static const bool can_make = false; // trait<T>::make() -> json works
static const bool can_cast = false; // trait<T>::cast() -> T works
};

// convenience base class for conversions that work
template <class T> struct json_traits_conv {
typedef T type;
static const bool can_make = true;
static const bool can_cast = true;

static json make(T t) { return json(t); }
static T cast(const json &j); // default decl for most cases
};

// json_cast<> function, a la lexical_cast<>
template <class T>
inline typename std::enable_if<json_traits<T>::can_cast, T>::type json_cast(const json &j) {
inline typename std::enable_if<json_traits<T>::can_cast, T>::type
json_cast(const json &j) {
return json_traits<T>::cast(j);
}

// make_json<> function, rather like to_json() but with a precise type
template <class T>
inline typename std::enable_if<json_traits<T>::can_cast, T>::type
make_json(T t) {
return json_traits<T>::make(t);
}

// identity
template <> struct json_traits<json> : public json_traits_conv<json> {
static json cast(const json &j) { return j; }
static json make(const json &j) { return j; }
};

// string
Expand All @@ -443,6 +454,8 @@ template <> struct json_traits<const char *> {
typedef const char *type;
static const bool can_make = true; // makes copy
static const bool can_cast = false; // sorry, private pointer

static json make(const char *s) { return json(s); }
};

// integer
Expand Down

0 comments on commit 7489973

Please sign in to comment.