|
1 // boost/identifier.hpp ----------------------------------------------------// |
|
2 |
|
3 // Copyright Beman Dawes 2006 |
|
4 |
|
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying |
|
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
|
7 |
|
8 // See documentation at http://www.boost.org/libs/utility |
|
9 |
|
10 #ifndef BOOST_IDENTIFIER_HPP |
|
11 #define BOOST_IDENTIFIER_HPP |
|
12 |
|
13 #include <boost/utility/enable_if.hpp> |
|
14 #include <boost/type_traits/is_base_of.hpp> |
|
15 #include <iosfwd> |
|
16 |
|
17 namespace boost |
|
18 { |
|
19 namespace detail |
|
20 { |
|
21 // class template identifier ---------------------------------------------// |
|
22 |
|
23 // Always used as a base class so that different instantiations result in |
|
24 // different class types even if instantiated with the same value type T. |
|
25 |
|
26 // Expected usage is that T is often an integer type, best passed by |
|
27 // value. There is no reason why T can't be a possibly larger class such as |
|
28 // std::string, best passed by const reference. |
|
29 |
|
30 // This implementation uses pass by value, based on expected common uses. |
|
31 |
|
32 template <typename T, typename D> |
|
33 class identifier |
|
34 { |
|
35 public: |
|
36 typedef T value_type; |
|
37 |
|
38 const value_type value() const { return m_value; } |
|
39 void assign( value_type v ) { m_value = v; } |
|
40 |
|
41 bool operator==( const D & rhs ) const { return m_value == rhs.m_value; } |
|
42 bool operator!=( const D & rhs ) const { return m_value != rhs.m_value; } |
|
43 bool operator< ( const D & rhs ) const { return m_value < rhs.m_value; } |
|
44 bool operator<=( const D & rhs ) const { return m_value <= rhs.m_value; } |
|
45 bool operator> ( const D & rhs ) const { return m_value > rhs.m_value; } |
|
46 bool operator>=( const D & rhs ) const { return m_value >= rhs.m_value; } |
|
47 |
|
48 typedef void (*unspecified_bool_type)(D); // without the D, unspecified_bool_type |
|
49 static void unspecified_bool_true(D){} // conversion allows relational operators |
|
50 // between different identifier types |
|
51 |
|
52 operator unspecified_bool_type() const { return m_value == value_type() ? 0 : unspecified_bool_true; } |
|
53 bool operator!() const { return m_value == value_type(); } |
|
54 |
|
55 // constructors are protected so that class can only be used as a base class |
|
56 protected: |
|
57 identifier() {} |
|
58 explicit identifier( value_type v ) : m_value(v) {} |
|
59 |
|
60 #if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // 1300 == VC++ 7.0 bug workaround |
|
61 private: |
|
62 #endif |
|
63 T m_value; |
|
64 }; |
|
65 |
|
66 //#ifndef BOOST_NO_SFINAE |
|
67 |
|
68 // template <class Ostream, class Id> |
|
69 // typename enable_if< is_base_of< identifier< typename Id::value_type, Id >, Id >, |
|
70 // Ostream & >::type operator<<( Ostream & os, const Id & id ) |
|
71 // { |
|
72 // return os << id.value(); |
|
73 // } |
|
74 |
|
75 // template <class Istream, class Id> |
|
76 // typename enable_if< is_base_of< identifier< typename Id::value_type, Id >, Id >, |
|
77 // Istream & >::type operator>>( Istream & is, Id & id ) |
|
78 // { |
|
79 // typename Id::value_type v; |
|
80 // is >> v; |
|
81 // id.value( v ); |
|
82 // return is; |
|
83 // } |
|
84 //#endif |
|
85 |
|
86 } // namespace detail |
|
87 } // namespace boost |
|
88 |
|
89 #endif // BOOST_IDENTIFIER_HPP |