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  * <http://shark-ml.org/>
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 
37 #include <shark/Core/Exception.h>
39 
40 namespace 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 ///
57 template<typename Flag>
58 class TypedFlags : public ISerializable {
59 public:
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 
99  inline TypedFlags<Flag> & operator|=(const TypedFlags<Flag>& flags ) {
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 
121 protected:
122  unsigned int m_flags;
123 };
124 
125 
126 ///
127 /// \brief Exception indicating the attempt to use a feature which is not supported
128 ///
129 template<class Feature>
131 public:
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  }
142 protected:
143  Feature m_feature;
144 };
145 
146 }
147 
148 namespace boost {
149 namespace serialization {
150 
151 template< typename T >
152 struct 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 \
161 typedef TypedFlags<Feature> Features;\
162 protected:\
163 Features m_features;\
164 public:\
165 const Features & features() const {\
166  return( m_features );\
167 }\
168 virtual void updateFeatures(){}\
169 typedef 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));\
177 throw 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));\
182 throw 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)\
186 if(!(this->features()&base_type::FEATURE)){SHARK_FEATURE_EXCEPTION_DERIVED(FEATURE);}
187 #endif // SHARK_CORE_FLAGS_H