Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:39:28

0001 /*
0002  *          Copyright Andrey Semashev 2007 - 2015.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  *    (See accompanying file LICENSE_1_0.txt or copy at
0005  *          http://www.boost.org/LICENSE_1_0.txt)
0006  */
0007 /*!
0008  * \file   settings.hpp
0009  * \author Andrey Semashev
0010  * \date   11.10.2009
0011  *
0012  * The header contains definition of the library settings container.
0013  */
0014 
0015 #ifndef BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
0016 #define BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
0017 
0018 #include <cstddef>
0019 #include <string>
0020 #include <iterator>
0021 #include <boost/assert.hpp>
0022 #include <boost/move/core.hpp>
0023 #include <boost/type_traits/conditional.hpp>
0024 #include <boost/iterator/iterator_adaptor.hpp>
0025 #include <boost/optional/optional.hpp>
0026 #include <boost/property_tree/ptree.hpp>
0027 #include <boost/core/explicit_operator_bool.hpp>
0028 #include <boost/log/detail/setup_config.hpp>
0029 #include <boost/log/detail/native_typeof.hpp>
0030 #if !defined(BOOST_LOG_TYPEOF)
0031 #include <boost/core/enable_if.hpp>
0032 #endif
0033 #if defined(BOOST_LOG_TYPEOF) && defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
0034 #include <boost/type_traits/declval.hpp>
0035 #endif
0036 #include <boost/log/detail/header.hpp>
0037 
0038 #ifdef BOOST_HAS_PRAGMA_ONCE
0039 #pragma once
0040 #endif
0041 
0042 namespace boost {
0043 
0044 BOOST_LOG_OPEN_NAMESPACE
0045 
0046 namespace aux {
0047 
0048 // This workaround is needed for MSVC 10 to work around ICE caused by stack overflow
0049 template< typename SectionT, bool IsConstV >
0050 struct basic_settings_section_iterator_base;
0051 
0052 template< typename SectionT >
0053 struct basic_settings_section_iterator_base< SectionT, true >
0054 {
0055     typedef typename SectionT::BOOST_NESTED_TEMPLATE iter< true > iterator_type;
0056     typedef typename SectionT::property_tree_type::const_iterator base_iterator_type;
0057     typedef iterator_adaptor<
0058         iterator_type,
0059         base_iterator_type,
0060         SectionT,
0061         use_default,
0062         const SectionT
0063     > type;
0064 };
0065 
0066 template< typename SectionT >
0067 struct basic_settings_section_iterator_base< SectionT, false >
0068 {
0069     typedef typename SectionT::BOOST_NESTED_TEMPLATE iter< false > iterator_type;
0070     typedef typename SectionT::property_tree_type::iterator base_iterator_type;
0071     typedef iterator_adaptor<
0072         iterator_type,
0073         base_iterator_type,
0074         SectionT,
0075         use_default,
0076         SectionT
0077     > type;
0078 };
0079 
0080 } // namespace aux
0081 
0082 /*!
0083  * \brief The class represents a reference to the settings container section
0084  *
0085  * The section refers to a sub-tree of the library settings container. It does not
0086  * own the referred sub-tree but allows for convenient access to parameters within the subsection.
0087  */
0088 template< typename CharT >
0089 class basic_settings_section
0090 {
0091     template< typename SectionT, bool IsConstV >
0092     friend struct aux::basic_settings_section_iterator_base;
0093 
0094 public:
0095     //! Character type
0096     typedef CharT char_type;
0097     //! String type
0098     typedef std::basic_string< char_type > string_type;
0099     //! Property tree type
0100     typedef property_tree::basic_ptree< std::string, string_type > property_tree_type;
0101     //! Property tree path type
0102     typedef typename property_tree_type::path_type path_type;
0103 
0104 private:
0105 #if !defined(BOOST_LOG_DOXYGEN_PASS)
0106 
0107     //! A reference proxy object
0108 #ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
0109     template< bool IsConstV >
0110     class ref;
0111     template< bool IsConstV >
0112     friend class ref;
0113 #endif
0114     template< bool IsConstV >
0115     class ref
0116     {
0117     private:
0118         typedef typename boost::conditional<
0119             IsConstV,
0120             basic_settings_section< char_type > const,
0121             basic_settings_section< char_type >
0122         >::type section_type;
0123 
0124     private:
0125         section_type& m_section;
0126         path_type m_path;
0127 
0128     public:
0129         ref(section_type& section, std::string const& section_name) :
0130             m_section(section),
0131             m_path(section_name)
0132         {
0133         }
0134         ref(section_type& section, const char* section_name) :
0135             m_section(section),
0136             m_path(section_name)
0137         {
0138         }
0139 
0140         ref& operator[] (std::string const& param_name)
0141         {
0142             m_path /= param_name;
0143             return *this;
0144         }
0145 
0146         ref& operator= (string_type const& value)
0147         {
0148             BOOST_ASSERT(m_section.m_ptree != NULL);
0149             m_section.m_ptree->put(m_path, value);
0150             return *this;
0151         }
0152 
0153         template< bool V >
0154         ref& operator= (ref< V > const& value)
0155         {
0156             BOOST_ASSERT(m_section.m_ptree != NULL);
0157             optional< string_type > val = value.get();
0158             if (!!val)
0159             {
0160                 m_section.m_ptree->put(m_path, val);
0161             }
0162             else if (optional< property_tree_type& > node = m_section.m_ptree->get_child_optional(m_path))
0163             {
0164                 node.put_value(string_type());
0165             }
0166 
0167             return *this;
0168         }
0169 
0170         template< typename T >
0171         ref& operator= (T const& value)
0172         {
0173             BOOST_ASSERT(m_section.m_ptree != NULL);
0174             m_section.m_ptree->put(m_path, value);
0175             return *this;
0176         }
0177 
0178         BOOST_EXPLICIT_OPERATOR_BOOL()
0179 
0180         bool operator! () const
0181         {
0182             return !m_section.m_ptree || !m_section.m_ptree->get_child_optional(m_path);
0183         }
0184 
0185         std::string get_name() const
0186         {
0187             return m_path.dump();
0188         }
0189 
0190         operator optional< string_type > () const
0191         {
0192             return get();
0193         }
0194 
0195         optional< string_type > get() const
0196         {
0197             if (m_section.m_ptree)
0198                 return m_section.m_ptree->template get_optional< string_type >(m_path);
0199             else
0200                 return optional< string_type >();
0201         }
0202 
0203         template< typename T >
0204         optional< T > get() const
0205         {
0206             if (m_section.m_ptree)
0207                 return m_section.m_ptree->template get_optional< T >(m_path);
0208             else
0209                 return optional< T >();
0210         }
0211 
0212         operator section_type () const
0213         {
0214             return get_section();
0215         }
0216 
0217         section_type get_section() const
0218         {
0219             if (m_section.m_ptree)
0220                 return section_type(m_section.m_ptree->get_child_optional(m_path).get_ptr());
0221             else
0222                 return section_type();
0223         }
0224 
0225 #if defined(BOOST_LOG_TYPEOF) && !(defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__) && !defined(__PATHSCALE__) && !defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 5))
0226 #if !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
0227         template< typename T >
0228         auto or_default(T const& def_value) const -> BOOST_LOG_TYPEOF(property_tree_type().get(typename property_tree_type::path_type(), def_value))
0229         {
0230             if (m_section.m_ptree)
0231                 return m_section.m_ptree->get(m_path, def_value);
0232             else
0233                 return def_value;
0234         }
0235 #else
0236         // GCC up to 4.5 (inclusively) segfaults on the following code, if C++11 mode is not enabled
0237         template< typename T >
0238         BOOST_LOG_TYPEOF(property_tree_type().get(typename property_tree_type::path_type(), boost::declval< T >())) or_default(T const& def_value) const
0239         {
0240             if (m_section.m_ptree)
0241                 return m_section.m_ptree->get(m_path, def_value);
0242             else
0243                 return def_value;
0244         }
0245 #endif
0246 #else
0247         template< typename T >
0248         T or_default(T const& def_value) const
0249         {
0250             if (m_section.m_ptree)
0251                 return m_section.m_ptree->get(m_path, def_value);
0252             else
0253                 return def_value;
0254         }
0255 
0256         template< typename T >
0257         typename boost::enable_if_c< boost::property_tree::detail::is_character< T >::value, std::basic_string< T > >::type
0258         or_default(const T* def_value) const
0259         {
0260             if (m_section.m_ptree)
0261                 return m_section.m_ptree->get(m_path, def_value);
0262             else
0263                 return def_value;
0264         }
0265 #endif
0266         string_type or_default(string_type const& def_value) const
0267         {
0268             return get().get_value_or(def_value);
0269         }
0270         string_type or_default(typename string_type::value_type const* def_value) const
0271         {
0272             if (optional< string_type > val = get())
0273                 return val.get();
0274             else
0275                 return def_value;
0276         }
0277     };
0278 
0279     //! An iterator over subsections and parameters
0280 #ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
0281     template< bool IsConstV >
0282     class iter;
0283     template< bool IsConstV >
0284     friend class iter;
0285 #endif
0286     template< bool IsConstV >
0287     class iter :
0288         public aux::basic_settings_section_iterator_base< basic_settings_section< char_type >, IsConstV >::type
0289     {
0290         friend class boost::iterator_core_access;
0291 
0292         typedef typename iter::iterator_adaptor_ iterator_adaptor_;
0293         // NOTE: This typedef must not come from iterator_adaptor_::base_type in order to work around MSVC 10 ICE
0294         typedef typename aux::basic_settings_section_iterator_base< basic_settings_section< char_type >, IsConstV >::base_iterator_type base_iterator_type;
0295 
0296     public:
0297         typedef typename iterator_adaptor_::reference reference;
0298 
0299     public:
0300         BOOST_DEFAULTED_FUNCTION(iter(), {})
0301         template< bool OtherIsConstV >
0302         iter(iter< OtherIsConstV > const& that) : iterator_adaptor_(that.base()) {}
0303         explicit iter(base_iterator_type const& it) : iterator_adaptor_(it) {}
0304 
0305         //! Returns the section name
0306         std::string const& get_name() const
0307         {
0308             return this->base()->first;
0309         }
0310 
0311     private:
0312         reference dereference() const
0313         {
0314             return reference(const_cast< property_tree_type* >(&this->base()->second));
0315         }
0316     };
0317 
0318 public:
0319     typedef ref< true > const_reference;
0320     typedef ref< false > reference;
0321     typedef iter< true > const_iterator;
0322     typedef iter< false > iterator;
0323     typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
0324     typedef std::reverse_iterator< iterator > reverse_iterator;
0325 
0326 #else
0327 
0328 public:
0329     /*!
0330      * Constant reference to the parameter value
0331      */
0332     typedef implementation_defined const_reference;
0333     /*!
0334      * Mutable reference to the parameter value
0335      */
0336     typedef implementation_defined reference;
0337 
0338     /*!
0339      * Constant iterator over nested parameters and subsections
0340      */
0341     typedef implementation_defined const_iterator;
0342     /*!
0343      * Mutable iterator over nested parameters and subsections
0344      */
0345     typedef implementation_defined iterator;
0346 
0347 #endif // !defined(BOOST_LOG_DOXYGEN_PASS)
0348 
0349 protected:
0350     //! Parameters
0351     property_tree_type* m_ptree;
0352 
0353 public:
0354     /*!
0355      * Default constructor. Creates an empty settings container.
0356      */
0357     basic_settings_section() BOOST_NOEXCEPT : m_ptree(NULL)
0358     {
0359     }
0360 
0361     /*!
0362      * Copy constructor.
0363      */
0364     basic_settings_section(basic_settings_section const& that) BOOST_NOEXCEPT : m_ptree(that.m_ptree)
0365     {
0366     }
0367 
0368     /*!
0369      * Checks if the section refers to the container.
0370      */
0371     BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
0372 
0373     /*!
0374      * Checks if the section refers to the container.
0375      */
0376     bool operator! () const BOOST_NOEXCEPT { return !m_ptree; }
0377 
0378     /*!
0379      * Returns an iterator over the nested subsections and parameters.
0380      */
0381     iterator begin()
0382     {
0383         if (m_ptree)
0384             return iterator(m_ptree->begin());
0385         else
0386             return iterator();
0387     }
0388 
0389     /*!
0390      * Returns an iterator over the nested subsections and parameters.
0391      */
0392     iterator end()
0393     {
0394         if (m_ptree)
0395             return iterator(m_ptree->end());
0396         else
0397             return iterator();
0398     }
0399 
0400     /*!
0401      * Returns an iterator over the nested subsections and parameters.
0402      */
0403     const_iterator begin() const
0404     {
0405         if (m_ptree)
0406             return const_iterator(m_ptree->begin());
0407         else
0408             return const_iterator();
0409     }
0410 
0411     /*!
0412      * Returns an iterator over the nested subsections and parameters.
0413      */
0414     const_iterator end() const
0415     {
0416         if (m_ptree)
0417             return const_iterator(m_ptree->end());
0418         else
0419             return const_iterator();
0420     }
0421 
0422     /*!
0423      * Returns a reverse iterator over the nested subsections and parameters.
0424      */
0425     reverse_iterator rbegin() { return reverse_iterator(begin()); }
0426 
0427     /*!
0428      * Returns a reverse iterator over the nested subsections and parameters.
0429      */
0430     reverse_iterator rend() { return reverse_iterator(end()); }
0431 
0432     /*!
0433      * Returns a reverse iterator over the nested subsections and parameters.
0434      */
0435     const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
0436 
0437     /*!
0438      * Returns a reverse iterator over the nested subsections and parameters.
0439      */
0440     const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
0441 
0442     /*!
0443      * Checks if the container is empty (i.e. contains no sections and parameters).
0444      */
0445     bool empty() const { return m_ptree == NULL || m_ptree->empty(); }
0446 
0447     /*!
0448      * Accessor to a single parameter. This operator should be used in conjunction
0449      * with the subsequent subscript operator that designates the parameter name.
0450      *
0451      * \param section_name The name of the section in which the parameter resides
0452      * \return An unspecified reference type that can be used for parameter name specifying
0453      */
0454     reference operator[] (std::string const& section_name) { return reference(*this, section_name); }
0455     /*!
0456      * Accessor to a single parameter. This operator should be used in conjunction
0457      * with the subsequent subscript operator that designates the parameter name.
0458      *
0459      * \param section_name The name of the section in which the parameter resides
0460      * \return An unspecified reference type that can be used for parameter name specifying
0461      */
0462     const_reference operator[] (std::string const& section_name) const { return const_reference(*this, section_name); }
0463 
0464     /*!
0465      * Accessor to a single parameter. This operator should be used in conjunction
0466      * with the subsequent subscript operator that designates the parameter name.
0467      *
0468      * \param section_name The name of the section in which the parameter resides
0469      * \return An unspecified reference type that can be used for parameter name specifying
0470      */
0471     reference operator[] (const char* section_name) { return reference(*this, section_name); }
0472     /*!
0473      * Accessor to a single parameter. This operator should be used in conjunction
0474      * with the subsequent subscript operator that designates the parameter name.
0475      *
0476      * \param section_name The name of the section in which the parameter resides
0477      * \return An unspecified reference type that can be used for parameter name specifying
0478      */
0479     const_reference operator[] (const char* section_name) const { return const_reference(*this, section_name); }
0480 
0481     /*!
0482      * Accessor for the embedded property tree
0483      */
0484     property_tree_type const& property_tree() const { return *m_ptree; }
0485     /*!
0486      * Accessor for the embedded property tree
0487      */
0488     property_tree_type& property_tree() { return *m_ptree; }
0489 
0490     /*!
0491      * Checks if the specified section is present in the container.
0492      *
0493      * \param section_name The name of the section
0494      */
0495     bool has_section(string_type const& section_name) const
0496     {
0497         return m_ptree != NULL && !!m_ptree->get_child_optional(section_name);
0498     }
0499     /*!
0500      * Checks if the specified parameter is present in the container.
0501      *
0502      * \param section_name The name of the section in which the parameter resides
0503      * \param param_name The name of the parameter
0504      */
0505     bool has_parameter(string_type const& section_name, string_type const& param_name) const
0506     {
0507         if (m_ptree)
0508         {
0509             optional< property_tree_type& > section = m_ptree->get_child_optional(section_name);
0510             if (!!section)
0511                 return (section->find(param_name) != section->not_found());
0512         }
0513 
0514         return false;
0515     }
0516 
0517     /*!
0518      * Swaps two references to settings sections.
0519      */
0520     void swap(basic_settings_section& that) BOOST_NOEXCEPT
0521     {
0522         property_tree_type* const p = m_ptree;
0523         m_ptree = that.m_ptree;
0524         that.m_ptree = p;
0525     }
0526 
0527 protected:
0528     explicit basic_settings_section(property_tree_type* tree) BOOST_NOEXCEPT : m_ptree(tree)
0529     {
0530     }
0531 };
0532 
0533 template< typename CharT >
0534 inline void swap(basic_settings_section< CharT >& left, basic_settings_section< CharT >& right) BOOST_NOEXCEPT
0535 {
0536     left.swap(right);
0537 }
0538 
0539 
0540 /*!
0541  * \brief The class represents settings container
0542  *
0543  * All settings are presented as a number of named parameters divided into named sections.
0544  * The parameters values are stored as strings. Individual parameters may be queried via subscript operators, like this:
0545  *
0546  * <code><pre>
0547  * optional< string > param = settings["Section1"]["Param1"]; // reads parameter "Param1" in section "Section1"
0548  *                                                            // returns an empty value if no such parameter exists
0549  * settings["Section2"]["Param2"] = 10; // sets the parameter "Param2" in section "Section2"
0550  *                                      // to value "10"
0551  * </pre></code>
0552  *
0553  * There are also other methods to work with parameters.
0554  */
0555 template< typename CharT >
0556 class basic_settings :
0557     public basic_settings_section< CharT >
0558 {
0559     typedef basic_settings this_type;
0560     BOOST_COPYABLE_AND_MOVABLE(this_type)
0561 
0562 public:
0563     //! Section type
0564     typedef basic_settings_section< CharT > section;
0565     //! Property tree type
0566     typedef typename section::property_tree_type property_tree_type;
0567 
0568 public:
0569     /*!
0570      * Default constructor. Creates an empty settings container.
0571      */
0572     basic_settings() : section(new property_tree_type())
0573     {
0574     }
0575 
0576     /*!
0577      * Copy constructor.
0578      */
0579     basic_settings(basic_settings const& that) :
0580         section(that.m_ptree ? new property_tree_type(*that.m_ptree) : static_cast< property_tree_type* >(NULL))
0581     {
0582     }
0583 
0584     /*!
0585      * Move constructor.
0586      */
0587     basic_settings(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
0588     {
0589         this->swap(that);
0590     }
0591     /*!
0592      * Initializing constructor. Creates a settings container with the copy of the specified property tree.
0593      */
0594     explicit basic_settings(property_tree_type const& tree) : section(new property_tree_type(tree))
0595     {
0596     }
0597 
0598     /*!
0599      * Destructor
0600      */
0601     ~basic_settings() BOOST_NOEXCEPT
0602     {
0603         delete this->m_ptree;
0604     }
0605 
0606     /*!
0607      * Copy assignment operator.
0608      */
0609     basic_settings& operator= (BOOST_COPY_ASSIGN_REF(basic_settings) that)
0610     {
0611         if (this != &that)
0612         {
0613             basic_settings tmp = that;
0614             this->swap(tmp);
0615         }
0616         return *this;
0617     }
0618     /*!
0619      * Move assignment operator.
0620      */
0621     basic_settings& operator= (BOOST_RV_REF(basic_settings) that) BOOST_NOEXCEPT
0622     {
0623         this->swap(that);
0624         return *this;
0625     }
0626 };
0627 
0628 #ifdef BOOST_LOG_USE_CHAR
0629 typedef basic_settings< char > settings;                        //!< Convenience typedef for narrow-character logging
0630 typedef basic_settings_section< char > settings_section;        //!< Convenience typedef for narrow-character logging
0631 #endif
0632 #ifdef BOOST_LOG_USE_WCHAR_T
0633 typedef basic_settings< wchar_t > wsettings;                    //!< Convenience typedef for wide-character logging
0634 typedef basic_settings_section< wchar_t > wsettings_section;    //!< Convenience typedef for wide-character logging
0635 #endif
0636 
0637 BOOST_LOG_CLOSE_NAMESPACE // namespace log
0638 
0639 } // namespace boost
0640 
0641 #include <boost/log/detail/footer.hpp>
0642 
0643 #endif // BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_