~ai.tron/armagetronad/0.4-winlibs-updated

« back to all changes in this revision

Viewing changes to boost/includes/boost/log/utility/setup/settings.hpp

  • Committer: Nik K.
  • Date: 2013-11-07 16:58:35 UTC
  • Revision ID: nik.karbaum@gmail.com-20131107165835-kq99jz23drfj4dkh
Forgot to add some files; here they are

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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)
 
6
 */
 
7
/*!
 
8
 * \file   settings.hpp
 
9
 * \author Andrey Semashev
 
10
 * \date   11.10.2009
 
11
 *
 
12
 * The header contains definition of the library settings container.
 
13
 */
 
14
 
 
15
#ifndef BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
 
16
#define BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_
 
17
 
 
18
#include <cstddef>
 
19
#include <string>
 
20
#include <iterator>
 
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>
 
32
#endif
 
33
#if defined(BOOST_LOG_TYPEOF) && defined(BOOST_LOG_NO_TRAILING_RESULT_TYPE)
 
34
#include <boost/utility/declval.hpp>
 
35
#endif
 
36
#include <boost/log/detail/header.hpp>
 
37
 
 
38
#ifdef BOOST_LOG_HAS_PRAGMA_ONCE
 
39
#pragma once
 
40
#endif
 
41
 
 
42
namespace boost {
 
43
 
 
44
BOOST_LOG_OPEN_NAMESPACE
 
45
 
 
46
namespace aux {
 
47
 
 
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;
 
51
 
 
52
template< typename SectionT >
 
53
struct basic_settings_section_iterator_base< SectionT, true >
 
54
{
 
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<
 
58
        iterator_type,
 
59
        base_iterator_type,
 
60
        SectionT,
 
61
        use_default,
 
62
        const SectionT
 
63
    > type;
 
64
};
 
65
 
 
66
template< typename SectionT >
 
67
struct basic_settings_section_iterator_base< SectionT, false >
 
68
{
 
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<
 
72
        iterator_type,
 
73
        base_iterator_type,
 
74
        SectionT,
 
75
        use_default,
 
76
        SectionT
 
77
    > type;
 
78
};
 
79
 
 
80
} // namespace aux
 
81
 
 
82
/*!
 
83
 * \brief The class represents a reference to the settings container section
 
84
 *
 
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.
 
87
 */
 
88
template< typename CharT >
 
89
class basic_settings_section
 
90
{
 
91
    template< typename SectionT, bool IsConstV >
 
92
    friend struct aux::basic_settings_section_iterator_base;
 
93
 
 
94
public:
 
95
    //! Character type
 
96
    typedef CharT char_type;
 
97
    //! String 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;
 
103
 
 
104
private:
 
105
#if !defined(BOOST_LOG_DOXYGEN_PASS)
 
106
 
 
107
    //! A reference proxy object
 
108
#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
 
109
    template< bool IsConstV >
 
110
    class ref;
 
111
    template< bool IsConstV >
 
112
    friend class ref;
 
113
#endif
 
114
    template< bool IsConstV >
 
115
    class ref
 
116
    {
 
117
    private:
 
118
        typedef typename mpl::if_c<
 
119
            IsConstV,
 
120
            basic_settings_section< char_type > const,
 
121
            basic_settings_section< char_type >
 
122
        >::type section_type;
 
123
 
 
124
    private:
 
125
        section_type& m_section;
 
126
        path_type m_path;
 
127
 
 
128
    public:
 
129
        ref(section_type& section, std::string const& section_name) :
 
130
            m_section(section),
 
131
            m_path(section_name)
 
132
        {
 
133
        }
 
134
        ref(section_type& section, const char* section_name) :
 
135
            m_section(section),
 
136
            m_path(section_name)
 
137
        {
 
138
        }
 
139
 
 
140
        ref& operator[] (std::string const& param_name)
 
141
        {
 
142
            m_path /= param_name;
 
143
            return *this;
 
144
        }
 
145
 
 
146
        ref& operator= (string_type const& value)
 
147
        {
 
148
            BOOST_ASSERT(m_section.m_ptree != NULL);
 
149
            m_section.m_ptree->put(m_path, value);
 
150
            return *this;
 
151
        }
 
152
 
 
153
        template< bool V >
 
154
        ref& operator= (ref< V > const& value)
 
155
        {
 
156
            BOOST_ASSERT(m_section.m_ptree != NULL);
 
157
            optional< string_type > val = value.get();
 
158
            if (!!val)
 
159
            {
 
160
                m_section.m_ptree->put(m_path, val);
 
161
            }
 
162
            else if (optional< property_tree_type& > node = m_section.m_ptree->get_child_optional(m_path))
 
163
            {
 
164
                node.put_value(string_type());
 
165
            }
 
166
 
 
167
            return *this;
 
168
        }
 
169
 
 
170
        template< typename T >
 
171
        ref& operator= (T const& value)
 
172
        {
 
173
            BOOST_ASSERT(m_section.m_ptree != NULL);
 
174
            m_section.m_ptree->put(m_path, value);
 
175
            return *this;
 
176
        }
 
177
 
 
178
        BOOST_LOG_EXPLICIT_OPERATOR_BOOL()
 
179
 
 
180
        bool operator! () const
 
181
        {
 
182
            return !m_section.m_ptree || !m_section.m_ptree->get_child_optional(m_path);
 
183
        }
 
184
 
 
185
        std::string get_name() const
 
186
        {
 
187
            return m_path.dump();
 
188
        }
 
189
 
 
190
        operator optional< string_type > () const
 
191
        {
 
192
            return get();
 
193
        }
 
194
 
 
195
        optional< string_type > get() const
 
196
        {
 
197
            if (m_section.m_ptree)
 
198
                return m_section.m_ptree->template get_optional< string_type >(m_path);
 
199
            else
 
200
                return optional< string_type >();
 
201
        }
 
202
 
 
203
        template< typename T >
 
204
        optional< T > get() const
 
205
        {
 
206
            if (m_section.m_ptree)
 
207
                return m_section.m_ptree->template get_optional< T >(m_path);
 
208
            else
 
209
                return optional< T >();
 
210
        }
 
211
 
 
212
        operator section_type () const
 
213
        {
 
214
            return get_section();
 
215
        }
 
216
 
 
217
        section_type get_section() const
 
218
        {
 
219
            if (m_section.m_ptree)
 
220
                return section_type(m_section.m_ptree->get_child_optional(m_path).get_ptr());
 
221
            else
 
222
                return section_type();
 
223
        }
 
224
 
 
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))
 
229
        {
 
230
            if (m_section.m_ptree)
 
231
                return m_section.m_ptree->get(m_path, def_value);
 
232
            else
 
233
                return def_value;
 
234
        }
 
235
#else
 
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
 
239
        {
 
240
            if (m_section.m_ptree)
 
241
                return m_section.m_ptree->get(m_path, def_value);
 
242
            else
 
243
                return def_value;
 
244
        }
 
245
#endif
 
246
#else
 
247
        template< typename T >
 
248
        T or_default(T const& def_value) const
 
249
        {
 
250
            if (m_section.m_ptree)
 
251
                return m_section.m_ptree->get(m_path, def_value);
 
252
            else
 
253
                return def_value;
 
254
        }
 
255
 
 
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
 
259
        {
 
260
            if (m_section.m_ptree)
 
261
                return m_section.m_ptree->get(m_path, def_value);
 
262
            else
 
263
                return def_value;
 
264
        }
 
265
#endif
 
266
        string_type or_default(string_type const& def_value) const
 
267
        {
 
268
            return get().get_value_or(def_value);
 
269
        }
 
270
        string_type or_default(typename string_type::value_type const* def_value) const
 
271
        {
 
272
            if (optional< string_type > val = get())
 
273
                return val.get();
 
274
            else
 
275
                return def_value;
 
276
        }
 
277
    };
 
