Skip to content

Commit 669c9e8

Browse files
committed
Added json filler for rolling release configs, that are default constructible.
1 parent 51721ca commit 669c9e8

File tree

5 files changed

+187
-71
lines changed

5 files changed

+187
-71
lines changed

parse/jsd_fusion_adapted_struct.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ namespace JSON
1919
class AdaptedParser
2020
{
2121
public:
22-
void operator()(T& object, std::string const& name, PropertyTree const& tree, ParsingOptions const& options) const
22+
typename std::enable_if <Internal::isParsable<T>::value, void>::type
23+
operator()(T& object, std::string const& name, PropertyTree const& tree, ParsingOptions const& options) const
2324
{
2425
//! If you get an Error here, you likely forgot to use BOOST_FUSION_ADAPT_STRUCT !
2526

stringify/jss_fusion_adapted_struct.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#endif
88

99
#include "jss_optional.hpp"
10+
#include "../utility/optional_info.hpp"
1011
#include "../utility/polymorphy.hpp"
1112

1213
#include <type_traits>

stringify/jss_optional.hpp

Lines changed: 5 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,11 @@
1-
#pragma once
2-
3-
#include "../utility/tmp_util/fundamental/eval_if.hpp"
4-
#include "../utility/tmp_util/fundamental/is_same.hpp"
5-
#include "../utility/tmp_util/fundamental/null_type.hpp"
6-
7-
// really want to swap with std::optional
8-
#include <boost/optional.hpp>
1+
#pragma once
2+
3+
#include "jss_core.hpp"
4+
5+
#include <boost/optional.hpp>
96

107
namespace JSON
118
{
12-
namespace Internal
13-
{
14-
template <typename T>
15-
struct has_value_type {
16-
typedef char yes[1];
17-
typedef char no[2];
18-
19-
template <typename C>
20-
static yes& test(typename C::value_type*);
21-
22-
template <typename>
23-
static no& test(...);
24-
25-
constexpr static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
26-
using type = JSON::bool_ <value>;
27-
};
28-
29-
template <typename T>
30-
using has_value_type_t = typename has_value_type <T>::type;
31-
32-
struct get_value_type
33-
{
34-
template <typename T>
35-
struct apply
36-
{
37-
using type = typename T::value_type;
38-
};
39-
};
40-
41-
template <typename T>
42-
struct is_optional
43-
{
44-
using __value_type = JSON::eval_if_default_t <has_value_type_t <T>, JSON::null_t, get_value_type, T>;
45-
using type = JSON::eval_if_default_t <
46-
JSON::bool_ <!std::is_same <__value_type, JSON::null_t>::value>,
47-
JSON::false_,
48-
JSON::is_same,
49-
T,
50-
boost::optional <__value_type>
51-
>;
52-
constexpr static const bool value = type::value;
53-
};
54-
55-
template <typename T, bool _is_optional>
56-
struct is_optional_set_impl
57-
{
58-
static inline bool isSet(T&&) noexcept { return true; }
59-
};
60-
61-
template <typename T>
62-
struct is_optional_set_impl <T, true>
63-
{
64-
static inline bool isSet(T&& t) noexcept { return t.operator bool(); }
65-
};
66-
67-
template <typename T>
68-
inline bool is_optional_set(T&& t) noexcept {
69-
using decayed = typename std::decay <T>::type;
70-
return is_optional_set_impl <T, is_optional <decayed>::value>::isSet(std::forward <T> (t));
71-
}
72-
}
73-
749
template <typename T>
7510
std::ostream& stringify (std::ostream& stream, std::string const& name, boost::optional <T> const& value, StringificationOptions const& options = {})
7611
{

utility/fill_missing.hpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#pragma once
2+
3+
#include "../parse/jsd_object.hpp"
4+
#include "../utility/optional_info.hpp"
5+
6+
#include <type_traits>
7+
#include <boost/optional.hpp>
8+
9+
#include <boost/fusion/sequence/intrinsic/at.hpp>
10+
#include <boost/fusion/include/at.hpp>
11+
#include <boost/fusion/adapted.hpp>
12+
#include <boost/fusion/include/at.hpp>
13+
#include <boost/mpl/range_c.hpp>
14+
#include <boost/mpl/for_each.hpp>
15+
#include <boost/fusion/include/size.hpp>
16+
17+
namespace JSON
18+
{
19+
template <typename T>
20+
void fill_missing(std::string const& name, PropertyTree& tree);
21+
22+
template <typename T>
23+
class Filler
24+
{
25+
public:
26+
template <typename U = T>
27+
typename std::enable_if <Internal::isParsable<U>::value, void>::type
28+
operator()(std::string const& name, PropertyTree& tree) const
29+
{
30+
//! If you get an Error here, you likely forgot to use BOOST_FUSION_ADAPT_STRUCT !
31+
32+
typedef boost::mpl::range_c<
33+
int,
34+
0,
35+
boost::fusion::result_of::size<T>::type::value
36+
> range;
37+
38+
std::stringstream sstr;
39+
boost::mpl::for_each<range>(std::bind<void>
40+
(
41+
_helper(boost::fusion::result_of::size<T>::type::value),
42+
std::placeholders::_1,
43+
std::ref(name),
44+
std::ref(tree)
45+
));
46+
}
47+
48+
template <typename U = T>
49+
typename std::enable_if <!Internal::isParsable<U>::value, void>::type
50+
operator()(std::string const& name, PropertyTree& tree) const
51+
{
52+
//std::cout << "endpoint: " << name << "\n";
53+
default_initialize <U>(name, tree);
54+
}
55+
56+
private:
57+
class _helper
58+
{
59+
public:
60+
template<class Index>
61+
void operator()(Index, std::string const& name, PropertyTree& tree) const
62+
{
63+
using type = typename boost::fusion::result_of::at_c<T, Index::value>::type;
64+
65+
if (!name.empty())
66+
default_initialize <type>(name, tree);
67+
68+
std::string deeperName;
69+
if (name.empty())
70+
deeperName = boost::fusion::extension::struct_member_name<T, Index::value>::call();
71+
else
72+
deeperName = name + "." + boost::fusion::extension::struct_member_name<T, Index::value>::call();
73+
74+
std::cout << deeperName << "\n";
75+
fill_missing <type>(deeperName, tree);
76+
}
77+
_helper(int len) : len(len) {}
78+
private:
79+
int len;
80+
};
81+
82+
template <typename U>
83+
typename std::enable_if <!Internal::is_optional <U>::value, void>::type
84+
static default_initialize(std::string const& name, PropertyTree& tree)
85+
{
86+
//using raw = typename std::decay<U>::type;
87+
auto opt = tree.tree.get_optional <std::string>(name);
88+
if (!opt)
89+
tree.tree.put(name, std::string{});
90+
}
91+
92+
template <typename U>
93+
typename std::enable_if <Internal::is_optional <U>::value, void>::type
94+
static default_initialize(std::string const& name, PropertyTree& tree)
95+
{
96+
// do nothing
97+
}
98+
};
99+
100+
template <typename T>
101+
void fill_missing(std::string const& name, PropertyTree& tree)
102+
{
103+
Filler <typename std::decay<T>::type> filler;
104+
filler(name, tree);
105+
}
106+
}

utility/optional_info.hpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#pragma once
2+
3+
#include "../utility/tmp_util/fundamental/eval_if.hpp"
4+
#include "../utility/tmp_util/fundamental/is_same.hpp"
5+
#include "../utility/tmp_util/fundamental/null_type.hpp"
6+
7+
// really want to swap with std::optional
8+
#include <boost/optional.hpp>
9+
10+
namespace JSON
11+
{
12+
namespace Internal
13+
{
14+
template <typename T>
15+
struct has_value_type {
16+
typedef char yes[1];
17+
typedef char no[2];
18+
19+
template <typename C>
20+
static yes& test(typename C::value_type*);
21+
22+
template <typename>
23+
static no& test(...);
24+
25+
constexpr static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes);
26+
using type = JSON::bool_ <value>;
27+
};
28+
29+
template <typename T>
30+
using has_value_type_t = typename has_value_type <T>::type;
31+
32+
struct get_value_type
33+
{
34+
template <typename T>
35+
struct apply
36+
{
37+
using type = typename T::value_type;
38+
};
39+
};
40+
41+
template <typename T>
42+
struct is_optional
43+
{
44+
using __value_type = JSON::eval_if_default_t <has_value_type_t <T>, JSON::null_t, get_value_type, T>;
45+
using type = JSON::eval_if_default_t <
46+
JSON::bool_ <!std::is_same <__value_type, JSON::null_t>::value>,
47+
JSON::false_,
48+
JSON::is_same,
49+
T,
50+
boost::optional <__value_type>
51+
>;
52+
constexpr static const bool value = type::value;
53+
};
54+
55+
template <typename T, bool _is_optional>
56+
struct is_optional_set_impl
57+
{
58+
static inline bool isSet(T&&) noexcept { return true; }
59+
};
60+
61+
template <typename T>
62+
struct is_optional_set_impl <T, true>
63+
{
64+
static inline bool isSet(T&& t) noexcept { return t.operator bool(); }
65+
};
66+
67+
template <typename T>
68+
inline bool is_optional_set(T&& t) noexcept {
69+
using decayed = typename std::decay <T>::type;
70+
return is_optional_set_impl <T, is_optional <decayed>::value>::isSet(std::forward <T> (t));
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)