Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/wave/util/cpp_ifblock.hpp @ 30

Last change on this file since 30 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 4.9 KB
Line 
1/*=============================================================================
2    Boost.Wave: A Standard compliant C++ preprocessor library
3
4    http://www.boost.org/
5
6    Copyright (c) 2001-2007 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
11#if !defined(CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED)
12#define CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED
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///////////////////////////////////////////////////////////////////////////////
23namespace boost {
24namespace wave {
25namespace util {
26
27///////////////////////////////////////////////////////////////////////////////
28// the class if_blocks handles recursive conditional compilation contexts
29class if_block
30{
31public:
32    if_block() :
33        status(true), some_part_status(true), 
34        enclosing_status(true), is_in_else(false)
35    {
36    }
37    if_block(bool status_, bool enclosing_status_) : 
38        status(status_), 
39        some_part_status(status_),
40        enclosing_status(enclosing_status_),
41        is_in_else(false)
42    {
43    }
44
45    void set_status(bool status_) 
46    { 
47        status = status_; 
48        if (status_) 
49            some_part_status = true; 
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
57private:
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
66class if_block_stack 
67:   private std::stack<if_block> 
68{
69public:
70    typedef std::stack<if_block>::size_type size_type;
71   
72    void enter_if_block(bool new_status)
73    {
74    // If enclosing block is false, then this block is also false
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()) {
85            // entered a (false) #elif block from a true block
86                this->top().set_status(false);
87            } 
88            else if (new_status && !this->top().get_some_part_status()) {
89            // Entered true #elif block and no previous block was true
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()) {
102            // Entered (true) #else block and no previous block was true
103                this->top().set_status(true);
104            } 
105            else if (get_status()) {
106            // Entered (false) #else block from true block
107                this->top().set_status(false);
108            }
109
110        // Set else flag
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
124// return, whether the top (innermost) condition is true or false
125    bool get_status() const
126    { 
127        return 0 == this->size() || this->top().get_status(); 
128    }
129    bool get_some_part_status() const
130    { 
131        return 0 == this->size() || this->top().get_some_part_status(); 
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   
140protected:
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
161#endif // !defined(CPP_IFBLOCK_HPP_D4676B36_00C5_41F4_BC9F_9CBBAE3B8006_INCLUDED)
Note: See TracBrowser for help on using the repository browser.