278
 
 
279
    //! An iterator over subsections and parameters
 
280
#ifndef BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS
 
281
    template< bool IsConstV >
 
282
    class iter;
 
283
    template< bool IsConstV >
 
284
    friend class iter;
 
285
#endif
 
286
    template< bool IsConstV >
 
287
    class iter :
 
288
        public aux::basic_settings_section_iterator_base< basic_settings_section< char_type >, IsConstV >::type
 
289
    {
 
290
        friend class boost::iterator_core_access;
 
291
 
 
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;
 
295
 
 
296
    public:
 
297
        typedef typename iterator_adaptor_::reference reference;
 
298
 
 
299
    public:
 
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) {}
 
304
 
 
305
        //! Returns the section name
 
306
        std::string const& get_name() const
 
307
        {
 
308
            return this->base()->first;
 
309
        }
 
310
 
 
311
    private:
 
312
        reference dereference() const
 
313
        {
 
314
            return reference(const_cast< property_tree_type* >(&this->base()->second));
 
315
        }
 
316
    };
 
317
 
 
318
public:
 
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;
 
325
 
 
326
#else
 
327
 
 
328
public:
 
329
    /*!
 
330
     * Constant reference to the parameter value
 
331
     */
 
332
    typedef implementation_defined const_reference;
 
333
    /*!
 
334
     * Mutable reference to the parameter value
 
335
     */
 
336
    typedef implementation_defined reference;
 
337
 
 
338
    /*!
 
339
     * Constant iterator over nested parameters and subsections
 
340
     */
 
341
    typedef implementation_defined const_iterator;
 
342
    /*!
 
343
     * Mutable iterator over nested parameters and subsections
 
344
     */
 
