1 /*
2  *          Copyright Andrey Semashev 2007 - 2015.
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   tagged_integer.hpp
9  * \author Andrey Semashev
10  * \date   11.01.2008
11  *
12  * \brief  This header is the Boost.Log library implementation, see the library documentation
13  *         at http://www.boost.org/doc/libs/release/libs/log/doc/html/index.html.
14  */
15 
16 #ifndef BOOST_LOG_TAGGED_INTEGER_HPP_INCLUDED_
17 #define BOOST_LOG_TAGGED_INTEGER_HPP_INCLUDED_
18 
19 #include <boost/log/detail/config.hpp>
20 #include <boost/log/detail/header.hpp>
21 
22 #ifdef BOOST_HAS_PRAGMA_ONCE
23 #pragma once
24 #endif
25 
26 namespace boost {
27 
28 BOOST_LOG_OPEN_NAMESPACE
29 
30 namespace aux {
31 
32 //! A tagged integer wrapper for type safety
33 template< typename IntT, typename TagT >
34 struct tagged_integer
35 {
36     //! Contained value type
37     typedef IntT integer_type;
38     //! Tag
39     typedef TagT tag;
40 
41     //! Contained value
42     integer_type value;
43 
44     //! Conversion operator
operator integer_typeboost::aux::tagged_integer45     BOOST_CONSTEXPR operator integer_type() const BOOST_NOEXCEPT { return value; }
46 
47     //  Increment
operator ++boost::aux::tagged_integer48     tagged_integer& operator++ () BOOST_NOEXCEPT { ++value; return *this; }
operator ++boost::aux::tagged_integer49     tagged_integer operator++ (int) BOOST_NOEXCEPT { tagged_integer temp = *this; ++value; return temp; }
50     //  Decrement
operator --boost::aux::tagged_integer51     tagged_integer& operator-- () BOOST_NOEXCEPT { --value; return *this; }
operator --boost::aux::tagged_integer52     tagged_integer operator-- (int) BOOST_NOEXCEPT { tagged_integer temp = *this; --value; return temp; }
53 
54 #define BOOST_LOG_TAGGED_INTEGER_OP(op)\
55     tagged_integer& operator op (tagged_integer const& that) BOOST_NOEXCEPT { value op that.value; return *this; }
56 
57     BOOST_LOG_TAGGED_INTEGER_OP(|=)
58     BOOST_LOG_TAGGED_INTEGER_OP(&=)
59     BOOST_LOG_TAGGED_INTEGER_OP(^=)
60     BOOST_LOG_TAGGED_INTEGER_OP(+=)
61     BOOST_LOG_TAGGED_INTEGER_OP(-=)
62     BOOST_LOG_TAGGED_INTEGER_OP(*=)
63     BOOST_LOG_TAGGED_INTEGER_OP(/=)
64     BOOST_LOG_TAGGED_INTEGER_OP(%=)
65 
66 #undef BOOST_LOG_TAGGED_INTEGER_OP
67 
68     //! Inversion operator
operator ~boost::aux::tagged_integer69     tagged_integer& operator~ () BOOST_NOEXCEPT { ~value; return *this; }
70 
71     //  Shift operators
72     template< typename T >
operator <<=boost::aux::tagged_integer73     tagged_integer& operator<<= (T const& that) BOOST_NOEXCEPT { value <<= that; return *this; }
74     template< typename T >
operator >>=boost::aux::tagged_integer75     tagged_integer& operator>>= (T const& that) BOOST_NOEXCEPT { value >>= that; return *this; }
76 
77 private:
78     //  Protection against improper usage
79     template< typename T1, typename T2 >
80     tagged_integer& operator<<= (tagged_integer< T1, T2 > const&);
81     template< typename T1, typename T2 >
82     tagged_integer& operator>>= (tagged_integer< T1, T2 > const&);
83 };
84 
85     //  Relational operators
86 #define BOOST_LOG_TAGGED_INTEGER_OP(op)\
87     template< typename IntT, typename TagT >\
88     inline bool operator op (\
89         tagged_integer< IntT, TagT > const& left, tagged_integer< IntT, TagT > const& right) BOOST_NOEXCEPT\
90     {\
91         return (left.value op right.value);\
92     }
93 
94 BOOST_LOG_TAGGED_INTEGER_OP(==)
95 BOOST_LOG_TAGGED_INTEGER_OP(!=)
96 BOOST_LOG_TAGGED_INTEGER_OP(<)
97 BOOST_LOG_TAGGED_INTEGER_OP(>)
98 BOOST_LOG_TAGGED_INTEGER_OP(<=)
99 BOOST_LOG_TAGGED_INTEGER_OP(>=)
100 
101 #undef BOOST_LOG_TAGGED_INTEGER_OP
102 
103 #define BOOST_LOG_TAGGED_INTEGER_OP(op)\
104     template< typename IntT, typename TagT >\
105     inline tagged_integer< IntT, TagT > operator op (\
106         tagged_integer< IntT, TagT > const& left, tagged_integer< IntT, TagT > const& right) BOOST_NOEXCEPT\
107     {\
108         tagged_integer< IntT, TagT > temp = left;\
109         temp op##= right;\
110         return temp;\
111     }
112 
113 BOOST_LOG_TAGGED_INTEGER_OP(|)
114 BOOST_LOG_TAGGED_INTEGER_OP(&)
115 BOOST_LOG_TAGGED_INTEGER_OP(^)
116 BOOST_LOG_TAGGED_INTEGER_OP(+)
117 BOOST_LOG_TAGGED_INTEGER_OP(-)
118 BOOST_LOG_TAGGED_INTEGER_OP(*)
119 BOOST_LOG_TAGGED_INTEGER_OP(/)
120 BOOST_LOG_TAGGED_INTEGER_OP(%)
121 
122 #undef BOOST_LOG_TAGGED_INTEGER_OP
123 
124 #define BOOST_LOG_TAGGED_INTEGER_OP(op)\
125     template< typename IntT, typename TagT, typename T >\
126     inline tagged_integer< IntT, TagT > operator op (\
127         tagged_integer< IntT, TagT > const& left, T const& right) BOOST_NOEXCEPT\
128     {\
129         tagged_integer< IntT, TagT > temp = left;\
130         temp op##= right;\
131         return temp;\
132     }
133 
134 BOOST_LOG_TAGGED_INTEGER_OP(<<)
135 BOOST_LOG_TAGGED_INTEGER_OP(>>)
136 
137 #undef BOOST_LOG_TAGGED_INTEGER_OP
138 
139 } // namespace aux
140 
141 BOOST_LOG_CLOSE_NAMESPACE // namespace log
142 
143 } // namespace boost
144 
145 #include <boost/log/detail/footer.hpp>
146 
147 #endif // BOOST_LOG_TAGGED_INTEGER_HPP_INCLUDED_
148