2
* Copyright Andrey Semashev 2007 - 2013.
3
* Distributed under the Boost Software License, Version 1.0.
4
* (See accompanying file LICENSE_1_0.txt or copy at
5
* http://www.boost.org/LICENSE_1_0.txt)
9
* \author Andrey Semashev
12
* The header contains definition of the library settings container.
15
#ifndef BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
16
#define BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
21
#include <boost/assert.hpp>
22
#include <boost/move/core.hpp>
23
#include <boost/mpl/if.hpp>
24
#include <boost/iterator/iterator_adaptor.hpp>
25
#include <boost/optional/optional.hpp>
26
#include <boost/property_tree/ptree.hpp>
27
#include <boost/log/detail/setup_config.hpp>
28
#include <boost/log/detail/native_typeof.hpp>
29
#include <boost/log/utility/explicit_operator_bool.hpp>
30
#if !defined(BOOST_LOG_TYPEOF)
31
#include <boost/utility/enable_if.hpp>
33
#if defined(BOOST_LOG_TYPEOF) && defined(BOOST_LOG_NO_TRAILING_RESULT_TYPE)
34
#include <boost/utility/declval.hpp>
36
#include <boost/log/detail/header.hpp>
38
#ifdef BOOST_LOG_HAS_PRAGMA_ONCE
44
BOOST_LOG_OPEN_NAMESPACE
48
// This workaround is needed for MSVC 10 to work around ICE caused by stack overflow
49
template< typename SectionT, bool IsConstV >
50
struct basic_settings_section_iterator_base;
52
template< typename SectionT >
53
struct basic_settings_section_iterator_base< SectionT, true >
55
typedef typename SectionT::BOOST_NESTED_TEMPLATE iter< true > iterator_type;
56
typedef typename SectionT::property_tree_type::const_iterator base_iterator_type;
57
typedef iterator_adaptor<
66
template< typename SectionT >
67
struct basic_settings_section_iterator_base< SectionT, false >
69
typedef typename SectionT::BOOST_NESTED_TEMPLATE iter< false > iterator_type;
70
typedef typename SectionT::property_tree_type::iterator base_iterator_type;
71
typedef iterator_adaptor<
83
* \brief The class represents a reference to the settings container section
85
* The section refers to a sub-tree of the library settings container. It does not
86
* own the referred sub-tree but allows for convenient access to parameters within the subsection.
88
template< typename CharT >
89
class basic_settings_section
91
template< typename SectionT, bool IsConstV >
92
friend struct aux::basic_settings_section_iterator_base;
96
typedef CharT char_type;
98
typedef std::basic_string< char_type > string_type;
99
//! Property tree type
100
typedef property_tree::basic_ptree< std::string, string_type > property_tree_type;
101
//! Property tree path type
102
typedef typename property_tree_type::path_type path_type;
105
#if !defined(BOOST_LOG_DOXYGEN_PASS)
107
//! A reference proxy object
108
#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
109
template< bool IsConstV >
111
template< bool IsConstV >
114
template< bool IsConstV >
118
typedef typename mpl::if_c<
120
basic_settings_section< char_type > const,
121
basic_settings_section< char_type >
122
>::type section_type;
125
section_type& m_section;
129
ref(section_type& section, std::string const& section_name) :
134
ref(section_type& section, const char* section_name) :
140
ref& operator[] (std::string const& param_name)
142
m_path /= param_name;
146
ref& operator= (string_type const& value)
148
BOOST_ASSERT(m_section.m_ptree != NULL);
149
m_section.m_ptree->put(m_path, value);
154
ref& operator= (ref< V > const& value)
156
BOOST_ASSERT(m_section.m_ptree != NULL);
157
optional< string_type > val = value.get();
160
m_section.m_ptree->put(m_path, val);
162
else if (optional< property_tree_type& > node = m_section.m_ptree->get_child_optional(m_path))
164
node.put_value(string_type());
170
template< typename T >
171
ref& operator= (T const& value)
173
BOOST_ASSERT(m_section.m_ptree != NULL);
174
m_section.m_ptree->put(m_path, value);
178
BOOST_LOG_EXPLICIT_OPERATOR_BOOL()
180
bool operator! () const
182
return !m_section.m_ptree || !m_section.m_ptree->get_child_optional(m_path);
185
std::string get_name() const
187
return m_path.dump();
190
operator optional< string_type > () const
195
optional< string_type > get() const
197
if (m_section.m_ptree)
198
return m_section.m_ptree->template get_optional< string_type >(m_path);
200
return optional< string_type >();
203
template< typename T >
204
optional< T > get() const
206
if (m_section.m_ptree)
207
return m_section.m_ptree->template get_optional< T >(m_path);
209
return optional< T >();
212
operator section_type () const
214
return get_section();
217
section_type get_section() const
219
if (m_section.m_ptree)
220
return section_type(m_section.m_ptree->get_child_optional(m_path).get_ptr());
222
return section_type();
225
#if defined(BOOST_LOG_TYPEOF) && !(defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) && !defined(__PATHSCALE__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 5))
226
#if !defined(BOOST_LOG_NO_TRAILING_RESULT_TYPE)
227
template< typename T >
228
auto or_default(T const& def_value) const -> BOOST_LOG_TYPEOF(property_tree_type().get(typename property_tree_type::path_type(), def_value))
230
if (m_section.m_ptree)
231
return m_section.m_ptree->get(m_path, def_value);
236
// GCC up to 4.5 (inclusively) segfaults on the following code, if C++11 mode is not enabled
237
template< typename T >
238
BOOST_LOG_TYPEOF(property_tree_type().get(typename property_tree_type::path_type(), boost::declval< T >())) or_default(T const& def_value) const
240
if (m_section.m_ptree)
241
return m_section.m_ptree->get(m_path, def_value);
247
template< typename T >
248
T or_default(T const& def_value) const
250
if (m_section.m_ptree)
251
return m_section.m_ptree->get(m_path, def_value);
256
template< typename T >
257
typename enable_if< boost::property_tree::detail::is_character< T >, std::basic_string< T > >::type
258
or_default(const T* def_value) const
260
if (m_section.m_ptree)
261
return m_section.m_ptree->get(m_path, def_value);
266
string_type or_default(string_type const& def_value) const
268
return get().get_value_or(def_value);
270
string_type or_default(typename string_type::value_type const* def_value) const
272
if (optional< string_type > val = get())
279
//! An iterator over subsections and parameters
280
#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
281
template< bool IsConstV >
283
template< bool IsConstV >
286
template< bool IsConstV >
288
public aux::basic_settings_section_iterator_base< basic_settings_section< char_type >, IsConstV >::type
290
friend class boost::iterator_core_access;
292
typedef typename iter::iterator_adaptor_ iterator_adaptor_;
293
// NOTE: This typedef must not come from iterator_adaptor_::base_type in order to work around MSVC 10 ICE
294
typedef typename aux::basic_settings_section_iterator_base< basic_settings_section< char_type >, IsConstV >::base_iterator_type base_iterator_type;
297
typedef typename iterator_adaptor_::reference reference;
300
BOOST_LOG_DEFAULTED_FUNCTION(iter(), {})
301
template< bool OtherIsConstV >
302
iter(iter< OtherIsConstV > const& that) : iterator_adaptor_(that.base()) {}
303
explicit iter(base_iterator_type const& it) : iterator_adaptor_(it) {}
305
//! Returns the section name
306
std::string const& get_name() const
308
return this->base()->first;
312
reference dereference() const
314
return reference(const_cast< property_tree_type* >(&this->base()->second));
319
typedef ref< true > const_reference;
320
typedef ref< false > reference;
321
typedef iter< true > const_iterator;
322
typedef iter< false > iterator;
323
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
324
typedef std::reverse_iterator< iterator > reverse_iterator;
330
* Constant reference to the parameter value
332
typedef implementation_defined const_reference;
334
* Mutable reference to the parameter value
336
typedef implementation_defined reference;
339
* Constant iterator over nested parameters and subsections
341
typedef implementation_defined const_iterator;
343
* Mutable iterator over nested parameters and subsections
345
typedef implementation_defined iterator;
347
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
351
property_tree_type* m_ptree;
355
* Default constructor. Creates an empty settings container.
357
basic_settings_section() : m_ptree(NULL)
364
basic_settings_section(basic_settings_section const& that) : m_ptree(that.m_ptree)
369
* Checks if the section refers to the container.
371
BOOST_LOG_EXPLICIT_OPERATOR_BOOL()
374
* Checks if the section refers to the container.
376
bool operator! () const { return !m_ptree; }
379
* Returns an iterator over the nested subsections and parameters.
384
return iterator(m_ptree->begin());
390
* Returns an iterator over the nested subsections and parameters.
395
return iterator(m_ptree->end());
401
* Returns an iterator over the nested subsections and parameters.
403
const_iterator begin() const
406
return const_iterator(m_ptree->begin());
408
return const_iterator();
412
* Returns an iterator over the nested subsections and parameters.
414
const_iterator end() const
417
return const_iterator(m_ptree->end());
419
return const_iterator();
423
* Returns a reverse iterator over the nested subsections and parameters.
425
reverse_iterator rbegin() { return reverse_iterator(begin()); }
428
* Returns a reverse iterator over the nested subsections and parameters.
430
reverse_iterator rend() { return reverse_iterator(end()); }
433
* Returns a reverse iterator over the nested subsections and parameters.
435
const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
438
* Returns a reverse iterator over the nested subsections and parameters.
440
const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
443
* Checks if the container is empty (i.e. contains no sections and parameters).
445
bool empty() const { return m_ptree == NULL || m_ptree->empty(); }
448
* Accessor to a single parameter. This operator should be used in conjunction
449
* with the subsequent subscript operator that designates the parameter name.
451
* \param section_name The name of the section in which the parameter resides
452
* \return An unspecified reference type that can be used for parameter name specifying
454
reference operator[] (std::string const& section_name) { return reference(*this, section_name); }
456
* Accessor to a single parameter. This operator should be used in conjunction
457
* with the subsequent subscript operator that designates the parameter name.
459
* \param section_name The name of the section in which the parameter resides
460
* \return An unspecified reference type that can be used for parameter name specifying
462
const_reference operator[] (std::string const& section_name) const { return const_reference(*this, section_name); }
465
* Accessor to a single parameter. This operator should be used in conjunction
466
* with the subsequent subscript operator that designates the parameter name.
468
* \param section_name The name of the section in which the parameter resides
469
* \return An unspecified reference type that can be used for parameter name specifying
471
reference operator[] (const char* section_name) { return reference(*this, section_name); }
473
* Accessor to a single parameter. This operator should be used in conjunction
474
* with the subsequent subscript operator that designates the parameter name.
476
* \param section_name The name of the section in which the parameter resides
477
* \return An unspecified reference type that can be used for parameter name specifying
479
const_reference operator[] (const char* section_name) const { return const_reference(*this, section_name); }
482
* Accessor for the embedded property tree
484
property_tree_type const& property_tree() const { return *m_ptree; }
486
* Accessor for the embedded property tree
488
property_tree_type& property_tree() { return *m_ptree; }
491
* Checks if the specified section is present in the container.
493
* \param section_name The name of the section
495
bool has_section(string_type const& section_name) const
497
return m_ptree != NULL && !!m_ptree->get_child_optional(section_name);
500
* Checks if the specified parameter is present in the container.
502
* \param section_name The name of the section in which the parameter resides
503
* \param param_name The name of the parameter
505
bool has_parameter(string_type const& section_name, string_type const& param_name) const
509
optional< property_tree_type const& > section = m_ptree->get_child_optional(section_name);
511
return (section->find(param_name) != section->not_found());
518
* Swaps two references to settings sections.
520
void swap(basic_settings_section& that)
522
property_tree_type* const p = m_ptree;
523
m_ptree = that.m_ptree;
528
explicit basic_settings_section(property_tree_type* tree) : m_ptree(tree)
533
template< typename CharT >
534
inline void swap(basic_settings_section< CharT >& left, basic_settings_section< CharT >& right)
541
* \brief The class represents settings container
543
* All settings are presented as a number of named parameters divided into named sections.
544
* The parameters values are stored as strings. Individual parameters may be queried via subscript operators, like this:
547
* optional< string > param = settings["Section1"]["Param1"]; // reads parameter "Param1" in section "Section1"
548
* // returns an empty value if no such parameter exists
549
* settings["Section2"]["Param2"] = 10; // sets the parameter "Param2" in section "Section2"
553
* There are also other methods to work with parameters.
555
template< typename CharT >
556
class basic_settings :
557
public basic_settings_section< CharT >
559
typedef basic_settings this_type;
560
BOOST_COPYABLE_AND_MOVABLE(this_type)
564
typedef basic_settings_section< CharT > section;
565
//! Property tree type
566
typedef typename section::property_tree_type property_tree_type;
570
* Default constructor. Creates an empty settings container.
572
basic_settings() : section(new property_tree_type())
579
basic_settings(basic_settings const& that) :
580
section(that.m_ptree ? new property_tree_type(*that.m_ptree) : static_cast< property_tree_type* >(NULL))
587
basic_settings(BOOST_RV_REF(this_type) that)
592
* Initializing constructor. Creates a settings container with the copy of the specified property tree.
594
explicit basic_settings(property_tree_type const& tree) : section(new property_tree_type(tree))
603
delete this->m_ptree;
607
* Copy assignment operator.
609
basic_settings& operator= (BOOST_COPY_ASSIGN_REF(basic_settings) that)
613
basic_settings tmp = that;
619
* Move assignment operator.
621
basic_settings& operator= (BOOST_RV_REF(basic_settings) that)
628
#ifdef BOOST_LOG_USE_CHAR
629
typedef basic_settings< char > settings; //!< Convenience typedef for narrow-character logging
630
typedef basic_settings_section< char > settings_section; //!< Convenience typedef for narrow-character logging
632
#ifdef BOOST_LOG_USE_WCHAR_T
633
typedef basic_settings< wchar_t > wsettings; //!< Convenience typedef for wide-character logging
634
typedef basic_settings_section< wchar_t > wsettings_section; //!< Convenience typedef for wide-character logging
637
BOOST_LOG_CLOSE_NAMESPACE // namespace log
641
#include <boost/log/detail/footer.hpp>
643
#endif // BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_