345
    typedef implementation_defined iterator;
 
346
 
 
347
#endif // !defined(BOOST_LOG_DOXYGEN_PASS)
 
348
 
 
349
protected:
 
350
    //! Parameters
 
351
    property_tree_type* m_ptree;
 
352
 
 
353
public:
 
354
    /*!
 
355
     * Default constructor. Creates an empty settings container.
 
356
     */
 
357
    basic_settings_section() : m_ptree(NULL)
 
358
    {
 
359
    }
 
360
 
 
361
    /*!
 
362
     * Copy constructor.
 
363
     */
 
364
    basic_settings_section(basic_settings_section const& that) : m_ptree(that.m_ptree)
 
365
    {
 
366
    }
 
367
 
 
368
    /*!
 
369
     * Checks if the section refers to the container.
 
370
     */
 
371
    BOOST_LOG_EXPLICIT_OPERATOR_BOOL()
 
372
 
 
373
    /*!
 
374
     * Checks if the section refers to the container.
 
375
     */
 
376
    bool operator! () const { return !m_ptree; }
 
377
 
 
378
    /*!
 
379
     * Returns an iterator over the nested subsections and parameters.
 
380
     */
 
381
    iterator begin()
 
382
    {
 
383
        if (m_ptree)
 
384
            return iterator(m_ptree->begin());
 
385
        else
 
386
            return iterator();
 
387
    }
 
388
 
 
389
    /*!
 
390
     * Returns an iterator over the nested subsections and parameters.
 
391
     */
 
392
    iterator end()
 
393
    {
 
394
        if (m_ptree)
 
395
            return iterator(m_ptree->end());
 
396
        else
 
397
            return iterator();
 
398
    }
 
399
 
 
400
    /*!
 
401
     * Returns an iterator over the nested subsections and parameters.
 
402
     */
 
403
    const_iterator begin() const
 
404
    {
 
405
        if (m_ptree)
 
406
            return const_iterator(m_ptree->begin());
 
407
        else
 
408
            return const_iterator();
 
409
    }
 
410
 
 
411
    /*!
 
412
     * Returns an iterator over the nested subsections and parameters.
 
413
     */
 
414
    const_iterator end() const
 
415
    {
 
416
        if (m_ptree)
 
417
            return const_iterator(m_ptree->end());
 
418
        else
 
419
            return const_iterator();
 
420
    }
 
421
 
 
422
    /*!
 
423
     * Returns a reverse iterator over the nested subsections and parameters.
 
424
     */
 
425
    reverse_iterator rbegin() { return reverse_iterator(begin()); }
 
426
 
 
427
    /*!
 
428
     * Returns a reverse iterator over the nested subsections and parameters.
 
429
     */
 
430
    reverse_iterator rend() { return reverse_iterator(end()); }
 
431
 
 
432
    /*!
 
433
     * Returns a reverse iterator over the nested subsections and parameters.
 
434
     */
 
435
    const_reverse_iterator rbegin() const { return const_reverse_iterator(begin()); }
 
436
 
 
437
    /*!
 
438
     * Returns a reverse iterator over the nested subsections and parameters.
 
439
     */
 
440
    const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
 
441
 
 
442
    /*!
 
443
     * Checks if the container is empty (i.e. contains no sections and parameters).
 
444
     */
 
445
    bool empty() const { return m_ptree == NULL || m_ptree->empty(); }
 
446
 
 
447
    /*!
 
448
     * Accessor to a single parameter. This operator should be used in conjunction
 
449
     * with the subsequent subscript operator that designates the parameter name.
 
450
     *
 
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
 
453
     */
 
454
    reference operator[] (std::string const& section_name) { return reference(*this, section_name); }
 
455
    /*!
 
456
     * Accessor to a single parameter. This operator should be used in conjunction
 
457
     * with the subsequent subscript operator that designates the parameter name.
 
458
     *
 
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
 
461
     */
 
462
    const_reference operator[] (std::string const& section_name) const { return const_reference(*this, section_name); }
 
463
 
 
464
    /*!
 
465
     * Accessor to a single parameter. This operator should be used in conjunction
 
466
     * with the subsequent subscript operator that designates the parameter name.
 
467
     *
 
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
 
470
     */
 
471
    reference operator[] (const char* section_name) { return reference(*this, section_name); }
 
472
    /*!
 
473
     * Accessor to a single parameter. This operator should be used in conjunction
 
474
     * with the subsequent subscript operator that designates the parameter name.
 
475
     *
 
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
 
478
     */
 
479
    const_reference operator[] (const char* section_name) const { return const_reference(*this, section_name); }
 
480
 
 
481
    /*!
 
482
     * Accessor for the embedded property tree
 
483
     */
 
484
    property_tree_type const& property_tree() const { return *m_ptree; }
 
