Skip to content

Commit ac677a1

Browse files
committed
Moved independent code out, that can be reused for other types of smart pointers.
1 parent 4ab4d8a commit ac677a1

File tree

6 files changed

+181
-114
lines changed

6 files changed

+181
-114
lines changed

parse/jsd_smart_ptr.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#pragma once
2+
3+
#include "../utility/polymorphy.h"
4+
#include "../utility/property_tree_probe.h"
5+
6+
#include <type_traits>
7+
8+
namespace JSON
9+
{
10+
namespace internal
11+
{
12+
template <typename T, bool ClassType, bool Enabler>
13+
struct smart_pointer_parser
14+
{
15+
};
16+
17+
template <typename T>
18+
struct smart_pointer_parser <T, true, true>
19+
{
20+
static void get(T& value, std::string const& name, PropertyTree const& object, ParsingOptions const& options)
21+
{
22+
value.reset(new typename std::decay<T>::type::element_type{});
23+
value->parse(name, object, options);
24+
}
25+
};
26+
27+
template <typename T>
28+
struct smart_pointer_parser <T, false, true>
29+
{
30+
static void get(T& value, std::string const& name, PropertyTree const& object, ParsingOptions const& options)
31+
{
32+
using element_type = typename std::decay<T>::type::element_type;
33+
value.reset(new element_type{});
34+
GET_VALUE(element_type, name, *value, {});
35+
}
36+
};
37+
38+
template <typename T>
39+
struct smart_pointer_parser <T, true, false>
40+
{
41+
static void get(T& value, std::string const& name, PropertyTree const& object, ParsingOptions const& options)
42+
{
43+
using polydecl_type = polydecls <typename T::element_type>;
44+
45+
try
46+
{
47+
// causes exceptions for proper error.
48+
object.tree.get <tree_probe> (name);
49+
50+
// expects type name
51+
auto type_name = object.tree.get_optional <std::string> (name + ".__cxx_type");
52+
if (!type_name)
53+
throw std::runtime_error (
54+
std::string("object with name '") +
55+
name +
56+
"' and base type '" +
57+
boost::typeindex::type_id_with_cvr<typename T::element_type>().pretty_name() +
58+
"' is declared polymorphic, but does not come with a type definition __cxx_type"
59+
);
60+
61+
// read smart pointer contents.
62+
polydecl_type::smart_pointer_get(value, type_name.get(), name, object, options);
63+
}
64+
catch (boost::property_tree::ptree_bad_data& exc)
65+
{
66+
DEFAULT_PROPERTY_ERROR_HANDLER(T(), T());
67+
}
68+
catch (boost::property_tree::ptree_bad_path& exc)
69+
{
70+
DEFAULT_PATH_ERROR_HANDLER(T(), T());
71+
}
72+
}
73+
};
74+
75+
template <typename T>
76+
struct smart_pointer_parser <T, false, false>
77+
{
78+
static void get(T& value, std::string const& name, PropertyTree const& object, ParsingOptions const& options)
79+
{
80+
// static_assert(false, "Not a class but polymorphic? you did something wrong!");
81+
// poly, but not a class
82+
}
83+
};
84+
85+
template <typename T>
86+
void parse_smart_ptr(T& value, std::string const& name,
87+
PropertyTree const& object, ParsingOptions const& options = {})
88+
{
89+
90+
using element_type = typename std::decay<decltype(value)>::type::element_type;
91+
using polydecl_type = polydecls <element_type>;
92+
93+
internal::smart_pointer_parser <T,
94+
std::is_class <element_type>::value,
95+
std::is_same <typename polydecl_type::type, no_poly>::value>::get(value,
96+
name,
97+
object,
98+
options);
99+
}
100+
}
101+
}

parse/jsd_unique_ptr.h

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,19 @@
11
#pragma once
22

33
#include "jsd_core.h"
4+
#include "jsd_smart_ptr.h"
5+
46
#include "../utility/polymorphy.h"
57

