Aleksandrs Gumenuks / MaximInterface_Extended

Dependents:   mbed_DS28EC20_GPIO

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FlagSet.hpp Source File

FlagSet.hpp

00001 /*******************************************************************************
00002 * Copyright (C) 2017 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 MaximInterface_FlagSet
00034 #define MaximInterface_FlagSet
00035 
00036 #include <stddef.h>
00037 #include <bitset>
00038 
00039 namespace MaximInterface {
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 reference(*this).flip(); }
00062     
00063     reference & flip() {
00064       *this = !*this;
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 !operator==(rhs); }
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 { return (bits.to_ulong() & flag) == flag; }
00097   
00098   bool any() const { return bits.any(); }
00099   
00100   bool none() const { return bits.none(); }
00101   
00102   size_t count() const { return bits.count(); }
00103   
00104   /// @}
00105 
00106   /// @name Capacity
00107   /// @{
00108   
00109   size_t size() const { return bits.size(); }
00110   
00111   /// @}
00112 
00113   /// @name Modifiers
00114   /// @{
00115   
00116   FlagSet & operator&=(const FlagSet & other) {
00117     bits &= other.bits;
00118     return *this;
00119   }
00120   
00121   FlagSet & operator|=(const FlagSet & other) {
00122     bits |= other.bits;
00123     return *this;
00124   }
00125   
00126   FlagSet & operator^=(const FlagSet & other) {
00127     bits ^= other.bits;
00128     return *this;
00129   }
00130   
00131   FlagSet operator~() const { return ~bits; }
00132 
00133   FlagSet & set() {
00134     bits.set();
00135     return *this;
00136   }
00137   
00138   FlagSet & set(Flag flag, bool value = true) {
00139     if (value) {
00140       bits |= flag;
00141     } else {
00142       bits &= ~std::bitset<flagBits>(flag);
00143     }
00144     return *this;
00145   }
00146   
00147   FlagSet & reset() {
00148     bits.reset();
00149     return *this;
00150   }
00151   
00152   FlagSet & reset(Flag flag) { return set(flag, false); }
00153   
00154   FlagSet & flip() {
00155     bits.flip();
00156     return *this;
00157   }
00158   
00159   FlagSet & flip(Flag flag) {
00160     bits ^= flag;
00161     return *this;
00162   }
00163   
00164   /// @}
00165 
00166   /// @name Conversions
00167   /// @{
00168   
00169   template <typename CharT, typename Traits, typename Allocator>
00170   std::basic_string<CharT, Traits, Allocator> to_string() const {
00171     return bits.template to_string<CharT, Traits, Allocator>();
00172   }
00173   
00174   unsigned long to_ulong() const { return bits.to_ulong(); }
00175   
00176   /// @}
00177 
00178 private:
00179   std::bitset<flagBits> bits;
00180 
00181   template <typename CharT, typename Traits>
00182   friend std::basic_ostream<CharT, Traits> &
00183   operator<<(std::basic_ostream<CharT, Traits> & os, const FlagSet & x);
00184 
00185   template <typename CharT, class Traits>
00186   friend std::basic_istream<CharT, Traits> &
00187   operator>>(std::basic_istream<CharT, Traits> & is, FlagSet & x);
00188 };
00189 
00190 template <typename Flag, size_t flagBits>
00191 FlagSet<Flag, flagBits> operator&(const FlagSet<Flag, flagBits> & lhs,
00192                                   const FlagSet<Flag, flagBits> & rhs) {
00193   return FlagSet<Flag, flagBits>(lhs) &= rhs;
00194 }
00195 
00196 template <typename Flag, size_t flagBits>
00197 FlagSet<Flag, flagBits> operator|(const FlagSet<Flag, flagBits> & lhs,
00198                                   const FlagSet<Flag, flagBits> & rhs) {
00199   return FlagSet<Flag, flagBits>(lhs) |= rhs;
00200 }
00201 
00202 template <typename Flag, size_t flagBits>
00203 FlagSet<Flag, flagBits> operator^(const FlagSet<Flag, flagBits> & lhs,
00204                                   const FlagSet<Flag, flagBits> & rhs) {
00205   return FlagSet<Flag, flagBits>(lhs) ^= rhs;
00206 }
00207 
00208 template <typename CharT, typename Traits, typename Flag, size_t flagBits>
00209 std::basic_ostream<CharT, Traits> &
00210 operator<<(std::basic_ostream<CharT, Traits> & os,
00211            const FlagSet<Flag, flagBits> & x) {
00212   os << x.bits;
00213   return os;
00214 }
00215 
00216 template <typename CharT, class Traits, typename Flag, size_t flagBits>
00217 std::basic_istream<CharT, Traits> &
00218 operator>>(std::basic_istream<CharT, Traits> & is,
00219            FlagSet<Flag, flagBits> & x) {
00220   is >> x.bits;
00221   return is;
00222 }
00223 
00224 } // namespace MaximInterface
00225 
00226 #endif