Device interface library for multiple platforms including Mbed.

Dependents:   DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FlagSet.hpp Source File

FlagSet.hpp

00001 /*******************************************************************************
00002 * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved.
00003 *
00004 * Permission is hereby granted, free of charge, to any person obtaining a
00005 * copy of this software and associated documentation files (the "Software"),
00006 * to deal in the Software without restriction, including without limitation
00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 * and/or sell copies of the Software, and to permit persons to whom the
00009 * Software is furnished to do so, subject to the following conditions:
00010 *
00011 * The above copyright notice and this permission notice shall be included
00012 * in all copies or substantial portions of the Software.
00013 *
00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020 * OTHER DEALINGS IN THE SOFTWARE.
00021 *
00022 * Except as contained in this notice, the name of Maxim Integrated
00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024 * Products, Inc. Branding Policy.
00025 *
00026 * The mere transfer of this software does not imply any licenses
00027 * of trade secrets, proprietary technology, copyrights, patents,
00028 * trademarks, maskwork rights, or any other form of intellectual
00029 * property whatsoever. Maxim Integrated Products, Inc. retains all
00030 * ownership rights.
00031 *******************************************************************************/
00032 
00033 #ifndef MaximInterfaceCore_FlagSet_hpp
00034 #define MaximInterfaceCore_FlagSet_hpp
00035 
00036 #include <stddef.h>
00037 #include <bitset>
00038 
00039 namespace MaximInterfaceCore {
00040 
00041 /// @brief
00042 /// Provides functionality similar to std::bitset except using a bit flag,
00043 /// typically of an enum type, as the indexer.
00044 template <typename Flag, size_t flagBits> class FlagSet {
00045 public:
00046   class reference {
00047   public:
00048     reference(FlagSet & flagSet, Flag flag) : flagSet(&flagSet), flag(flag) {}
00049 
00050     reference & operator=(bool x) {
00051       flagSet->set(flag, x);
00052       return *this;
00053     }
00054 
00055     reference & operator=(const reference & x) {
00056       return operator=(static_cast<bool>(x));
00057     }
00058 
00059     operator bool() const { return flagSet->test(flag); }
00060 
00061     bool operator~() const { return !(*this); }
00062 
00063     reference & flip() {
00064       flagSet->flip(flag);
00065       return *this;
00066     }
00067 
00068   private:
00069     FlagSet * flagSet;
00070     Flag flag;
00071   };
00072 
00073   FlagSet() : bits() {}
00074 
00075   FlagSet(unsigned long val) : bits(val) {}
00076 
00077   template <typename CharT, typename Traits, typename Alloc>
00078   explicit FlagSet(
00079       const std::basic_string<CharT, Traits, Alloc> & str,
00080       typename std::basic_string<CharT, Traits, Alloc>::size_type pos = 0,
00081       typename std::basic_string<CharT, Traits, Alloc>::size_type n =
00082           std::basic_string<CharT, Traits, Alloc>::npos)
00083       : bits(str, pos, n) {}
00084 
00085   bool operator==(const FlagSet & rhs) const { return bits == rhs.bits; }
00086 
00087   bool operator!=(const FlagSet & rhs) const { return bits != rhs.bits; }
00088 
00089   /// @name Element access
00090   /// @{
00091 
00092   bool operator[](Flag flag) const { return test(flag); }
00093 
00094   reference operator[](Flag flag) { return reference(*this, flag); }
00095 
00096   bool test(Flag flag) const {
00097     const unsigned long rawFlag = static_cast<unsigned long>(flag);
00098     return (bits.to_ulong() & rawFlag) == rawFlag;
00099   }
00100 
00101   bool any() const { return bits.any(); }
00102 
00103   bool none() const { return bits.none(); }
00104 
00105   size_t count() const { return bits.count(); }
00106 
00107   /// @}
00108 
00109   /// @name Capacity
00110   /// @{
00111 
00112   size_t size() const { return bits.size(); }
00113 
00114   /// @}
00115 
00116   /// @name Modifiers
00117   /// @{
00118 
00119   FlagSet & operator&=(const FlagSet & other) {
00120     bits &= other.bits;
00121     return *this;
00122   }
00123 
00124   FlagSet & operator|=(const FlagSet & other) {
00125     bits |= other.bits;
00126     return *this;
00127   }
00128 
00129   FlagSet & operator^=(const FlagSet & other) {
00130     bits ^= other.bits;
00131     return *this;
00132   }
00133 
00134   FlagSet operator~() const { return FlagSet(*this).flip(); }
00135 
00136   FlagSet & set() {
00137     bits.set();
00138     return *this;
00139   }
00140 
00141   FlagSet & set(Flag flag, bool value = true) {
00142     const unsigned long rawFlag = static_cast<unsigned long>(flag);
00143     if (value) {
00144       bits |= rawFlag;
00145     } else {
00146       bits &= static_cast<unsigned long>(~rawFlag);
00147     }
00148     return *this;
00149   }
00150 
00151   FlagSet & reset() {
00152     bits.reset();
00153     return *this;
00154   }
00155 
00156   FlagSet & reset(Flag flag) { return set(flag, false); }
00157 
00158   FlagSet & flip() {
00159     bits.flip();
00160     return *this;
00161   }
00162 
00163   FlagSet & flip(Flag flag) {
00164     bits ^= static_cast<unsigned long>(flag);
00165     return *this;
00166   }
00167 
00168   /// @}
00169 
00170   /// @name Conversions
00171   /// @{
00172 
00173   template <typename CharT, typename Traits, typename Allocator>
00174   std::basic_string<CharT, Traits, Allocator> to_string() const {
00175     return bits.template to_string<CharT, Traits, Allocator>();
00176   }
00177 
00178   unsigned long to_ulong() const { return bits.to_ulong(); }
00179 
00180   /// @}
00181 
00182   template <typename CharT, typename Traits>
00183   friend std::basic_ostream<CharT, Traits> &
00184   operator<<(std::basic_ostream<CharT, Traits> & os, const FlagSet & x) {
00185     os << x.bits;
00186     return os;
00187   }
00188 
00189   template <typename CharT, class Traits>
00190   friend std::basic_istream<CharT, Traits> &
00191   operator>>(std::basic_istream<CharT, Traits> & is, FlagSet & x) {
00192     is >> x.bits;
00193     return is;
00194   }
00195 
00196 private:
00197   std::bitset<flagBits> bits;
00198 };
00199 
00200 template <typename Flag, size_t flagBits>
00201 FlagSet<Flag, flagBits> operator&(const FlagSet<Flag, flagBits> & lhs,
00202                                   const FlagSet<Flag, flagBits> & rhs) {
00203   return FlagSet<Flag, flagBits>(lhs) &= rhs;
00204 }
00205 
00206 template <typename Flag, size_t flagBits>
00207 FlagSet<Flag, flagBits> operator|(const FlagSet<Flag, flagBits> & lhs,
00208                                   const FlagSet<Flag, flagBits> & rhs) {
00209   return FlagSet<Flag, flagBits>(lhs) |= rhs;
00210 }
00211 
00212 template <typename Flag, size_t flagBits>
00213 FlagSet<Flag, flagBits> operator^(const FlagSet<Flag, flagBits> & lhs,
00214                                   const FlagSet<Flag, flagBits> & rhs) {
00215   return FlagSet<Flag, flagBits>(lhs) ^= rhs;
00216 }
00217 
00218 } // namespace MaximInterfaceCore
00219 
00220 #endif