Chris@16
|
1 /*
|
Chris@101
|
2 * Copyright Andrey Semashev 2007 - 2015.
|
Chris@16
|
3 * Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
4 * (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
5 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 */
|
Chris@16
|
7 /*!
|
Chris@16
|
8 * \file settings.hpp
|
Chris@16
|
9 * \author Andrey Semashev
|
Chris@16
|
10 * \date 11.10.2009
|
Chris@16
|
11 *
|
Chris@16
|
12 * The header contains definition of the library settings container.
|
Chris@16
|
13 */
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
|
Chris@16
|
16 #define BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
|
Chris@16
|
17
|
Chris@16
|
18 #include <cstddef>
|
Chris@16
|
19 #include <string>
|
Chris@16
|
20 #include <iterator>
|
Chris@16
|
21 #include <boost/assert.hpp>
|
Chris@16
|
22 #include <boost/move/core.hpp>
|
Chris@16
|
23 #include <boost/mpl/if.hpp>
|
Chris@16
|
24 #include <boost/iterator/iterator_adaptor.hpp>
|
Chris@16
|
25 #include <boost/optional/optional.hpp>
|
Chris@16
|
26 #include <boost/property_tree/ptree.hpp>
|
Chris@16
|
27 #include <boost/log/detail/setup_config.hpp>
|
Chris@16
|
28 #include <boost/log/detail/native_typeof.hpp>
|
Chris@16
|
29 #include <boost/utility/explicit_operator_bool.hpp>
|
Chris@16
|
30 #if !defined(BOOST_LOG_TYPEOF)
|
Chris@16
|
31 #include <boost/utility/enable_if.hpp>
|
Chris@16
|
32 #endif
|
Chris@16
|
33 #if defined(BOOST_LOG_TYPEOF) && defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
|
Chris@16
|
34 #include <boost/utility/declval.hpp>
|
Chris@16
|
35 #endif
|
Chris@16
|
36 #include <boost/log/detail/header.hpp>
|
Chris@16
|
37
|
Chris@16
|
38 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@16
|
39 #pragma once
|
Chris@16
|
40 #endif
|
Chris@16
|
41
|
Chris@16
|
42 namespace boost {
|
Chris@16
|
43
|
Chris@16
|
44 BOOST_LOG_OPEN_NAMESPACE
|
Chris@16
|
45
|
Chris@16
|
46 namespace aux {
|
Chris@16
|
47
|
Chris@16
|
48 // This workaround is needed for MSVC 10 to work around ICE caused by stack overflow
|
Chris@16
|
49 template< typename SectionT, bool IsConstV >
|
Chris@16
|
50 struct basic_settings_section_iterator_base;
|
Chris@16
|
51
|
Chris@16
|
52 template< typename SectionT >
|
Chris@16
|
53 struct basic_settings_section_iterator_base< SectionT, true >
|
Chris@16
|
54 {
|
Chris@16
|
55 typedef typename SectionT::BOOST_NESTED_TEMPLATE iter< true > iterator_type;
|
Chris@16
|
56 typedef typename SectionT::property_tree_type::const_iterator base_iterator_type;
|
Chris@16
|
57 typedef iterator_adaptor<
|
Chris@16
|
58 iterator_type,
|
Chris@16
|
59 base_iterator_type,
|
Chris@16
|
60 SectionT,
|
Chris@16
|
61 use_default,
|
Chris@16
|
62 const SectionT
|
Chris@16
|
63 > type;
|
Chris@16
|
64 };
|
Chris@16
|
65
|
Chris@16
|
66 template< typename SectionT >
|
Chris@16
|
67 struct basic_settings_section_iterator_base< SectionT, false >
|
Chris@16
|
68 {
|
Chris@16
|
69 typedef typename SectionT::BOOST_NESTED_TEMPLATE iter< false > iterator_type;
|
Chris@16
|
70 typedef typename SectionT::property_tree_type::iterator base_iterator_type;
|
Chris@16
|
71 typedef iterator_adaptor<
|
Chris@16
|
72 iterator_type,
|
Chris@16
|
73 base_iterator_type,
|
Chris@16
|
74 SectionT,
|
Chris@16
|
75 use_default,
|
Chris@16
|
76 SectionT
|
Chris@16
|
77 > type;
|
Chris@16
|
78 };
|
Chris@16
|
79
|
Chris@16
|
80 } // namespace aux
|
Chris@16
|
81
|
Chris@16
|
82 /*!
|
Chris@16
|
83 * \brief The class represents a reference to the settings container section
|
Chris@16
|
84 *
|
Chris@16
|
85 * The section refers to a sub-tree of the library settings container. It does not
|
Chris@16
|
86 * own the referred sub-tree but allows for convenient access to parameters within the subsection.
|
Chris@16
|
87 */
|
Chris@16
|
88 template< typename CharT >
|
Chris@16
|
89 class basic_settings_section
|
Chris@16
|
90 {
|
Chris@16
|
91 template< typename SectionT, bool IsConstV >
|
Chris@16
|
92 friend struct aux::basic_settings_section_iterator_base;
|
Chris@16
|
93
|
Chris@16
|
94 public:
|
Chris@16
|
95 //! Character type
|
Chris@16
|
96 typedef CharT char_type;
|
Chris@16
|
97 //! String type
|
Chris@16
|
98 typedef std::basic_string< char_type > string_type;
|
Chris@16
|
99 //! Property tree type
|
Chris@16
|
100 typedef property_tree::basic_ptree< std::string, string_type > property_tree_type;
|
Chris@16
|
101 //! Property tree path type
|
Chris@16
|
102 typedef typename property_tree_type::path_type path_type;
|
Chris@16
|
103
|
Chris@16
|
104 private:
|
Chris@16
|
105 #if !defined(BOOST_LOG_DOXYGEN_PASS)
|
Chris@16
|
106
|
Chris@16
|
107 //! A reference proxy object
|
Chris@16
|
108 #ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
|
Chris@16
|
109 template< bool IsConstV >
|
Chris@16
|
110 class ref;
|
Chris@16
|
111 template< bool IsConstV >
|
Chris@16
|
112 friend class ref;
|
Chris@16
|
113 #endif
|
Chris@16
|
114 template< bool IsConstV >
|
Chris@16
|
115 class ref
|
Chris@16
|
116 {
|
Chris@16
|
117 private:
|
Chris@16
|
118 typedef typename mpl::if_c<
|
Chris@16
|
119 IsConstV,
|
Chris@16
|
120 basic_settings_section< char_type > const,
|
Chris@16
|
121 basic_settings_section< char_type >
|
Chris@16
|
122 >::type section_type;
|
Chris@16
|
123
|
Chris@16
|
124 private:
|
Chris@16
|
125 section_type& m_section;
|
Chris@16
|
126 path_type m_path;
|
Chris@16
|
127
|
Chris@16
|
128 public:
|
Chris@16
|
129 ref(section_type& section, std::string const& section_name) :
|
Chris@16
|
130 m_section(section),
|
Chris@16
|
131 m_path(section_name)
|
Chris@16
|
132 {
|
Chris@16
|
133 }
|
Chris@16
|
134 ref(section_type& section, const char* section_name) :
|
Chris@16
|
135 m_section(section),
|
Chris@16
|
136 m_path(section_name)
|
Chris@16
|
137 {
|
Chris@16
|
138 }
|
Chris@16
|
139
|
Chris@16
|
140 ref& operator[] (std::string const& param_name)
|
Chris@16
|
141 {
|
Chris@16
|
142 m_path /= param_name;
|
Chris@16
|
143 return *this;
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 ref& operator= (string_type const& value)
|
Chris@16
|
147 {
|
Chris@16
|
148 BOOST_ASSERT(m_section.m_ptree != NULL);
|
Chris@16
|
149 m_section.m_ptree->put(m_path, value);
|
Chris@16
|
150 return *this;
|
Chris@16
|
151 }
|
Chris@16
|
152
|
Chris@16
|
153 template< bool V >
|
Chris@16
|
154 ref& operator= (ref< V > const& value)
|
Chris@16
|
155 {
|
Chris@16
|
156 BOOST_ASSERT(m_section.m_ptree != NULL);
|
Chris@16
|
157 optional< string_type > val = value.get();
|
Chris@16
|
158 if (!!val)
|
Chris@16
|
159 {
|
Chris@16
|
160 m_section.m_ptree->put(m_path, val);
|
Chris@16
|
161 }
|
Chris@16
|
162 else if (optional< property_tree_type& > node = m_section.m_ptree->get_child_optional(m_path))
|
Chris@16
|
163 {
|
Chris@16
|
164 node.put_value(string_type());
|
Chris@16
|
165 }
|
Chris@16
|
166
|
Chris@16
|
167 return *this;
|
Chris@16
|
168 }
|
Chris@16
|
169
|
Chris@16
|
170 template< typename T >
|
Chris@16
|
171 ref& operator= (T const& value)
|
Chris@16
|
172 {
|
Chris@16
|
173 BOOST_ASSERT(m_section.m_ptree != NULL);
|
Chris@16
|
174 m_section.m_ptree->put(m_path, value);
|
Chris@16
|
175 return *this;
|
Chris@16
|
176 }
|
Chris@16
|
177
|
Chris@16
|
178 BOOST_EXPLICIT_OPERATOR_BOOL()
|
Chris@16
|
179
|
Chris@16
|
180 bool operator! () const
|
Chris@16
|
181 {
|
Chris@16
|
182 return !m_section.m_ptree || !m_section.m_ptree->get_child_optional(m_path);
|
Chris@16
|
183 }
|
Chris@16
|
184
|
Chris@16
|
185 std::string get_name() const
|
Chris@16
|
186 {
|
Chris@16
|
187 return m_path.dump();
|
Chris@16
|
188 }
|
Chris@16
|
189
|
Chris@16
|
190 operator optional< string_type > () const
|
Chris@16
|
191 {
|
Chris@16
|
192 return get();
|
Chris@16
|
193 }
|
Chris@16
|
194
|
Chris@16
|
195 optional< string_type > get() const
|
Chris@16
|
196 {
|
Chris@16
|
197 if (m_section.m_ptree)
|
Chris@16
|
198 return m_section.m_ptree->template get_optional< string_type >(m_path);
|
Chris@16
|
199 else
|
Chris@16
|
200 return optional< string_type >();
|
Chris@16
|
201 }
|
Chris@16
|
202
|
Chris@16
|
203 template< typename T >
|
Chris@16
|
204 optional< T > get() const
|
Chris@16
|
205 {
|
Chris@16
|
206 if (m_section.m_ptree)
|
Chris@16
|
207 return m_section.m_ptree->template get_optional< T >(m_path);
|
Chris@16
|
208 else
|
Chris@16
|
209 return optional< T >();
|
Chris@16
|
210 }
|
Chris@16
|
211
|
Chris@16
|
212 operator section_type () const
|
Chris@16
|
213 {
|
Chris@16
|
214 return get_section();
|
Chris@16
|
215 }
|
Chris@16
|
216
|
Chris@16
|
217 section_type get_section() const
|
Chris@16
|
218 {
|
Chris@16
|
219 if (m_section.m_ptree)
|
Chris@16
|
220 return section_type(m_section.m_ptree->get_child_optional(m_path).get_ptr());
|
Chris@16
|
221 else
|
Chris@16
|
222 return section_type();
|
Chris@16
|
223 }
|
Chris@16
|
224
|
Chris@16
|
225 #if defined(BOOST_LOG_TYPEOF) && !(defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) && !defined(__PATHSCALE__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 5))
|
Chris@16
|
226 #if !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
|
Chris@16
|
227 template< typename T >
|
Chris@16
|
228 auto or_default(T const& def_value) const -> BOOST_LOG_TYPEOF(property_tree_type().get(typename property_tree_type::path_type(), def_value))
|
Chris@16
|
229 {
|
Chris@16
|
230 if (m_section.m_ptree)
|
Chris@16
|
231 return m_section.m_ptree->get(m_path, def_value);
|
Chris@16
|
232 else
|
Chris@16
|
233 return def_value;
|
Chris@16
|
234 }
|
Chris@16
|
235 #else
|
Chris@16
|
236 // GCC up to 4.5 (inclusively) segfaults on the following code, if C++11 mode is not enabled
|
Chris@16
|
237 template< typename T >
|
Chris@16
|
238 BOOST_LOG_TYPEOF(property_tree_type().get(typename property_tree_type::path_type(), boost::declval< T >())) or_default(T const& def_value) const
|
Chris@16
|
239 {
|
Chris@16
|
240 if (m_section.m_ptree)
|
Chris@16
|
241 return m_section.m_ptree->get(m_path, def_value);
|
Chris@16
|
242 else
|
Chris@16
|
243 return def_value;
|
Chris@16
|
244 }
|
Chris@16
|
245 #endif
|
Chris@16
|
246 #else
|
Chris@16
|
247 template< typename T >
|
Chris@16
|
248 T or_default(T const& def_value) const
|
Chris@16
|
249 {
|
Chris@16
|
250 if (m_section.m_ptree)
|
Chris@16
|
251 return m_section.m_ptree->get(m_path, def_value);
|
Chris@16
|
252 else
|
Chris@16
|
253 return def_value;
|
Chris@16
|
254 }
|
Chris@16
|
255
|
Chris@16
|
256 template< typename T >
|
Chris@16
|
257 typename enable_if< boost::property_tree::detail::is_character< T >, std::basic_string< T > >::type
|
Chris@16
|
258 or_default(const T* def_value) const
|
Chris@16
|
259 {
|
Chris@16
|
260 if (m_section.m_ptree)
|
Chris@16
|
261 return m_section.m_ptree->get(m_path, def_value);
|
Chris@16
|
262 else
|
Chris@16
|
263 return def_value;
|
Chris@16
|
264 }
|
Chris@16
|
265 #endif
|
Chris@16
|
266 string_type or_default(string_type const& def_value) const
|
Chris@16
|
267 {
|
Chris@16
|
268 return get().get_value_or(def_value);
|
Chris@16
|
269 }
|
Chris@16
|
270 string_type or_default(typename string_type::value_type const* def_value) const
|
Chris@16
|
271 {
|
Chris@16
|
272 if (optional< string_type > val = get())
|
Chris@16
|
273 return val.get();
|
Chris@16
|
274 else
|
Chris@16
|
275 return def_value;
|
Chris@16
|
276 }
|
Chris@16
|
277 };
|
Chris@16
|
278
|
Chris@16
|
279 //! An iterator over subsections and parameters
|
Chris@16
|
280 #ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
|
Chris@16
|
281 template< bool IsConstV >
|
Chris@16
|
282 class iter;
|
Chris@16
|
283 template< bool IsConstV >
|
Chris@16
|
284 friend class iter;
|
Chris@16
|
285 #endif
|
Chris@16
|
286 template< bool IsConstV >
|
Chris@16
|
287 class iter :
|
Chris@16
|
288 public aux::basic_settings_section_iterator_base< basic_settings_section< char_type >, IsConstV >::type
|
Chris@16
|
289 {
|
Chris@16
|
290 friend class boost::iterator_core_access;
|
Chris@16
|
291
|
Chris@16
|
292 typedef typename iter::iterator_adaptor_ iterator_adaptor_;
|
Chris@16
|
293 // NOTE: This typedef must not come from iterator_adaptor_::base_type in order to work around MSVC 10 ICE
|
Chris@16
|
294 typedef typename aux::basic_settings_section_iterator_base< basic_settings_section< char_type >, IsConstV >::base_iterator_type base_iterator_type;
|
Chris@16
|
295
|
Chris@16
|
296 public:
|
Chris@16
|
297 typedef typename iterator_adaptor_::reference reference;
|
Chris@16
|
298
|
Chris@16
|
299 public:
|
Chris@16
|
300 BOOST_DEFAULTED_FUNCTION(iter(), {})
|
Chris@16
|
301 template< bool OtherIsConstV >
|
Chris@16
|
302 iter(iter< OtherIsConstV > const& that) : iterator_adaptor_(that.base()) {}
|
Chris@16
|
303 explicit iter(base_iterator_type const& it) : iterator_adaptor_(it) {}
|
Chris@16
|
304
|
Chris@16
|
305 //! Returns the section name
|
Chris@16
|
306 std::string const& get_name() const
|
Chris@16
|
307 {
|
Chris@16
|
308 return this->base()->first;
|
Chris@16
|
309 }
|
Chris@16
|
310
|
Chris@16
|
311 private:
|
Chris@16
|
312 reference dereference() const
|
Chris@16
|
313 {
|
Chris@16
|
314 return reference(const_cast< property_tree_type* >(&this->base()->second));
|
Chris@16
|
315 }
|
Chris@16
|
316 };
|
Chris@16
|
317
|
Chris@16
|
318 public:
|
Chris@16
|
319 typedef ref< true > const_reference;
|
Chris@16
|
320 typedef ref< false > reference;
|
Chris@16
|
321 typedef iter< true > const_iterator;
|
Chris@16
|
322 typedef iter< false > iterator;
|
Chris@16
|
323 typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
Chris@16
|
324 typedef std::reverse_iterator< iterator > reverse_iterator;
|
Chris@16
|
325
|
Chris@16
|
326 #else
|
Chris@16
|
327
|
Chris@16
|
328 public:
|
Chris@16
|
329 /*!
|
Chris@16
|
330 * Constant reference to the parameter value
|
Chris@16
|
331 */
|
Chris@16
|
332 typedef implementation_defined const_reference;
|
Chris@16
|
333 /*!
|
Chris@16
|
334 * Mutable reference to the parameter value
|
Chris@16
|
335 */
|
Chris@16
|
336 typedef implementation_defined reference;
|
Chris@16
|
337
|
Chris@16
|
338 /*!
|
Chris@16
|
339 * Constant iterator over nested parameters and subsections
|
Chris@16
|
340 */
|
Chris@16
|
341 typedef implementation_defined const_iterator;
|
Chris@16
|
342 /*!
|
Chris@16
|
343 * Mutable iterator over nested parameters and subsections
|
Chris@16
|
344 */
|
Chris@16
|
345 typedef implementation_defined iterator;
|
Chris@16
|
346
|
Chris@16
|
347 #endif // !defined(BOOST_LOG_DOXYGEN_PASS)
|
Chris@16
|
348
|
Chris@16
|
349 protected:
|
Chris@16
|
350 //! Parameters
|
Chris@16
|
351 property_tree_type* m_ptree;
|
Chris@16
|
352
|
Chris@16
|
353 public:
|
Chris@16
|
354 /*!
|
Chris@16
|
355 * Default constructor. Creates an empty settings container.
|
Chris@16
|
356 */
|
Chris@16
|
357 basic_settings_section() : m_ptree(NULL)
|
Chris@16
|
358 {
|
Chris@16
|
359 }
|
Chris@16
|
360
|
Chris@16
|
361 /*!
|
Chris@16
|
362 * Copy constructor.
|
Chris@16
|
363 */
|
Chris@16
|
364 basic_settings_section(basic_settings_section const& that) : m_ptree(that.m_ptree)
|
Chris@16
|
365 {
|
Chris@16
|
366 }
|
Chris@16
|
367
|
Chris@16
|
368 /*!
|
Chris@16
|
369 * Checks if the section refers to the container.
|
Chris@16
|
370 */
|
Chris@101
|
371 BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
Chris@16
|
372
|
Chris@16
|
373 /*!
|
Chris@16
|
374 * Checks if the section refers to the container.
|
Chris@16
|
375 */
|
Chris@101
|
376 bool operator! () const BOOST_NOEXCEPT { return !m_ptree; }
|
Chris@16
|
377
|
Chris@16
|
378 /*!
|
Chris@16
|
379 * Returns an iterator over the nested subsections and parameters.
|
Chris@16
|
380 */
|
Chris@16
|
381 iterator begin()
|
Chris@16
|
382 {
|
Chris@16
|
383 if (m_ptree)
|
Chris@16
|
384 return iterator(m_ptree->begin());
|
Chris@16
|
385 else
|
Chris@16
|
386 return iterator();
|
Chris@16
|
387 }
|
Chris@16
|
388
|
Chris@16
|
389 /*!
|
Chris@16
|
390 * Returns an iterator over the nested subsections and parameters.
|
Chris@16
|
391 */
|
Chris@16
|
392 iterator end()
|
Chris@16
|
393 {
|
Chris@16
|
394 if (m_ptree)
|
Chris@16
|
395 return iterator(m_ptree->end());
|
Chris@16
|
396 else
|
Chris@16
|
397 return iterator();
|
Chris@16
|
398 }
|
Chris@16
|
399
|
Chris@16
|
400 /*!
|
Chris@16
|
401 * Returns an iterator over the nested subsections and parameters.
|
Chris@16
|
402 */
|
Chris@16
|
403 const_iterator begin() const
|
Chris@16
|
404 {
|
Chris@16
|
405 if (m_ptree)
|
Chris@16
|
406 return const_iterator(m_ptree->begin());
|
Chris@16
|
407 else
|
Chris@16
|
408 return const_iterator();
|
Chris@16
|
409 }
|
Chris@16
|
410
|
Chris@16
|
411 /*!
|
Chris@16
|
412 * Returns an iterator over the nested subsections and parameters.
|
Chris@16
|
413 */
|
Chris@16
|
414 const_iterator end() const
|
Chris@16
|
415 {
|
Chris@16
|
416 if (m_ptree)
|
Chris@16
|
417 return const_iterator(m_ptree->end());
|
Chris@16
|
418 else
|
Chris@16
|
419 return const_iterator();
|
Chris@16
|
420 }
|
Chris@16
|
421
|
Chris@16
|
422 /*!
|
Chris@16
|
423 * Returns a reverse iterator over the nested subsections and parameters.
|
Chris@16
|
424 */
|
Chris@16
|
425 reverse_iterator rbegin() { return reverse_iterator(begin()); }
|
Chris@16
|
426
|
Chris@16
|
427 /*!
|
Chris@16
|
428 * Returns a reverse iterator over the nested subsections and parameters.
|
Chris@16
|
429 */
|
Chris@16
|
430 reverse_iterator rend() { return reverse_iterator(end()); }
|
Chris@16
|
431
|
Chris@16
|
432 /*!
|
Chris@16
|
433 * Returns a reverse iterator over the nested subsections and parameters.
|
Chris@16
|
434 */
|
Chris@16
|
435 const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
|
Chris@16
|
436
|
Chris@16
|
437 /*!
|
Chris@16
|
438 * Returns a reverse iterator over the nested subsections and parameters.
|
Chris@16
|
439 */
|
Chris@16
|
440 const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
|
Chris@16
|
441
|
Chris@16
|
442 /*!
|
Chris@16
|
443 * Checks if the container is empty (i.e. contains no sections and parameters).
|
Chris@16
|
444 */
|
Chris@16
|
445 bool empty() const { return m_ptree == NULL || m_ptree->empty(); }
|
Chris@16
|
446
|
Chris@16
|
447 /*!
|
Chris@16
|
448 * Accessor to a single parameter. This operator should be used in conjunction
|
Chris@16
|
449 * with the subsequent subscript operator that designates the parameter name.
|
Chris@16
|
450 *
|
Chris@16
|
451 * \param section_name The name of the section in which the parameter resides
|
Chris@16
|
452 * \return An unspecified reference type that can be used for parameter name specifying
|
Chris@16
|
453 */
|
Chris@16
|
454 reference operator[] (std::string const& section_name) { return reference(*this, section_name); }
|
Chris@16
|
455 /*!
|
Chris@16
|
456 * Accessor to a single parameter. This operator should be used in conjunction
|
Chris@16
|
457 * with the subsequent subscript operator that designates the parameter name.
|
Chris@16
|
458 *
|
Chris@16
|
459 * \param section_name The name of the section in which the parameter resides
|
Chris@16
|
460 * \return An unspecified reference type that can be used for parameter name specifying
|
Chris@16
|
461 */
|
Chris@16
|
462 const_reference operator[] (std::string const& section_name) const { return const_reference(*this, section_name); }
|
Chris@16
|
463
|
Chris@16
|
464 /*!
|
Chris@16
|
465 * Accessor to a single parameter. This operator should be used in conjunction
|
Chris@16
|
466 * with the subsequent subscript operator that designates the parameter name.
|
Chris@16
|
467 *
|
Chris@16
|
468 * \param section_name The name of the section in which the parameter resides
|
Chris@16
|
469 * \return An unspecified reference type that can be used for parameter name specifying
|
Chris@16
|
470 */
|
Chris@16
|
471 reference operator[] (const char* section_name) { return reference(*this, section_name); }
|
Chris@16
|
472 /*!
|
Chris@16
|
473 * Accessor to a single parameter. This operator should be used in conjunction
|
Chris@16
|
474 * with the subsequent subscript operator that designates the parameter name.
|
Chris@16
|
475 *
|
Chris@16
|
476 * \param section_name The name of the section in which the parameter resides
|
Chris@16
|
477 * \return An unspecified reference type that can be used for parameter name specifying
|
Chris@16
|
478 */
|
Chris@16
|
479 const_reference operator[] (const char* section_name) const { return const_reference(*this, section_name); }
|
Chris@16
|
480
|
Chris@16
|
481 /*!
|
Chris@16
|
482 * Accessor for the embedded property tree
|
Chris@16
|
483 */
|
Chris@16
|
484 property_tree_type const& property_tree() const { return *m_ptree; }
|
Chris@16
|
485 /*!
|
Chris@16
|
486 * Accessor for the embedded property tree
|
Chris@16
|
487 */
|
Chris@16
|
488 property_tree_type& property_tree() { return *m_ptree; }
|
Chris@16
|
489
|
Chris@16
|
490 /*!
|
Chris@16
|
491 * Checks if the specified section is present in the container.
|
Chris@16
|
492 *
|
Chris@16
|
493 * \param section_name The name of the section
|
Chris@16
|
494 */
|
Chris@16
|
495 bool has_section(string_type const& section_name) const
|
Chris@16
|
496 {
|
Chris@16
|
497 return m_ptree != NULL && !!m_ptree->get_child_optional(section_name);
|
Chris@16
|
498 }
|
Chris@16
|
499 /*!
|
Chris@16
|
500 * Checks if the specified parameter is present in the container.
|
Chris@16
|
501 *
|
Chris@16
|
502 * \param section_name The name of the section in which the parameter resides
|
Chris@16
|
503 * \param param_name The name of the parameter
|
Chris@16
|
504 */
|
Chris@16
|
505 bool has_parameter(string_type const& section_name, string_type const& param_name) const
|
Chris@16
|
506 {
|
Chris@16
|
507 if (m_ptree)
|
Chris@16
|
508 {
|
Chris@16
|
509 optional< property_tree_type& > section = m_ptree->get_child_optional(section_name);
|
Chris@16
|
510 if (!!section)
|
Chris@16
|
511 return (section->find(param_name) != section->not_found());
|
Chris@16
|
512 }
|
Chris@16
|
513
|
Chris@16
|
514 return false;
|
Chris@16
|
515 }
|
Chris@16
|
516
|
Chris@16
|
517 /*!
|
Chris@16
|
518 * Swaps two references to settings sections.
|
Chris@16
|
519 */
|
Chris@16
|
520 void swap(basic_settings_section& that)
|
Chris@16
|
521 {
|
Chris@16
|
522 property_tree_type* const p = m_ptree;
|
Chris@16
|
523 m_ptree = that.m_ptree;
|
Chris@16
|
524 that.m_ptree = p;
|
Chris@16
|
525 }
|
Chris@16
|
526
|
Chris@16
|
527 protected:
|
Chris@16
|
528 explicit basic_settings_section(property_tree_type* tree) : m_ptree(tree)
|
Chris@16
|
529 {
|
Chris@16
|
530 }
|
Chris@16
|
531 };
|
Chris@16
|
532
|
Chris@16
|
533 template< typename CharT >
|
Chris@16
|
534 inline void swap(basic_settings_section< CharT >& left, basic_settings_section< CharT >& right)
|
Chris@16
|
535 {
|
Chris@16
|
536 left.swap(right);
|
Chris@16
|
537 }
|
Chris@16
|
538
|
Chris@16
|
539
|
Chris@16
|
540 /*!
|
Chris@16
|
541 * \brief The class represents settings container
|
Chris@16
|
542 *
|
Chris@16
|
543 * All settings are presented as a number of named parameters divided into named sections.
|
Chris@16
|
544 * The parameters values are stored as strings. Individual parameters may be queried via subscript operators, like this:
|
Chris@16
|
545 *
|
Chris@16
|
546 * <code><pre>
|
Chris@16
|
547 * optional< string > param = settings["Section1"]["Param1"]; // reads parameter "Param1" in section "Section1"
|
Chris@16
|
548 * // returns an empty value if no such parameter exists
|
Chris@16
|
549 * settings["Section2"]["Param2"] = 10; // sets the parameter "Param2" in section "Section2"
|
Chris@16
|
550 * // to value "10"
|
Chris@16
|
551 * </pre></code>
|
Chris@16
|
552 *
|
Chris@16
|
553 * There are also other methods to work with parameters.
|
Chris@16
|
554 */
|
Chris@16
|
555 template< typename CharT >
|
Chris@16
|
556 class basic_settings :
|
Chris@16
|
557 public basic_settings_section< CharT >
|
Chris@16
|
558 {
|
Chris@16
|
559 typedef basic_settings this_type;
|
Chris@16
|
560 BOOST_COPYABLE_AND_MOVABLE(this_type)
|
Chris@16
|
561
|
Chris@16
|
562 public:
|
Chris@16
|
563 //! Section type
|
Chris@16
|
564 typedef basic_settings_section< CharT > section;
|
Chris@16
|
565 //! Property tree type
|
Chris@16
|
566 typedef typename section::property_tree_type property_tree_type;
|
Chris@16
|
567
|
Chris@16
|
568 public:
|
Chris@16
|
569 /*!
|
Chris@16
|
570 * Default constructor. Creates an empty settings container.
|
Chris@16
|
571 */
|
Chris@16
|
572 basic_settings() : section(new property_tree_type())
|
Chris@16
|
573 {
|
Chris@16
|
574 }
|
Chris@16
|
575
|
Chris@16
|
576 /*!
|
Chris@16
|
577 * Copy constructor.
|
Chris@16
|
578 */
|
Chris@16
|
579 basic_settings(basic_settings const& that) :
|
Chris@16
|
580 section(that.m_ptree ? new property_tree_type(*that.m_ptree) : static_cast< property_tree_type* >(NULL))
|
Chris@16
|
581 {
|
Chris@16
|
582 }
|
Chris@16
|
583
|
Chris@16
|
584 /*!
|
Chris@16
|
585 * Move constructor.
|
Chris@16
|
586 */
|
Chris@16
|
587 basic_settings(BOOST_RV_REF(this_type) that)
|
Chris@16
|
588 {
|
Chris@16
|
589 this->swap(that);
|
Chris@16
|
590 }
|
Chris@16
|
591 /*!
|
Chris@16
|
592 * Initializing constructor. Creates a settings container with the copy of the specified property tree.
|
Chris@16
|
593 */
|
Chris@16
|
594 explicit basic_settings(property_tree_type const& tree) : section(new property_tree_type(tree))
|
Chris@16
|
595 {
|
Chris@16
|
596 }
|
Chris@16
|
597
|
Chris@16
|
598 /*!
|
Chris@16
|
599 * Destructor
|
Chris@16
|
600 */
|
Chris@16
|
601 ~basic_settings()
|
Chris@16
|
602 {
|
Chris@16
|
603 delete this->m_ptree;
|
Chris@16
|
604 }
|
Chris@16
|
605
|
Chris@16
|
606 /*!
|
Chris@16
|
607 * Copy assignment operator.
|
Chris@16
|
608 */
|
Chris@16
|
609 basic_settings& operator= (BOOST_COPY_ASSIGN_REF(basic_settings) that)
|
Chris@16
|
610 {
|
Chris@16
|
611 if (this != &that)
|
Chris@16
|
612 {
|
Chris@16
|
613 basic_settings tmp = that;
|
Chris@16
|
614 this->swap(tmp);
|
Chris@16
|
615 }
|
Chris@16
|
616 return *this;
|
Chris@16
|
617 }
|
Chris@16
|
618 /*!
|
Chris@16
|
619 * Move assignment operator.
|
Chris@16
|
620 */
|
Chris@16
|
621 basic_settings& operator= (BOOST_RV_REF(basic_settings) that)
|
Chris@16
|
622 {
|
Chris@16
|
623 this->swap(that);
|
Chris@16
|
624 return *this;
|
Chris@16
|
625 }
|
Chris@16
|
626 };
|
Chris@16
|
627
|
Chris@16
|
628 #ifdef BOOST_LOG_USE_CHAR
|
Chris@16
|
629 typedef basic_settings< char > settings; //!< Convenience typedef for narrow-character logging
|
Chris@16
|
630 typedef basic_settings_section< char > settings_section; //!< Convenience typedef for narrow-character logging
|
Chris@16
|
631 #endif
|
Chris@16
|
632 #ifdef BOOST_LOG_USE_WCHAR_T
|
Chris@16
|
633 typedef basic_settings< wchar_t > wsettings; //!< Convenience typedef for wide-character logging
|
Chris@16
|
634 typedef basic_settings_section< wchar_t > wsettings_section; //!< Convenience typedef for wide-character logging
|
Chris@16
|
635 #endif
|
Chris@16
|
636
|
Chris@16
|
637 BOOST_LOG_CLOSE_NAMESPACE // namespace log
|
Chris@16
|
638
|
Chris@16
|
639 } // namespace boost
|
Chris@16
|
640
|
Chris@16
|
641 #include <boost/log/detail/footer.hpp>
|
Chris@16
|
642
|
Chris@16
|
643 #endif // BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
|