Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/wave/grammars/cpp_expression_value.hpp @ 47

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

updated boost from 1_33_1 to 1_34_1

File size: 26.8 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_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
12#define CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED
13
14#if defined (BOOST_SPIRIT_DEBUG)
15#include <iostream>
16#endif // defined(BOOST_SPIRIT_DEBUG)
17
18#include <boost/wave/wave_config.hpp>
19
20// this must occur after all of the includes and before any code appears
21#ifdef BOOST_HAS_ABI_HEADERS
22#include BOOST_ABI_PREFIX
23#endif
24
25///////////////////////////////////////////////////////////////////////////////
26namespace boost {
27namespace wave {
28namespace grammars {
29namespace closures {
30
31class closure_value;
32inline bool as_bool(closure_value const& v);
33
34///////////////////////////////////////////////////////////////////////////////
35//
36//  The closure_value class represents the closure type, which is used for the
37//  expression grammar.
38//
39//      This class was introduced to allow the expression grammar to respect
40//      the numeric type of a numeric literal or expression result.
41//
42///////////////////////////////////////////////////////////////////////////////
43class closure_value {
44public:
45
46    enum value_type {
47        is_int = 1,
48        is_uint = 2,
49        is_bool = 3
50    };
51   
52    closure_value(value_error valid_ = error_noerror) 
53    : type(is_int), valid(valid_) 
54    { value.i = 0; }
55    explicit closure_value(int i, value_error valid_ = error_noerror) 
56    : type(is_int), valid(valid_) 
57    { value.i = i; }
58    explicit closure_value(unsigned int ui, value_error valid_ = error_noerror) 
59    : type(is_uint), valid(valid_) 
60    { value.ui = ui; }
61    explicit closure_value(long i, value_error valid_ = error_noerror) 
62    : type(is_int), valid(valid_) 
63    { value.i = i; }
64    explicit closure_value(unsigned long ui, value_error valid_ = error_noerror) 
65    : type(is_uint), valid(valid_) 
66    { value.ui = ui; }
67    explicit closure_value(bool b, value_error valid_ = error_noerror) 
68    : type(is_bool), valid(valid_) 
69    { value.b = b; }
70
71    value_type get_type() const { return type; }
72    value_error is_valid() const { return valid; }
73   
74// explicit conversion
75    friend int as_int(closure_value const& v)
76    {
77        switch (v.type) {
78        case is_uint:   return v.value.ui;
79        case is_bool:   return v.value.b ? 1 : 0;
80        case is_int:    break;
81        }
82        return v.value.i;
83    }
84    friend unsigned int as_uint(closure_value const& v)
85    {
86        switch (v.type) {
87        case is_uint:   return v.value.ui;
88        case is_bool:   return v.value.b ? 1 : 0;
89        case is_int:    break;
90        }
91        return v.value.i;
92    }
93    friend long as_long(closure_value const& v) 
94    {
95        switch (v.type) {
96        case is_uint:   return v.value.ui;
97        case is_bool:   return v.value.b ? 1 : 0;
98        case is_int:    break;
99        }
100        return v.value.i;
101    }
102    friend unsigned long as_ulong(closure_value const& v)
103    {
104        switch (v.type) {
105        case is_uint:   return v.value.ui;
106        case is_bool:   return v.value.b ? 1 : 0;
107        case is_int:    break;
108        }
109        return v.value.i;
110    }
111    friend bool as_bool(closure_value const& v)
112    {
113        switch (v.type) {
114        case is_uint:   return v.value.ui != 0;
115        case is_bool:   return v.value.b;
116        case is_int:    break;
117        }
118        return v.value.i != 0.0;
119    }
120
121// assignment   
122    closure_value &operator= (closure_value const &rhs)
123    {
124        switch (rhs.get_type()) {
125        case is_int:   
126            value.i = as_long(rhs); 
127            type = is_int;
128            break;
129       
130        case is_uint:   
131            value.ui = as_ulong(rhs); 
132            type = is_uint;
133            break;
134       
135        case is_bool:   
136            value.b = as_bool(rhs);
137            type = is_bool;
138            break;
139        }
140        valid = rhs.valid;
141        return *this;
142    }
143    closure_value &operator= (int rhs)
144    {
145        type = is_int;
146        value.i = rhs;
147        valid = error_noerror;
148        return *this;
149    }
150    closure_value &operator= (unsigned int rhs)
151    {
152        type = is_uint;
153        value.ui = rhs;
154        valid = error_noerror;
155        return *this;
156    }
157    closure_value &operator= (long rhs)
158    {
159        type = is_int;
160        value.i = rhs;
161        valid = error_noerror;
162        return *this;
163    }
164    closure_value &operator= (unsigned long rhs)
165    {
166        type = is_uint;
167        value.ui = rhs;
168        valid = error_noerror;
169        return *this;
170    }
171    closure_value &operator= (bool rhs)
172    {
173        type = is_bool;
174        value.b = rhs;
175        valid = error_noerror;
176        return *this;
177    }
178
179// arithmetics
180    closure_value &operator+= (closure_value const &rhs)
181    {
182        switch (type) {
183        case is_int:   
184            switch(rhs.type) {
185            case is_bool:
186                {
187                    long result = value.i + as_long(rhs); 
188                    if (rhs.value.i > 0L && value.i > result || 
189                        rhs.value.i < 0L && value.i < result)
190                    {
191                        valid = error_integer_overflow;
192                    }
193                    else {
194                        value.i = result;
195                    }
196                }
197                break;
198               
199            case is_int:
200                {
201                    long result = value.i + rhs.value.i;
202                    if (rhs.value.i > 0L && value.i > result || 
203                        rhs.value.i < 0L && value.i < result)
204                    {
205                        valid = error_integer_overflow;
206                    }
207                    else {
208                        value.i = result;
209                    }
210                }
211                break;
212               
213            case is_uint:
214                {
215                    unsigned long result = value.ui + rhs.value.ui; 
216                    if (result < value.ui) {
217                        valid = error_integer_overflow;
218                    }
219                    else {
220                        value.ui = result;
221                        type = is_uint; 
222                    }
223                }
224                break;
225            }
226            break;
227           
228        case is_uint:
229            {
230                unsigned long result = value.ui + as_ulong(rhs); 
231                if (result < value.ui) {
232                    valid = error_integer_overflow;
233                }
234                else {
235                    value.ui = result;
236                }
237            }
238            break;
239           
240        case is_bool:   
241            value.i = value.b + as_bool(rhs);
242            type = is_int;
243        }
244        valid = (value_error)(valid | rhs.valid);
245        return *this;
246    }
247    closure_value &operator-= (closure_value const &rhs)
248    {
249        switch (type) {
250        case is_int:
251            switch(rhs.type) {
252            case is_bool:
253                {
254                    long result = value.i - as_long(rhs); 
255                    if (rhs.value.i > 0L && result > value.i || 
256                        rhs.value.i < 0L && result < value.i)
257                    {
258                        valid = error_integer_overflow;
259                    }
260                    else {
261                        value.i = result;
262                    }
263                }
264                break;
265
266            case is_int:
267                {
268                    long result = value.i - rhs.value.i;
269                    if (rhs.value.i > 0L && result > value.i || 
270                        rhs.value.i < 0L && result < value.i)
271                    {
272                        valid = error_integer_overflow;
273                    }
274                    else {
275                        value.i = result;
276                    }
277                }
278                break;
279               
280            case is_uint:
281                {
282                    unsigned long result = value.ui - rhs.value.ui; 
283                    if (result > value.ui) {
284                        valid = error_integer_overflow;
285                    }
286                    else {
287                        value.ui = result;
288                        type = is_uint; 
289                    }
290                }
291                break;
292            }
293            break;
294           
295        case is_uint:
296            switch(rhs.type) {
297            case is_bool:
298                {
299                    unsigned long result = value.ui - as_ulong(rhs); 
300                    if (result > value.ui)
301                    {
302                        valid = error_integer_overflow;
303                    }
304                    else {
305                        value.ui = result;
306                    }
307                }
308                break;
309
310            case is_int:
311                {
312                    unsigned long result = value.ui - rhs.value.i;
313                    if (rhs.value.i > 0L && result > value.ui || 
314                        rhs.value.i < 0L && result < value.ui)
315                    {
316                        valid = error_integer_overflow;
317                    }
318                    else {
319                        value.ui = result;
320                    }
321                }
322                break;
323               
324            case is_uint:
325                {
326                    unsigned long result = value.ui - rhs.value.ui; 
327                    if (result > value.ui) {
328                        valid = error_integer_overflow;
329                    }
330                    else {
331                        value.ui = result;
332                    }
333                }
334                break;
335            }
336            break;
337
338        case is_bool:   
339            value.i = value.b - as_bool(rhs);
340            type = is_int;
341        }
342        valid = (value_error)(valid | rhs.valid);
343        return *this;
344    }
345    closure_value &operator*= (closure_value const &rhs)
346    {
347        switch (type) {
348        case is_int:   
349            switch(rhs.type) {
350            case is_bool:   value.i *= as_long(rhs); break;
351            case is_int:
352                {
353                    long result = value.i * rhs.value.i; 
354                    if (0 != value.i && 0 != rhs.value.i &&
355                        (result / value.i != rhs.value.i ||
356                         result / rhs.value.i != value.i)
357                       )
358                    {
359                        valid = error_integer_overflow;
360                    }
361                    else {
362                        value.i = result;
363                    }
364                }
365                break;
366               
367            case is_uint:
368                {
369                    unsigned long result = value.ui * rhs.value.ui; 
370                    if (0 != value.ui && 0 != rhs.value.ui &&
371                        (result / value.ui != rhs.value.ui ||
372                         result / rhs.value.ui != value.ui)
373                       )
374                    {
375                        valid = error_integer_overflow;
376                    }
377                    else {
378                        value.ui = result;
379                        type = is_uint; 
380                    }
381                }
382                break;
383            }
384            break;
385           
386        case is_uint:
387            {
388                unsigned long rhs_val = as_ulong(rhs);
389                unsigned long result = value.ui * rhs_val; 
390                if (0 != value.ui && 0 != rhs_val &&
391                    (result / value.ui != rhs_val ||
392                      result / rhs_val != value.ui)
393                    )
394                {
395                    valid = error_integer_overflow;
396                }
397                else {
398                    value.ui = result;
399                    type = is_uint; 
400                }
401            }
402            break;
403           
404        case is_bool:
405            switch (rhs.type) {
406            case is_int:
407                value.i = (value.b ? 1 : 0) * rhs.value.i; 
408                type = is_int; 
409                break;
410               
411            case is_uint:
412                value.ui = (value.b ? 1 : 0) * rhs.value.ui; 
413                type = is_uint; 
414                break;
415               
416            case is_bool:
417                value.b = 0 != ((value.b ? 1 : 0) * (rhs.value.b ? 1 : 0));
418                break;
419            }
420        }
421        valid = (value_error)(valid | rhs.valid);
422        return *this;
423    }
424    closure_value &operator/= (closure_value const &rhs)
425    {
426        switch (type) {
427        case is_int:   
428            switch(rhs.type) {
429            case is_bool:   
430            case is_int:
431                if (as_long(rhs) != 0) {
432                    if (value.i == -value.i && -1 == rhs.value.i) {
433                    // LONG_MIN / -1 on two's complement
434                        valid = error_integer_overflow;
435                    }
436                    else {
437                        value.i /= as_long(rhs); 
438                    }
439                }
440                else {
441                    valid = error_division_by_zero;   // division by zero
442                }
443                break;
444               
445            case is_uint:
446                if (rhs.value.ui != 0) {
447                    value.ui /= rhs.value.ui; 
448                    type = is_uint; 
449                }
450                else {
451                    valid = error_division_by_zero;      // division by zero
452                }
453                break;
454            }
455            break;
456           
457        case is_uint: 
458            if (as_ulong(rhs) != 0) 
459                value.ui /= as_ulong(rhs); 
460            else
461                valid = error_division_by_zero;         // division by zero
462            break;
463
464        case is_bool: 
465            if (as_bool(rhs)) {
466                switch(rhs.type) {
467                case is_int:
468                    value.i = (value.b ? 1 : 0) / rhs.value.i;
469                    type = is_int;
470                    break;
471                   
472                case is_uint:
473                    value.i = (value.b ? 1 : 0) / rhs.value.ui;
474                    type = is_int;
475                    break;
476                   
477                case is_bool:
478                    break;
479                }
480            }
481            else {
482                valid = error_division_by_zero;         // division by zero
483            }
484        }
485        return *this;
486    }
487    closure_value &operator%= (closure_value const &rhs)
488    {
489        switch (type) {
490        case is_int:   
491            switch(rhs.type) {
492            case is_bool:   
493            case is_int:
494                if (as_long(rhs) != 0) {
495                    if (value.i == -value.i && -1 == rhs.value.i) {
496                    // LONG_MIN % -1 on two's complement
497                        valid = error_integer_overflow;
498                    }
499                    else {
500                        value.i %= as_long(rhs); 
501                    }
502                }
503                else {
504                    valid = error_division_by_zero;      // division by zero
505                }
506                break;
507               
508            case is_uint:
509                if (rhs.value.ui != 0) {
510                    value.ui %= rhs.value.ui; 
511                    type = is_uint; 
512                }
513                else {
514                    valid = error_division_by_zero;      // division by zero
515                }
516                break;
517            }
518            break;
519           
520        case is_uint: 
521            if (as_ulong(rhs) != 0) 
522                value.ui %= as_ulong(rhs); 
523            else
524                valid = error_division_by_zero;      // division by zero
525            break;
526
527        case is_bool: 
528            if (as_bool(rhs)) {
529                switch(rhs.type) {
530                case is_int:
531                    value.i = (value.b ? 1 : 0) % rhs.value.i;
532                    type = is_int;
533                    break;
534                   
535                case is_uint:
536                    value.i = (value.b ? 1 : 0) % rhs.value.ui;
537                    type = is_int;
538                    break;
539                   
540                case is_bool:
541                    break;
542                }                   
543            }
544            else {
545                valid = error_division_by_zero;      // division by zero
546            }
547        }
548        return *this;
549    }
550
551    friend closure_value
552    operator- (closure_value const &rhs)
553    {
554        switch (rhs.type) {
555        case is_int:
556            {
557                long value = as_long(rhs);
558                if (value != 0 && value == -value)
559                    return closure_value(-value, error_integer_overflow);
560                return closure_value(-value, rhs.valid);
561            }
562           
563        case is_bool:   return closure_value(-as_long(rhs), rhs.valid); 
564        case is_uint:   break;
565        }
566
567        long value = as_ulong(rhs);
568        if (value != 0 && value == -value)
569            return closure_value(-value, error_integer_overflow);
570        return closure_value(-value, rhs.valid);
571    }
572    friend closure_value
573    operator~ (closure_value const &rhs)
574    {
575        return closure_value(~as_ulong(rhs), rhs.valid); 
576    }
577    friend closure_value
578    operator! (closure_value const &rhs)
579    {
580        switch (rhs.type) {
581        case is_int:    return closure_value(!as_long(rhs), rhs.valid);
582        case is_bool:   return closure_value(!as_bool(rhs), rhs.valid); 
583        case is_uint:   break;
584        }
585        return closure_value(!as_ulong(rhs), rhs.valid);
586    }
587   
588// comparison
589    friend closure_value
590    operator== (closure_value const &lhs, closure_value const &rhs)
591    {
592        bool cmp = false;
593        switch (lhs.type) {
594        case is_int:
595            switch(rhs.type) {
596            case is_bool:   cmp = as_bool(lhs) == rhs.value.b; break;
597            case is_int:    cmp = lhs.value.i == rhs.value.i; break;
598            case is_uint:   cmp = lhs.value.ui == rhs.value.ui; break;
599            }
600            break;
601           
602        case is_uint:   cmp = lhs.value.ui == as_ulong(rhs); break;
603        case is_bool:   cmp = lhs.value.b == as_bool(rhs); break;
604        }
605        return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
606    }
607    friend closure_value
608    operator!= (closure_value const &lhs, closure_value const &rhs)
609    {
610        return closure_value(!as_bool(lhs == rhs), (value_error)(lhs.valid | rhs.valid));
611    }
612    friend closure_value
613    operator> (closure_value const &lhs, closure_value const &rhs)
614    {
615        bool cmp = false;
616        switch (lhs.type) {
617        case is_int:
618            switch(rhs.type) {
619            case is_bool:   cmp = lhs.value.i > as_long(rhs); break;
620            case is_int:    cmp = lhs.value.i > rhs.value.i; break;
621            case is_uint:   cmp = lhs.value.ui > rhs.value.ui; break;
622            }
623            break;
624           
625        case is_uint:   cmp = lhs.value.ui > as_ulong(rhs); break;
626        case is_bool:   cmp = lhs.value.b > as_bool(rhs); break;
627        }
628        return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
629    }
630    friend closure_value
631    operator< (closure_value const &lhs, closure_value const &rhs)
632    {
633        bool cmp = false;
634        switch (lhs.type) {
635        case is_int:
636            switch(rhs.type) {
637            case is_bool:   cmp = lhs.value.i < as_long(rhs); break;
638            case is_int:    cmp = lhs.value.i < rhs.value.i; break;
639            case is_uint:   cmp = lhs.value.ui < rhs.value.ui; break;
640            }
641            break;
642           
643        case is_uint:   cmp = lhs.value.ui < as_ulong(rhs); break;
644        case is_bool:   cmp = as_bool(lhs) < as_bool(rhs); break;
645        }
646        return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
647    }
648    friend closure_value
649    operator<= (closure_value const &lhs, closure_value const &rhs)
650    {
651        return closure_value(!as_bool(lhs > rhs), (value_error)(lhs.valid | rhs.valid));
652    }
653    friend closure_value
654    operator>= (closure_value const &lhs, closure_value const &rhs)
655    {
656        return closure_value(!as_bool(lhs < rhs), (value_error)(lhs.valid | rhs.valid));
657    }
658
659    closure_value &
660    operator<<= (closure_value const &rhs)
661    {
662        switch (type) {
663        case is_bool:
664        case is_int:
665            switch (rhs.type) {
666            case is_bool:
667            case is_int:
668                {
669                long shift_by = as_long(rhs);
670                   
671                    if (shift_by > 64) 
672                        shift_by = 64;
673                    else if (shift_by < -64)
674                        shift_by = -64;
675                    value.i <<= shift_by; 
676                }
677                break;
678               
679            case is_uint:
680                {
681                unsigned long shift_by = as_ulong(rhs);
682                   
683                    if (shift_by > 64) 
684                        shift_by = 64;
685                    value.ui <<= shift_by; 
686               
687                // Note: The usual arithmetic conversions are not performed on
688                //       bit shift operations.
689                }
690                break;
691            }
692            break;
693
694        case is_uint:
695            switch (rhs.type) {
696            case is_bool:
697            case is_int:
698                {
699                long shift_by = as_long(rhs);
700                   
701                    if (shift_by > 64) 
702                        shift_by = 64;
703                    else if (shift_by < -64)
704                        shift_by = -64;
705                    value.ui <<= shift_by; 
706                }
707                break;
708               
709            case is_uint:
710                {
711                unsigned long shift_by = as_ulong(rhs);
712                   
713                    if (shift_by > 64) 
714                        shift_by = 64;
715                    value.ui <<= shift_by; 
716                }
717                break;
718            }
719        }
720        valid = (value_error)(valid | rhs.valid);
721        return *this;
722    }
723
724    closure_value &
725    operator>>= (closure_value const &rhs)
726    {
727        switch (type) {
728        case is_bool:
729        case is_int:
730            switch (rhs.type) {
731            case is_bool:
732            case is_int:
733                {
734                long shift_by = as_long(rhs);
735                   
736                    if (shift_by > 64) 
737                        shift_by = 64;
738                    else if (shift_by < -64)
739                        shift_by = -64;
740                    value.i >>= shift_by; 
741                }
742                break;
743               
744            case is_uint:
745                {
746                unsigned long shift_by = as_ulong(rhs);
747                   
748                    if (shift_by > 64) 
749                        shift_by = 64;
750                    value.ui >>= shift_by; 
751               
752                // Note: The usual arithmetic conversions are not performed on
753                //       bit shift operations.
754                }
755                break;
756            }
757            break;
758           
759        case is_uint:
760            switch (rhs.type) {
761            case is_bool:
762            case is_int:
763                {
764                long shift_by = as_long(rhs);
765                   
766                    if (shift_by > 64) 
767                        shift_by = 64;
768                    else if (shift_by < -64)
769                        shift_by = -64;
770                    value.ui >>= shift_by; 
771                }
772                break;
773               
774            case is_uint:
775                {
776                unsigned long shift_by = as_ulong(rhs);
777                   
778                    if (shift_by > 64) 
779                        shift_by = 64;
780                    value.ui >>= shift_by; 
781                }
782                break;
783            }
784            break;
785        }
786        valid = (value_error)(valid | rhs.valid);
787        return *this;
788    }
789
790    friend closure_value
791    operator|| (closure_value const &lhs, closure_value const &rhs)
792    {
793        bool result = as_bool(lhs) || as_bool(rhs);
794        return closure_value(result, (value_error)(lhs.valid | rhs.valid));
795    }
796   
797    friend closure_value
798    operator&& (closure_value const &lhs, closure_value const &rhs)
799    {
800        bool result = as_bool(lhs) && as_bool(rhs);
801        return closure_value(result, (value_error)(lhs.valid | rhs.valid));
802    }
803
804    friend closure_value
805    operator| (closure_value const &lhs, closure_value const &rhs)
806    {
807        unsigned long result = as_ulong(lhs) | as_ulong(rhs);
808        return closure_value(result, (value_error)(lhs.valid | rhs.valid));
809    }
810   
811    friend closure_value
812    operator& (closure_value const &lhs, closure_value const &rhs)
813    {
814        unsigned long result = as_ulong(lhs) & as_ulong(rhs);
815        return closure_value(result, (value_error)(lhs.valid | rhs.valid));
816    }
817
818    friend closure_value
819    operator^ (closure_value const &lhs, closure_value const &rhs)
820    {
821        unsigned long result = as_ulong(lhs) ^ as_ulong(rhs);
822        return closure_value(result, (value_error)(lhs.valid | rhs.valid));
823    }
824   
825    // handle the ?: operator
826    closure_value &
827    handle_questionmark(closure_value const &cond, closure_value const &val2)
828    {
829        switch (type) {
830        case is_int:
831            switch (val2.type) {
832            case is_bool: value.b = as_bool(cond) ? value.b : as_bool(val2); break;
833            case is_int:  value.i = as_bool(cond) ? value.i : as_long(val2); break;
834            case is_uint: 
835                value.ui = as_bool(cond) ? value.ui : as_ulong(val2); 
836                type = is_uint;   // changing type!
837                break;
838            }
839            break;
840           
841        case is_uint:   value.ui = as_bool(cond) ? value.ui : as_ulong(val2); break;
842        case is_bool:   value.b = as_bool(cond) ? value.b : as_bool(val2); break;
843        }
844        valid = as_bool(cond) ? valid : val2.valid;
845        return *this;
846    }
847   
848#if defined (BOOST_SPIRIT_DEBUG)
849    friend std::ostream&
850    operator<< (std::ostream &o, closure_value const &val)
851    {
852        switch (val.type) {
853        case is_int:    o << "int(" << as_long(val) << ")"; break;
854        case is_uint:   o << "unsigned int(" << as_ulong(val) << ")"; break;
855        case is_bool:   o << "bool(" << as_bool(val) << ")"; break;
856        }
857        return o;
858    }
859#endif // defined(BOOST_SPIRIT_DEBUG)
860
861private:
862    value_type type;
863    union {
864        long i;
865        unsigned long ui;
866        bool b;
867    } value;
868    value_error valid;
869};
870
871///////////////////////////////////////////////////////////////////////////////
872}   // namespace closures
873}   // namespace grammars
874}   // namespace wave
875}   // namespace boost
876
877// the suffix header occurs after all of the code
878#ifdef BOOST_HAS_ABI_HEADERS
879#include BOOST_ABI_SUFFIX
880#endif
881
882#endif // !defined(CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
Note: See TracBrowser for help on using the repository browser.