68
#include <type_traits>
79
#include <memory>
810

911
namespace JSON
1012
{
11-
namespace internal
12-
{
13-
template <typename T, bool ClassType, bool Enabler>
14-
struct type_dependent_retriever
15-
{
16-
};
17-
18-
template <typename T>
19-
struct type_dependent_retriever <T, true, true>
20-
{
21-
static void get(T& value, std::string const& name, PropertyTree const& object, ParsingOptions const& options)
22-
{
23-
value.reset(new T{});
24-
value->parse(name, object, options);
25-
}
26-
};
27-
28-
template <typename T>
29-
struct type_dependent_retriever <T, false, true>
30-
{
31-
static void get(T& value, std::string const& name, PropertyTree const& object, ParsingOptions const& options)
32-
{
33-
value.reset(new T{});
34-
GET_VALUE(T, name, *value, {});
35-
}
36-
};
37-
38-
template <typename T>
39-
struct type_dependent_retriever <T, true, false>
40-
{
41-
static void get(T& value, std::string const& name, PropertyTree const& object, ParsingOptions const& options)
42-
{
43-
using polydecl_type = polydecls <typename T::element_type>;
44-
45-
auto type_name = object.tree.get_optional <std::string> (name + ".__cxx_type");
46-
if (!type_name)
47-
throw std::runtime_error ("object is declared polymorphic, but does not come with a type definition __cxx_type");
48-
polydecl_type::smart_pointer_get(value, type_name.get(), name, object, options);
49-
}
50-
};
51-
52-
template <typename T>
53-
struct type_dependent_retriever <T, false, false>
54-
{
55-
static void get(T& value, std::string const& name, PropertyTree const& object, ParsingOptions const& options)
56-
{
57-
// static_assert(false, "Not a class but polymorphic? you did something wrong!");
58-
// poly, but not a class
59-
}
60-
};
61-
}
62-
6313
template <typename T, typename Deleter>
6414
void parse(std::unique_ptr <T, Deleter>& value, std::string const& name,
6515
PropertyTree const& object, ParsingOptions const& options = {})
6616
{
67-
using polydecl_type = polydecls <T>;
68-
69-
internal::type_dependent_retriever <typename std::decay<decltype(value)>::type,
70-
std::is_class <T>::value,
71-
std::is_same <typename polydecl_type::type, no_poly>::value>::get(value,
72-
name,
73-
object,
74-
options);
17+
internal::parse_smart_ptr(value, name, object, options);
7518
}
7619
}

stringify/jss.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
#include "jss_unordered_map.h"
2727
#include "jss_set.h"
2828
#include "jss_atomic.h"
29-
#include "jss_smart_ptr.h"
29+
#include "jss_unique_ptr.h"
30+
#include "jss_shared_ptr.h"
31+
#include "jss_weak_ptr.h"
3032
#include "jss_check.h"
3133
#include "jss_optional.h"
3234
#include "jss_renamed.h"

