Flags.h
Go to the documentation of this file.
1//===========================================================================
2/*!
3 *
4 *
5 * \brief Flexible and extensible mechanisms for holding flags.
6 *
7 *
8 *
9 * \author T.Voss
10 * \date 2010-2011
11 *
12 *
13 * \par Copyright 1995-2017 Shark Development Team
14 *
15 * <BR><HR>
16 * This file is part of Shark.
17 * <https://shark-ml.github.io/Shark/>
18 *
19 * Shark is free software: you can redistribute it and/or modify
20 * it under the terms of the GNU Lesser General Public License as published
21 * by the Free Software Foundation, either version 3 of the License, or
22 * (at your option) any later version.
23 *
24 * Shark is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU Lesser General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License
30 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
31 *
32 */
33//===========================================================================
34#ifndef SHARK_CORE_FLAGS_H
35#define SHARK_CORE_FLAGS_H
36
39
40namespace shark {
41
42
43///
44/// \brief Flexible and extensible mechanisms for holding flags.
45///
46/// \par
47/// The world's most airbrushed integer ever...
48///
49/// \par
50/// This class encapsulates a flexible mechanism for holding flags.
51/// Its templatization makes it possible to base it on any base
52/// type, while unsigned int will be the most common choice. This
53/// mechanism makes it possible, in principle, to support as many
54/// flags as needed. Furthermore, classes may extend the flags
55/// defined by their superclass.
56///
57template<typename Flag>
58class TypedFlags : public ISerializable {
59public:
60 TypedFlags() : m_flags( 0 ) { }
61 TypedFlags(TypedFlags const& other) : m_flags(other.m_flags) { }
62
63 virtual ~TypedFlags() {}
64
66 m_flags = rhs.m_flags;
67 return( *this );
68 }
69
70 inline void set( Flag f ) {
71 m_flags |= f;
72 }
73
74 inline void setAll() {
75 m_flags |= ~0;
76 }
77
78 inline void reset() {
79 m_flags = 0;
80 }
81
82 inline void reset( Flag f ) {
83 m_flags &= ~f;
84 }
85
86 inline bool test( Flag f ) const {
87 return ( m_flags & f) == (unsigned int)f;
88 }
89
90 inline bool operator&( Flag f ) const {
91 return ( m_flags & f) == (unsigned int)f;
92 }
93
94 inline TypedFlags<Flag> & operator|=( Flag f ) {
95 m_flags |= f;
96 return( *this );
97 }
98
100 m_flags |= flags.m_flags;
101 return( *this );
102 }
103
104 inline TypedFlags<Flag> operator|( Flag f ) const {
105 TypedFlags<Flag> copy( *this );
106 copy |= f;
107 return( copy );
108 }
109 inline TypedFlags<Flag> operator|(const TypedFlags<Flag>& flags ) const {
110 TypedFlags<Flag> copy( *this );
111 copy |= flags;
112 return copy;
113 }
114
115 virtual void read( InArchive & archive )
116 { archive & m_flags; }
117
118 virtual void write( OutArchive & archive ) const
119 { archive & m_flags; }
120
121protected:
122 unsigned int m_flags;
123};
124
125
126///
127/// \brief Exception indicating the attempt to use a feature which is not supported
128///
129template<class Feature>
131public:
132 TypedFeatureNotAvailableException( Feature feature, const std::string & file = std::string(), unsigned int line = 0 )
133 : Exception( "Feature not available", file, line ),
134 m_feature( feature ) {}
135 TypedFeatureNotAvailableException( const std::string & message, Feature feature, const std::string & file = std::string(), unsigned int line = 0 )
136 : Exception( message, file, line ),
137 m_feature( feature ) {}
138
139 Feature feature() const {
140 return m_feature ;
141 }
142protected:
143 Feature m_feature;
144};
145
146}
147
148namespace boost {
149namespace serialization {
150
151template< typename T >
152struct tracking_level< shark::TypedFlags<T> > {
153 typedef mpl::integral_c_tag tag;
154 BOOST_STATIC_CONSTANT( int, value = track_always );
155};
156
157}
158}
159
160#define SHARK_FEATURE_INTERFACE \
161typedef TypedFlags<Feature> Features;\
162protected:\
163Features m_features;\
164public:\
165const Features & features() const {\
166 return( m_features );\
167}\
168virtual void updateFeatures(){}\
169typedef TypedFeatureNotAvailableException<Feature> FeatureNotAvailableException
170
171/// Throws an Exception when called.
172/// This macro should be used in default implementations of the interface.
173/// This define also checks first whether the feature is set to true inside the class.
174/// If this is the case then we have encountered a programming mistake - so we assert instead.
175#define SHARK_FEATURE_EXCEPTION(FEATURE) \
176{assert(!(this->features()&FEATURE));\
177throw FeatureNotAvailableException("Class does not support Feature " #FEATURE, FEATURE,__FILE__, __LINE__);}
178/// Same as SHARK_FEATURE_EXCEPTION, but used when called from a derived class.
179/// Assumes that a typedef "base_type" for the Baseclass exists
180#define SHARK_FEATURE_EXCEPTION_DERIVED(FEATURE) \
181{assert(!(this->features()&base_type::FEATURE));\
182throw typename base_type::FeatureNotAvailableException("Class does not support Feature " #FEATURE, base_type::FEATURE,__FILE__, __LINE__);}
183
184/// Checks whether the feature is available, if not, it throws an exception.
185#define SHARK_FEATURE_CHECK(FEATURE)\
186if(!(this->features()&base_type::FEATURE)){SHARK_FEATURE_EXCEPTION_DERIVED(FEATURE);}
187#endif // SHARK_CORE_FLAGS_H