]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*============================================================================= |
2 | Boost.Wave: A Standard compliant C++ preprocessor library | |
3 | ||
4 | http://www.boost.org/ | |
5 | ||
6 | Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost | |
7 | Software License, Version 1.0. (See accompanying file | |
8 | LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | =============================================================================*/ | |
10 | ||
20effc67 TL |
11 | #if !defined(BOOST_CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED) |
12 | #define BOOST_CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED | |
7c673cae FG |
13 | |
14 | #include <stack> | |
15 | #include <boost/wave/wave_config.hpp> | |
16 | ||
17 | // this must occur after all of the includes and before any code appears | |
18 | #ifdef BOOST_HAS_ABI_HEADERS | |
19 | #include BOOST_ABI_PREFIX | |
20 | #endif | |
21 | ||
22 | /////////////////////////////////////////////////////////////////////////////// | |
23 | namespace boost { | |
24 | namespace wave { | |
25 | namespace util { | |
26 | ||
27 | /////////////////////////////////////////////////////////////////////////////// | |
28 | // the class if_blocks handles recursive conditional compilation contexts | |
29 | class if_block | |
30 | { | |
31 | public: | |
32 | if_block() : | |
b32b8144 | 33 | status(true), some_part_status(true), |
7c673cae FG |
34 | enclosing_status(true), is_in_else(false) |
35 | { | |
36 | } | |
b32b8144 FG |
37 | if_block(bool status_, bool enclosing_status_) : |
38 | status(status_), | |
7c673cae FG |
39 | some_part_status(status_), |
40 | enclosing_status(enclosing_status_), | |
41 | is_in_else(false) | |
42 | { | |
43 | } | |
44 | ||
b32b8144 FG |
45 | void set_status(bool status_) |
46 | { | |
47 | status = status_; | |
48 | if (status_) | |
49 | some_part_status = true; | |
7c673cae FG |
50 | } |
51 | bool get_status() const { return status; } | |
52 | bool get_some_part_status() const { return some_part_status; } | |
53 | bool get_enclosing_status() const { return enclosing_status; } | |
54 | bool get_in_else() const { return is_in_else; } | |
55 | void set_in_else() { is_in_else = true; } | |
56 | ||
57 | private: | |
58 | bool status; // Current block is true | |
59 | bool some_part_status; // One of the preceding or current #if/#elif was true | |
60 | bool enclosing_status; // Enclosing #if block is true | |
61 | bool is_in_else; // Inside the #else part | |
62 | }; | |
63 | ||
64 | /////////////////////////////////////////////////////////////////////////////// | |
65 | // stack of conditional compilation contexts | |
b32b8144 FG |
66 | class if_block_stack |
67 | : private std::stack<if_block> | |
7c673cae FG |
68 | { |
69 | public: | |
70 | typedef std::stack<if_block>::size_type size_type; | |
71 | ||
72 | void enter_if_block(bool new_status) | |
73 | { | |
20effc67 | 74 | // If enclosing block is false, then this block is also false |
7c673cae FG |
75 | bool enclosing_status = get_status(); |
76 | this->push (value_type (new_status && enclosing_status, enclosing_status)); | |
77 | } | |
78 | bool enter_elif_block(bool new_status) | |
79 | { | |
80 | if (!is_inside_ifpart()) | |
81 | return false; // #elif without matching #if | |
82 | ||
83 | if (get_enclosing_status()) { | |
84 | if (get_status()) { | |
20effc67 | 85 | // entered a (false) #elif block from a true block |
7c673cae | 86 | this->top().set_status(false); |
b32b8144 | 87 | } |
7c673cae | 88 | else if (new_status && !this->top().get_some_part_status()) { |
20effc67 | 89 | // Entered true #elif block and no previous block was true |
7c673cae FG |
90 | this->top().set_status(new_status); |
91 | } | |
92 | } | |
93 | return true; | |
94 | } | |
95 | bool enter_else_block() | |
96 | { | |
97 | if (!is_inside_ifpart()) | |
98 | return false; // #else without matching #if | |
99 | ||
100 | if (get_enclosing_status()) { | |
101 | if (!this->top().get_some_part_status()) { | |
20effc67 | 102 | // Entered (true) #else block and no previous block was true |
7c673cae | 103 | this->top().set_status(true); |
b32b8144 | 104 | } |
7c673cae | 105 | else if (get_status()) { |
20effc67 | 106 | // Entered (false) #else block from true block |
7c673cae FG |
107 | this->top().set_status(false); |
108 | } | |
109 | ||
20effc67 | 110 | // Set else flag |
7c673cae FG |
111 | this->top().set_in_else(); |
112 | } | |
113 | return true; | |
114 | } | |
115 | bool exit_if_block() | |
116 | { | |
117 | if (0 == this->size()) | |
118 | return false; // #endif without matching #if | |
119 | ||
120 | this->pop(); | |
121 | return true; | |
122 | } | |
123 | ||
20effc67 | 124 | // return, whether the top (innermost) condition is true or false |
7c673cae | 125 | bool get_status() const |
b32b8144 FG |
126 | { |
127 | return 0 == this->size() || this->top().get_status(); | |
7c673cae FG |
128 | } |
129 | bool get_some_part_status() const | |
b32b8144 FG |
130 | { |
131 | return 0 == this->size() || this->top().get_some_part_status(); | |
7c673cae FG |
132 | } |
133 | bool get_enclosing_status() const | |
134 | { | |
135 | return 0 == this->size() || this->top().get_enclosing_status(); | |
136 | } | |
137 | ||
138 | size_type get_if_block_depth() const { return this->size(); } | |
139 | ||
140 | protected: | |
141 | bool is_inside_ifpart() const | |
142 | { | |
143 | return 0 != this->size() && !this->top().get_in_else(); | |
144 | } | |
145 | bool is_inside_elsepart() const | |
146 | { | |
147 | return 0 != this->size() && this->top().get_in_else(); | |
148 | } | |
149 | }; | |
150 | ||
151 | /////////////////////////////////////////////////////////////////////////////// | |
152 | } // namespace util | |
153 | } // namespace wave | |
154 | } // namespace boost | |
155 | ||
156 | // the suffix header occurs after all of the code | |
157 | #ifdef BOOST_HAS_ABI_HEADERS | |
158 | #include BOOST_ABI_SUFFIX | |
159 | #endif | |
160 | ||
20effc67 | 161 | #endif // !defined(BOOST_CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED) |