485
    /*!
 
486
     * Accessor for the embedded property tree
 
487
     */
 
488
    property_tree_type& property_tree() { return *m_ptree; }
 
489
 
 
490
    /*!
 
491
     * Checks if the specified section is present in the container.
 
492
     *
 
493
     * \param section_name The name of the section
 
494
     */
 
495
    bool has_section(string_type const& section_name) const
 
496
    {
 
497
        return m_ptree != NULL && !!m_ptree->get_child_optional(section_name);
 
498
    }
 
499
    /*!
 
500
     * Checks if the specified parameter is present in the container.
 
501
     *
 
502
     * \param section_name The name of the section in which the parameter resides
 
503
     * \param param_name The name of the parameter
 
504
     */
 
505
    bool has_parameter(string_type const& section_name, string_type const& param_name) const
 
506
    {
 
507
        if (m_ptree)
 
508
        {
 
509
            optional< property_tree_type const& > section = m_ptree->get_child_optional(section_name);
 
510
            if (!!section)
 
511
                return (section->find(param_name) != section->not_found());
 
512
        }
 
513
 
 
514
        return false;
 
515
    }
 
516
 
 
517
    /*!
 
518
     * Swaps two references to settings sections.
 
519
     */
 
520
    void swap(basic_settings_section& that)
 
521
    {
 
522
        property_tree_type* const p = m_ptree;
 
523
        m_ptree = that.m_ptree;
 
524
        that.m_ptree = p;
 
525
    }
 
526
 
 
527
protected:
 
528
    explicit basic_settings_section(property_tree_type* tree) : m_ptree(tree)
 
529
    {
 
530
    }
 
531
};
 
532
 
 
533
template< typename CharT >
 
534
inline void swap(basic_settings_section< CharT >& left, basic_settings_section< CharT >& right)
 
535
{
 
536
    left.swap(right);
 
537
}
 
538
 
 
539
 
 
540
/*!
 
541
 * \brief The class represents settings container
 
542
 *
 
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:
 
545
 *
 
546
 * <code><pre>
 
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"
 
550
 *                                      // to value "10"
 
551
 * </pre></code>
 
552
 *
 
553
 * There are also other methods to work with parameters.
 
554
 */
 
555
template< typename CharT >
 
556
class basic_settings :
 
557
    public basic_settings_section< CharT >
 
558
{
 
559
    typedef basic_settings this_type;
 
560
    BOOST_COPYABLE_AND_MOVABLE(this_type)
 
561
 
 
562
public:
 
563
    //! Section type
 
564
    typedef basic_settings_section< CharT > section;
 
565
    //! Property tree type
 
566
    typedef typename section::property_tree_type property_tree_type;
 
567
 
 
568
public:
 
569
    /*!
 
570
     * Default constructor. Creates an empty settings container.
 
571
     */
 
572
    basic_settings() : section(new property_tree_type())
 
573
    {
 
574
    }
 
575
 
 
576
    /*!
 
577
     * Copy constructor.
 
578
     */
 
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))
 
581
    {
 
582
    }
 
583
 
 
584
    /*!
 
585
     * Move constructor.
 
586
     */
 
587
    basic_settings(BOOST_RV_REF(this_type) that)
 
588
    {
 
589
        this->swap(that);
 
590
    }
 
591
    /*!
 
592
     * Initializing constructor. Creates a settings container with the copy of the specified property tree.
 
593
     */
 
594
    explicit basic_settings(property_tree_type const& tree) : section(new property_tree_type(tree))
 
595
    {
 
596
    }
 
597
 
 
598
    /*!
 
599
     * Destructor
 
600
     */
 
601
    ~basic_settings()
 
602
    {
 
603
        delete this->m_ptree;
 
604
    }
 
605
 
 
606
    /*!
 
607
     * Copy assignment operator.
 
608
     */
 
609
    basic_settings& operator= (BOOST_COPY_ASSIGN_REF(basic_settings) that)
 
610
    {
 
611
        if (this != &that)
 
612
        {
 
613
            basic_settings tmp = that;
 
614
            this->swap(tmp);
 
615
        }
 
616
        return *this;
 
617
    }
 
618
    /*!
 
619
     * Move assignment operator.
 
620
     */
 
621
    basic_settings& operator= (BOOST_RV_REF(basic_settings) that)
 
622
    {
 
623
        this->swap(that);
 
624
        return *this;
 
625
    }
 
626
};
 
627
 
 
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
 
631
#endif
 
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
 
635
#endif
 
636
 
 
637
BOOST_LOG_CLOSE_NAMESPACE // namespace log
 
638
 
 
639
} // namespace boost
 
640
 
 
641
#include <boost/log/detail/footer.hpp>
 
642
 
 
643
#endif // BOOST_LOG_UTILITY_SETUP_SETTINGS_HPP_INCLUDED_