stringify/jss_smart_ptr.h

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,56 @@
1-
#ifndef JSS_SMART_PTR_H_INCLUDED
2-
#define JSS_SMART_PTR_H_INCLUDED
1+
#pragma once
2+
3+
namespace JSON
4+
{
5+
namespace internal
6+
{
7+
template <typename T, bool IsClass, bool IsPolymorphic>
8+
struct smart_pointer_stringifier
9+
{
10+
};
11+
12+
template <typename T>
13+
struct smart_pointer_stringifier <T, true, false>
14+
{
15+
static void exec(std::ostream& stream, const std::string& name, T const& value, StringificationOptions const& options)
16+
{
17+
value->stringify(stream, options);
18+
}
19+
};
20+
21+
template <typename T>
22+
struct smart_pointer_stringifier <T, true, true>
23+
{
24+
static void exec(std::ostream& stream, const std::string& name, T const& value, StringificationOptions const& options)
25+
{
26+
//value->stringify(stream, options);
27+
polydecls <typename T::element_type>::smart_pointer_set(value, stream, options);
28+
}
29+
};
30+
31+
template <typename T, bool IsPolymorphic>
32+
struct smart_pointer_stringifier <T, false, IsPolymorphic>
33+
{
34+
static void exec(std::ostream& stream, const std::string& name, T const& value, StringificationOptions const& options)
35+
{
36+
stringify(stream, name, *value, options);
37+
}
38+
};
39+
40+
template <typename T>
41+
std::ostream& stringify_smart_ptr(std::ostream& stream, const std::string& name, T const& value, StringificationOptions const& options = {})
42+
{
43+
if (options.in_object && !options.ignore_name)
44+
WRITE_NAME(stream);
45+
46+
using element_type = typename std::decay<decltype(value)>::type::element_type;
347

4-
#include "jss_shared_ptr.h"
5-
#include "jss_unique_ptr.h"
6-
#include "jss_weak_ptr.h"
7-
8-
#endif // JSS_SMART_PTR_H_INCLUDED
48+
internal::smart_pointer_stringifier <
49+
typename std::decay<decltype(value)>::type,
50+
std::is_class <element_type>::value,
51+
!std::is_same <element_type, no_poly>::value
52+
>::exec(stream, name, value, options);
53+
return stream;
54+
}
55+
}
56+
}

stringify/jss_unique_ptr.h

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,13 @@
22
#define JSS_UNIQUE_PTR_H_INCLUDED
33

44
#include "jss_core.h"
5+
#include "jss_smart_ptr.h"
56
#include "../utility/polymorphy.h"
67

78
#include <memory>
89

910
namespace JSON
10-
{
11-
namespace internal
12-
{
13-
template <typename T, bool IsClass, bool IsPolymorphic>
14-
struct stringify_call_chooser
15-
{
16-
};
17-
18-
template <typename T>
19-
struct stringify_call_chooser <T, true, false>
20-
{
21-
static void exec(std::ostream& stream, const std::string& name, T const& value, StringificationOptions const& options)
22-
{
23-
value->stringify(stream, options);
24-
}
25-
};
26-
27-
template <typename T>
28-
struct stringify_call_chooser <T, true, true>
29-
{
30-
static void exec(std::ostream& stream, const std::string& name, T const& value, StringificationOptions const& options)
31-
{
32-
//value->stringify(stream, options);
33-
polydecls <typename T::element_type>::smart_pointer_set(value, stream, options);
34-
}
35-
};
36-
37-
template <typename T, bool IsPolymorphic>
38-
struct stringify_call_chooser <T, false, IsPolymorphic>
39-
{
40-
static void exec(std::ostream& stream, const std::string& name, T const& value, StringificationOptions const& options)
41-
{
42-
stringify(stream, name, *value, options);
43-
}
44-
};
45-
}
46-
11+
{
4712
template <typename T, typename Deleter,
4813
typename = typename std::enable_if <
4914
Internal::can_stringify<T>::value ||
@@ -54,15 +19,7 @@ namespace JSON
5419
if (!value)
5520
throw UniquePtrNullptrException{};
5621

57-
if (options.in_object && !options.ignore_name)
58-
WRITE_NAME(stream);
59-
60-
internal::stringify_call_chooser <
61-
typename std::decay<decltype(value)>::type,
62-
std::is_class <T>::value,
63-
!std::is_same <typename polydecls <T>::type, no_poly>::value
64-
>::exec(stream, name, value, options);
65-
return stream;
22+
internal::stringify_smart_ptr(stream, name, value, options);
6623
}
6724
}
6825

utility/property_tree_probe.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
3+
#include <iosfwd>
4+
5+
namespace JSON
6+
{
7+
struct tree_probe
8+
{
9+
};
10+
11+
inline std::istream& operator>>(std::istream& istream, tree_probe const&)
12+
{
13+
// ignore.
14+
return istream;
15+
}
16+
}

0 commit comments

Comments
 (0)