Branch data Line data Source code
1 : : /* Copyright 2006-2009 Savarese Software Research Corporation
2 : : *
3 : : * Licensed under the Apache License, Version 2.0 (the "License");
4 : : * you may not use this file except in compliance with the License.
5 : : * You may obtain a copy of the License at
6 : : *
7 : : * https://www.savarese.com/software/ApacheLicense-2.0
8 : : *
9 : : * Unless required by applicable law or agreed to in writing, software
10 : : * distributed under the License is distributed on an "AS IS" BASIS,
11 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : : * See the License for the specific language governing permissions and
13 : : * limitations under the License.
14 : : */
15 : :
16 : : /**
17 : : * @file
18 : : * This header defines the BindProperties class.
19 : : */
20 : :
21 : : #ifndef __SSRC_WSPR_UTILITY_BIND_PROPERTIES_H
22 : : #define __SSRC_WSPR_UTILITY_BIND_PROPERTIES_H
23 : :
24 : : #include <ssrc/wisp/utility/wisp_struct.h>
25 : : #include <ssrc/wispers/utility/Properties.h>
26 : : #include <type_traits>
27 : :
28 : : __BEGIN_NS_SSRC_WSPR_UTILITY
29 : :
30 : : // TODO: find a cleaner way to do this.
31 : : template<typename T>
32 : : struct is_bindable {
33 : : typedef ssrc::wisp::utility::wisp_struct type;
34 : : };
35 : :
36 : : #define WSPR_IS_BINDABLE_SEQUENCE(T) \
37 : : __BEGIN_NS_SSRC_WSPR_UTILITY \
38 : : template<> struct is_bindable<T> { \
39 : : typedef property_vector type; \
40 : : }; \
41 : : __END_NS_SSRC_WSPR_UTILITY
42 : :
43 : : #define WSPR_IS_PRIMITIVE_BINDABLE_SEQUENCE(T) \
44 : : __BEGIN_NS_SSRC_WSPR_UTILITY \
45 : : template<> struct is_bindable<T> { \
46 : : typedef primitive_property_vector type; \
47 : : }; \
48 : : __END_NS_SSRC_WSPR_UTILITY
49 : :
50 : : /**
51 : : * BindProperties is used to create temporary function objects for use
52 : : * with wisp_struct visit() in order to copy wisp_struct member variables
53 : : * to comparably named Properties values. For example:
54 : : * <pre>
55 : : * WISP_STRUCT(IntPair, ((int, first))((int, second)));
56 : : * WISP_STRUCT(NestedPair, ((IntPair, first))((IntPair, second)));
57 : : *
58 : : * Properties props;
59 : : * NestedPair pair(IntPair(1, 2), IntPair(3, 4));
60 : : * const string expected("{first={first=1,second=2},second={first=3,second=4}}");
61 : : *
62 : : * pair.visit(BindProperties(props));
63 : : * assert(expected == to_string(props));
64 : : * </pre>
65 : : *
66 : : * As demonstrated in the example, nested wisp_struct members will be
67 : : * recursively bound.
68 : : */
69 : : class BindProperties {
70 : : Properties & properties;
71 : :
72 : : template<typename V>
73 : : const BindProperties &
74 : 8 : bind(const char * const key, const V & value,
75 : : const std::false_type&, const ssrc::wisp::utility::wisp_struct&) const
76 : : {
77 : 8 : properties.set(value, key);
78 : 8 : return *this;
79 : : }
80 : :
81 : : template<typename V>
82 : : const BindProperties &
83 : 2 : bind(const char * const key, const V & value,
84 : : const std::true_type&, const ssrc::wisp::utility::wisp_struct&) const
85 : : {
86 [ + - + - : 2 : value.visit(BindProperties(*properties.create_node(key)));
+ - + - ]
87 : 2 : return *this;
88 : : }
89 : :
90 : : // Support functions for bindable sequence bind.
91 : : template<typename Iterator>
92 : 0 : static void visit(Iterator & v, Properties & p,
93 : : const ssrc::wisp::utility::wisp_struct&)
94 : : {
95 : 0 : v->visit(BindProperties(p));
96 : 0 : }
97 : :
98 : : template<typename Iterator>
99 : 0 : static void visit(Iterator & v, Properties & p,
100 : : const primitive_property_vector&)
101 : : {
102 : 0 : primitive_property_vector & pv = p.create_primitive_property_vector();
103 : :
104 [ # # ]: 0 : for(typename Iterator::value_type::const_iterator it = v->begin(),
105 : 0 : && end = v->end(); it != end; ++it)
106 : : {
107 [ # # ]: 0 : pv.push_back(*it);
108 : : }
109 : 0 : }
110 : :
111 : : template<typename Iterator>
112 : 0 : static void visit(Iterator & v, Properties & p, const property_vector&)
113 : : {
114 : 0 : property_vector & pv = p.create_property_vector();
115 : :
116 [ # # ]: 0 : for(typename Iterator::value_type::const_iterator it = v->begin(),
117 : 0 : && end = v->end(); it != end; ++it)
118 : : {
119 [ # # ]: 0 : pv.push_back(new Properties);
120 : 0 : visit(it, pv.back(), typename is_bindable<typename Iterator::value_type::value_type>::type());
121 : : }
122 : 0 : }
123 : :
124 : : // For bindable sequences.
125 : : template<typename V>
126 : : const BindProperties &
127 : 0 : bind(const char * const key, const V & value,
128 : : const std::false_type&, const primitive_property_vector&) const
129 : : {
130 : : primitive_property_vector & pv =
131 : 0 : properties.create_primitive_property_vector(key);
132 : :
133 [ # # ]: 0 : for(typename V::const_iterator it = value.begin(), && end = value.end();
134 : : it != end; ++it)
135 : : {
136 [ # # ]: 0 : pv.push_back(*it);
137 : : }
138 : :
139 : 0 : return *this;
140 : : }
141 : :
142 : : template<typename V>
143 : : const BindProperties &
144 : 0 : bind(const char * const key, const V & value,
145 : : const std::false_type&, const property_vector&) const
146 : : {
147 : 0 : property_vector & pv = properties.create_property_vector(key);
148 : :
149 [ # # # # : 0 : for(typename V::const_iterator it = value.begin(), && end = value.end();
# # ]
150 : : it != end; ++it)
151 : : {
152 [ # # # # : 0 : pv.push_back(new Properties);
# # ]
153 [ # # # # : 0 : visit(it, pv.back(),
# # # # ]
154 : : typename is_bindable<typename V::value_type>::type());
155 : : }
156 : :
157 : 0 : return *this;
158 : : }
159 : :
160 : : public:
161 : :
162 : : /**
163 : : * Creates a BindProperties instance that will bind values to the specified
164 : : * Properties argument.
165 : : *
166 : : * @param properties A reference to the Properties instance to which
167 : : * values will be bound.
168 : : */
169 : 4 : explicit BindProperties(Properties & properties) : properties(properties) { }
170 : :
171 : : /**
172 : : * Adds a key-value pair to the associated Properties.
173 : : *
174 : : * @param key The name of the variable to bind.
175 : : * @param value The value of the variable to bind.
176 : : */
177 : : template<typename V>
178 : : const BindProperties &
179 : 10 : operator()(const char * const key, const V & value) const {
180 : : return bind(key, value,
181 : : typename std::is_base_of<ssrc::wisp::utility::wisp_struct, V>::type(),
182 [ # # # # : 10 : typename is_bindable<V>::type());
# # # # ]
183 : : }
184 : : };
185 : :
186 : : __END_NS_SSRC_WSPR_UTILITY
187 : :
188 : : #endif
|