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

« back to all changes in this revision

Viewing changes to boost/includes/boost/log/utility/once_block.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   once_block.hpp
 
9
 * \author Andrey Semashev
 
10
 * \date   23.06.2010
 
11
 *
 
12
 * \brief  The header defines classes and macros for once-blocks.
 
13
 */
 
14
 
 
15
#ifndef BOOST_LOG_UTILITY_ONCE_BLOCK_HPP_INCLUDED_
 
16
#define BOOST_LOG_UTILITY_ONCE_BLOCK_HPP_INCLUDED_
 
17
 
 
18
#include <boost/log/detail/config.hpp>
 
19
#include <boost/log/utility/unique_identifier_name.hpp>
 
20
#include <boost/log/detail/header.hpp>
 
21
 
 
22
#ifdef BOOST_LOG_HAS_PRAGMA_ONCE
 
23
#pragma once
 
24
#endif
 
25
 
 
26
#ifndef BOOST_LOG_NO_THREADS
 
27
 
 
28
namespace boost {
 
29
 
 
30
BOOST_LOG_OPEN_NAMESPACE
 
31
 
 
32
/*!
 
33
 * \brief A flag to detect if a code block has already been executed.
 
34
 *
 
35
 * This structure should be used in conjunction with the \c BOOST_LOG_ONCE_BLOCK_FLAG
 
36
 * macro. Usage example:
 
37
 *
 
38
 * <code>
 
39
 * void foo()
 
40
 * {
 
41
 *     static once_block_flag flag = BOOST_LOG_ONCE_BLOCK_INIT;
 
42
 *     BOOST_LOG_ONCE_BLOCK_FLAG(flag)
 
43
 *     {
 
44
 *         puts("Hello, world once!");
 
45
 *     }
 
46
 * }
 
47
 * </code>
 
48
 */
 
49
struct once_block_flag
 
50
{
 
51
#ifndef BOOST_LOG_DOXYGEN_PASS
 
52
    // Do not use, implementation detail
 
53
    enum
 
54
    {
 
55
        uninitialized = 0,
 
56
        being_initialized,
 
57
        initialized
 
58
    }
 
59
    status;
 
60
#endif // BOOST_LOG_DOXYGEN_PASS
 
61
};
 
62
 
 
63
/*!
 
64
 * \def BOOST_LOG_ONCE_BLOCK_INIT
 
65
 *
 
66
 * The static initializer for \c once_block_flag.
 
67
 */
 
68
#define BOOST_LOG_ONCE_BLOCK_INIT { boost::log::once_block_flag::uninitialized }
 
69
 
 
70
namespace aux {
 
71
 
 
72
class once_block_sentry
 
73
{
 
74
private:
 
75
    once_block_flag& m_Flag;
 
76
 
 
77
public:
 
78
    explicit once_block_sentry(once_block_flag& f) : m_Flag(f)
 
79
    {
 
80
    }
 
81
 
 
82
    ~once_block_sentry()
 
83
    {
 
84
        if (m_Flag.status != once_block_flag::initialized)
 
85
            rollback();
 
86
    }
 
87
 
 
88
    bool executed() const
 
89
    {
 
90
        return (m_Flag.status == once_block_flag::initialized || enter_once_block());
 
91
    }
 
92
 
 
93
    BOOST_LOG_API void commit();
 
94
 
 
95
private:
 
96
    //  Non-copyable, non-assignable
 
97
    once_block_sentry(once_block_sentry const&);
 
98
    once_block_sentry& operator= (once_block_sentry const&);
 
99
 
 
100
    BOOST_LOG_API bool enter_once_block() const;
 
101
    BOOST_LOG_API void rollback();
 
102
};
 
103
 
 
104
} // namespace aux
 
105
 
 
106
BOOST_LOG_CLOSE_NAMESPACE // namespace log
 
107
 
 
108
} // namespace boost
 
109
 
 
110
#else // BOOST_LOG_NO_THREADS
 
111
 
 
112
namespace boost {
 
113
 
 
114
BOOST_LOG_OPEN_NAMESPACE
 
115
 
 
116
struct once_block_flag
 
117
{
 
118
    bool status;
 
119
};
 
120
 
 
121
#define BOOST_LOG_ONCE_BLOCK_INIT { false }
 
122
 
 
123
namespace aux {
 
124
 
 
125
class once_block_sentry
 
126
{
 
127
private:
 
128
    once_block_flag& m_Flag;
 
129
 
 
130
public:
 
131
    explicit once_block_sentry(once_block_flag& f) : m_Flag(f)
 
132
    {
 
133
    }
 
134
 
 
135
    bool executed() const
 
136
    {
 
137
        return m_Flag.status;
 
138
    }
 
139
 
 
140
    void commit()
 
141
    {
 
142
        m_Flag.status = true;
 
143
    }
 
144
 
 
145
private:
 
146
    //  Non-copyable, non-assignable
 
147
    once_block_sentry(once_block_sentry const&);
 
148
    once_block_sentry& operator= (once_block_sentry const&);
 
149
};
 
150
 
 
151
} // namespace aux
 
152
 
 
153
BOOST_LOG_CLOSE_NAMESPACE // namespace log
 
154
 
 
155
} // namespace boost
 
156
 
 
157
#endif // BOOST_LOG_NO_THREADS
 
158
 
 
159
#ifndef BOOST_LOG_DOXYGEN_PASS
 
160
 
 
161
#define BOOST_LOG_ONCE_BLOCK_FLAG_INTERNAL(flag_var, sentry_var)\
 
162
    for (boost::log::aux::once_block_sentry sentry_var((flag_var));\
 
163
        !sentry_var.executed(); sentry_var.commit())
 
164
 
 
165
#define BOOST_LOG_ONCE_BLOCK_INTERNAL(flag_var, sentry_var)\
 
166
    static boost::log::once_block_flag flag_var = BOOST_LOG_ONCE_BLOCK_INIT;\
 
167
    BOOST_LOG_ONCE_BLOCK_FLAG_INTERNAL(flag_var, sentry_var)
 
168
 
 
169
#endif // BOOST_LOG_DOXYGEN_PASS
 
170
 
 
171
/*!
 
172
 * \def BOOST_LOG_ONCE_BLOCK_FLAG(flag_var)
 
173
 *
 
174
 * Begins a code block to be executed only once, with protection against thread concurrency.
 
175
 * User has to provide the flag variable that controls whether the block has already
 
176
 * been executed.
 
177
 */
 
178
#define BOOST_LOG_ONCE_BLOCK_FLAG(flag_var)\
 
179
    BOOST_LOG_ONCE_BLOCK_INTERNAL(\
 
180
        flag_var,\
 
181
        BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_once_block_sentry_))
 
182
 
 
183
/*!
 
184
 * \def BOOST_LOG_ONCE_BLOCK()
 
185
 *
 
186
 * Begins a code block to be executed only once, with protection against thread concurrency.
 
187
 */
 
188
#define BOOST_LOG_ONCE_BLOCK()\
 
189
    BOOST_LOG_ONCE_BLOCK_INTERNAL(\
 
190
        BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_once_block_flag_),\
 
191
        BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_once_block_sentry_))
 
192
 
 
193
#include <boost/log/detail/footer.hpp>
 
194
 
 
195
#endif // BOOST_LOG_UTILITY_ONCE_BLOCK_HPP_INCLUDED_