Stefan Scholz / ETL
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bitset.h Source File

bitset.h

Go to the documentation of this file.
00001 ///\file
00002 
00003 /******************************************************************************
00004 The MIT License(MIT)
00005 
00006 Embedded Template Library.
00007 https://github.com/ETLCPP/etl
00008 http://www.etlcpp.com
00009 
00010 Copyright(c) 2014 jwellbelove
00011 
00012 Permission is hereby granted, free of charge, to any person obtaining a copy
00013 of this software and associated documentation files(the "Software"), to deal
00014 in the Software without restriction, including without limitation the rights
00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
00016 copies of the Software, and to permit persons to whom the Software is
00017 furnished to do so, subject to the following conditions :
00018 
00019 The above copyright notice and this permission notice shall be included in all
00020 copies or substantial portions of the Software.
00021 
00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00028 SOFTWARE.
00029 ******************************************************************************/
00030 
00031 #ifndef __ETL_BITSET__
00032 #define __ETL_BITSET__
00033 
00034 #include <algorithm>
00035 #include <iterator>
00036 #include <string.h>
00037 #include <stddef.h>
00038 #include <stdint.h>
00039 
00040 #include "platform.h "
00041 #include "integral_limits.h "
00042 #include "algorithm.h "
00043 #include "nullptr.h "
00044 #include "log.h "
00045 #include "exception.h "
00046 #include "integral_limits.h "
00047 #include "binary.h "
00048 
00049 #ifdef ETL_COMPILER_MICROSOFT
00050 #undef min
00051 #endif
00052 
00053 #include "error_handler.h "
00054 
00055 #if defined(ETL_COMPILER_KEIL)
00056 #pragma diag_suppress 1300
00057 #endif
00058 
00059 //*****************************************************************************
00060 ///\defgroup bitset bitset
00061 /// Similar to std::bitset but without requiring std::string.
00062 ///\ingroup containers
00063 //*****************************************************************************
00064 
00065 namespace etl
00066 {
00067   //***************************************************************************
00068   /// Exception base for bitset
00069   ///\ingroup bitset
00070   //***************************************************************************
00071   class bitset_exception : public etl::exception
00072   {
00073   public:
00074 
00075     bitset_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
00076       : exception(reason_, file_name_, line_number_)
00077     {
00078     }
00079   };
00080 
00081   //***************************************************************************
00082   /// Bitset nullptr exception.
00083   ///\ingroup bitset
00084   //***************************************************************************
00085   class bitset_nullptr : public bitset_exception
00086   {
00087   public:
00088 
00089     bitset_nullptr(string_type file_name_, numeric_type line_number_)
00090       : bitset_exception("bitset: nullptr", file_name_, line_number_)
00091     {
00092     }
00093   };
00094 
00095   //*************************************************************************
00096   /// The base class for etl::bitset
00097   ///\ingroup bitset
00098   //*************************************************************************
00099   class ibitset
00100   {
00101   protected:
00102 
00103     // The type used for each element in the array.
00104 #if !defined(ETL_BITSET_ELEMENT_TYPE)
00105     typedef uint_least8_t element_t;
00106 #else
00107     typedef ETL_BITSET_ELEMENT_TYPE element_t;
00108 #endif
00109 
00110   public:
00111 
00112     static const element_t ALL_SET = etl::integral_limits<element_t>::max;
00113     static const element_t ALL_CLEAR = 0;
00114 
00115     static const size_t    BITS_PER_ELEMENT = etl::integral_limits<element_t>::bits;
00116 
00117     enum
00118     {
00119       npos = etl::integral_limits<size_t>::max
00120     };
00121 
00122     //*************************************************************************
00123     /// The reference type returned.
00124     //*************************************************************************
00125     class bit_reference
00126     {
00127     public:
00128 
00129       friend class ibitset;
00130 
00131       //*******************************
00132       /// Conversion operator.
00133       //*******************************
00134       operator bool() const
00135       {
00136         return p_bitset->test(position);
00137       }
00138 
00139       //*******************************
00140       /// Assignment operator.
00141       //*******************************
00142       bit_reference& operator = (bool b)
00143       {
00144         p_bitset->set(position, b);
00145         return *this;
00146       }
00147 
00148       //*******************************
00149       /// Assignment operator.
00150       //*******************************
00151       bit_reference& operator = (const bit_reference& r)
00152       {
00153         p_bitset->set(position, bool(r));
00154         return *this;
00155       }
00156 
00157       //*******************************
00158       /// Flip the bit.
00159       //*******************************
00160       bit_reference& flip()
00161       {
00162         p_bitset->flip(position);
00163         return *this;
00164       }
00165 
00166       //*******************************
00167       /// Return the logical inverse of the bit.
00168       //*******************************
00169       bool operator~() const
00170       {
00171         return !p_bitset->test(position);
00172       }
00173 
00174     private:
00175 
00176       //*******************************
00177       /// Default constructor.
00178       //*******************************
00179       bit_reference()
00180         : p_bitset(std::nullptr),
00181         position(0)
00182       {
00183       }
00184 
00185       //*******************************
00186       /// Constructor.
00187       //*******************************
00188       bit_reference(ibitset& r_bitset, size_t position_)
00189         : p_bitset(&r_bitset),
00190         position(position_)
00191       {
00192       }
00193 
00194       ibitset* p_bitset; ///< The bitset.
00195       size_t   position; ///< The position in the bitset.
00196     };
00197 
00198     //*************************************************************************
00199     /// The size of the bitset.
00200     //*************************************************************************
00201     size_t size() const
00202     {
00203       return NBITS;
00204     }
00205 
00206     //*************************************************************************
00207     /// Count the number of bits set.
00208     //*************************************************************************
00209     size_t count() const
00210     {
00211       size_t n = 0;
00212 
00213       for (size_t i = 0; i < SIZE; ++i)
00214       {
00215         n += etl::count_bits(pdata[i]);
00216       }
00217 
00218       return n;
00219     }
00220 
00221     //*************************************************************************
00222     /// Tests a bit at a position.
00223     /// Positions greater than the number of configured bits will return <b>false</b>.
00224     //*************************************************************************
00225     bool test(size_t position) const
00226     {
00227       size_t       index;
00228       element_t mask;
00229 
00230       if (SIZE == 1)
00231       {
00232         index = 0;
00233         mask = element_t(1) << position;
00234       }
00235       else
00236       {
00237         index = position >> etl::log2<BITS_PER_ELEMENT>::value;
00238         mask = element_t(1) << (position & (BITS_PER_ELEMENT - 1));
00239       }
00240 
00241       return (pdata[index] & mask) != 0;
00242     }
00243 
00244     //*************************************************************************
00245     /// Set the bit at the position.
00246     //*************************************************************************
00247     ibitset& set()
00248     {
00249       for (size_t i = 0; i < SIZE; ++i)
00250       {
00251         pdata[i] = ALL_SET;
00252       }
00253 
00254       pdata[SIZE - 1] &= TOP_MASK;
00255 
00256       return *this;
00257     }
00258 
00259     //*************************************************************************
00260     /// Set the bit at the position.
00261     //*************************************************************************
00262     ibitset& set(size_t position, bool value = true)
00263     {
00264       size_t    index;
00265       element_t bit;
00266 
00267       if (SIZE == 1)
00268       {
00269         index = 0;
00270         bit = element_t(1) << position;
00271       }
00272       else
00273       {
00274         index = position >> etl::log2<BITS_PER_ELEMENT>::value;
00275         bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1));
00276       }
00277 
00278       if (value)
00279       {
00280         pdata[index] |= bit;
00281       }
00282       else
00283       {
00284         pdata[index] &= ~bit;
00285       }
00286 
00287       return *this;
00288     }
00289 
00290     //*************************************************************************
00291     /// Set from a string.
00292     //*************************************************************************
00293     ibitset& set(const char* text)
00294     {
00295       reset();
00296 
00297       size_t i = std::min(NBITS, strlen(text));
00298 
00299       while (i > 0)
00300       {
00301         set(--i, *text++ == '1');
00302       }
00303 
00304       return *this;
00305     }
00306 
00307     //*************************************************************************
00308     /// Resets the bitset.
00309     //*************************************************************************
00310     ibitset& reset()
00311     {
00312       for (size_t i = 0; i < SIZE; ++i)
00313       {
00314         pdata[i] = ALL_CLEAR;
00315       }
00316 
00317       return *this;
00318     }
00319 
00320     //*************************************************************************
00321     /// Reset the bit at the position.
00322     //*************************************************************************
00323     ibitset& reset(size_t position)
00324     {
00325       size_t       index;
00326       element_t bit;
00327 
00328       if (SIZE == 1)
00329       {
00330         index = 0;
00331         bit = element_t(1) << position;
00332       }
00333       else
00334       {
00335         index = position >> etl::log2<BITS_PER_ELEMENT>::value;
00336         bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1));
00337       }
00338 
00339       pdata[index] &= ~bit;
00340 
00341       return *this;
00342     }
00343 
00344     //*************************************************************************
00345     /// Flip all of the bits.
00346     //*************************************************************************
00347     ibitset& flip()
00348     {
00349       for (size_t i = 0; i < SIZE; ++i)
00350       {
00351         pdata[i] = ~pdata[i];
00352       }
00353 
00354       pdata[SIZE - 1] &= TOP_MASK;
00355 
00356       return *this;
00357     }
00358 
00359     //*************************************************************************
00360     /// Flip the bit at the position.
00361     //*************************************************************************
00362     ibitset& flip(size_t position)
00363     {
00364       if (position < NBITS)
00365       {
00366         size_t    index;
00367         element_t bit;
00368 
00369         if (SIZE == 1)
00370         {
00371           index = 0;
00372           bit = element_t(1) << position;
00373         }
00374         else
00375         {
00376           index = position >> log2<BITS_PER_ELEMENT>::value;
00377           bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1));
00378         }
00379 
00380         pdata[index] ^= bit;
00381       }
00382 
00383       return *this;
00384     }
00385 
00386     //*************************************************************************
00387     // Are all the bits sets?
00388     //*************************************************************************
00389     bool all() const
00390     {
00391       // All but the last.
00392       for (size_t i = 0; i < (SIZE - 1); ++i)
00393       {
00394         if (pdata[i] != ALL_SET)
00395         {
00396           return false;
00397         }
00398       }
00399 
00400       // The last.
00401       if (pdata[SIZE - 1] != (ALL_SET & TOP_MASK))
00402       {
00403         return false;
00404       }
00405 
00406       return true;
00407     }
00408 
00409     //*************************************************************************
00410     /// Are any of the bits set?
00411     //*************************************************************************
00412     bool any() const
00413     {
00414       return !none();
00415     }
00416 
00417     //*************************************************************************
00418     /// Are none of the bits set?
00419     //*************************************************************************
00420     bool none() const
00421     {
00422       for (size_t i = 0; i < SIZE; ++i)
00423       {
00424         if (pdata[i] != 0)
00425         {
00426           return false;
00427         }
00428       }
00429 
00430       return true;
00431     }
00432 
00433     //*************************************************************************
00434     /// Finds the first bit in the specified state.
00435     ///\param state The state to search for.
00436     ///\returns The position of the bit or SIZE if none were found.
00437     //*************************************************************************
00438     size_t find_first(bool state) const
00439     {
00440       return find_next(state, 0);
00441     }
00442 
00443     //*************************************************************************
00444     /// Finds the next bit in the specified state.
00445     ///\param state    The state to search for.
00446     ///\param position The position to start from.
00447     ///\returns The position of the bit or SIZE if none were found.
00448     //*************************************************************************
00449     size_t find_next(bool state, size_t position) const
00450     {
00451       // Where to start.
00452       size_t index;
00453       size_t bit;
00454 
00455       if (SIZE == 1)
00456       {
00457         index = 0;
00458         bit = position;
00459       }
00460       else
00461       {
00462         index = position >> log2<BITS_PER_ELEMENT>::value;
00463         bit = position & (BITS_PER_ELEMENT - 1);
00464       }
00465 
00466       element_t mask = 1 << bit;
00467 
00468       // For each element in the bitset...
00469       while (index < SIZE)
00470       {
00471         element_t value = pdata[index];
00472 
00473         // Needs checking?
00474         if ((state && (value != ALL_CLEAR)) ||
00475           (!state && (value != ALL_SET)))
00476         {
00477           // For each bit in the element...
00478           while ((bit < BITS_PER_ELEMENT) && (position < NBITS))
00479           {
00480             // Equal to the required state?
00481             if (((value & mask) != 0) == state)
00482             {
00483               return position;
00484             }
00485 
00486             // Move on to the next bit.
00487             mask <<= 1;
00488             ++position;
00489             ++bit;
00490           }
00491         }
00492         else
00493         {
00494           position += BITS_PER_ELEMENT;
00495         }
00496 
00497         // Start at the beginning for all other elements.
00498         bit = 0;
00499         mask = 1;
00500 
00501         ++index;
00502       }
00503 
00504       return ibitset::npos;
00505     }
00506 
00507     //*************************************************************************
00508     /// Read [] operator.
00509     //*************************************************************************
00510     bool operator[] (size_t position) const
00511     {
00512       return test(position);
00513     }
00514 
00515     //*************************************************************************
00516     /// Write [] operator.
00517     //*************************************************************************
00518     bit_reference operator [] (size_t position)
00519     {
00520       return bit_reference(*this, position);
00521     }
00522 
00523     //*************************************************************************
00524     /// operator &=
00525     //*************************************************************************
00526     ibitset& operator &=(const ibitset& other)
00527     {
00528       for (size_t i = 0; i < SIZE; ++i)
00529       {
00530         pdata[i] &= other.pdata[i];
00531       }
00532 
00533       return *this;
00534     }
00535 
00536     //*************************************************************************
00537     /// operator |=
00538     //*************************************************************************
00539     ibitset& operator |=(const ibitset& other)
00540     {
00541       for (size_t i = 0; i < SIZE; ++i)
00542       {
00543         pdata[i] |= other.pdata[i];
00544       }
00545 
00546       return *this;
00547     }
00548 
00549     //*************************************************************************
00550     /// operator ^=
00551     //*************************************************************************
00552     ibitset& operator ^=(const ibitset& other)
00553     {
00554       for (size_t i = 0; i < SIZE; ++i)
00555       {
00556         pdata[i] ^= other.pdata[i];
00557       }
00558 
00559       return *this;
00560     }
00561 
00562     //*************************************************************************
00563     /// operator <<=
00564     //*************************************************************************
00565     ibitset& operator<<=(size_t shift)
00566     {
00567       if (SIZE == 1)
00568       {
00569         pdata[0] <<= shift;
00570       }
00571       else
00572       {
00573         size_t source = NBITS - shift - 1;
00574         size_t destination = NBITS - 1;
00575 
00576         for (size_t i = 0; i < (NBITS - shift); ++i)
00577         {
00578           set(destination--, test(source--));
00579         }
00580 
00581         for (size_t i = 0; i < shift; ++i)
00582         {
00583           reset(destination--);
00584         }
00585       }
00586 
00587       return *this;
00588     }
00589 
00590     //*************************************************************************
00591     /// operator >>=
00592     //*************************************************************************
00593     ibitset& operator>>=(size_t shift)
00594     {
00595       if (SIZE == 1)
00596       {
00597         pdata[0] >>= shift;
00598       }
00599       else
00600       {
00601         size_t source = shift;
00602         size_t destination = 0;
00603 
00604         for (size_t i = 0; i < (NBITS - shift); ++i)
00605         {
00606           set(destination++, test(source++));
00607         }
00608 
00609         for (size_t i = 0; i < shift; ++i)
00610         {
00611           reset(destination++);
00612         }
00613       }
00614 
00615       return *this;
00616     }
00617 
00618     //*************************************************************************
00619     /// operator =
00620     //*************************************************************************
00621     ibitset& operator =(const ibitset& other)
00622     {
00623       if (this != &other)
00624       {
00625         etl::copy_n(other.pdata, SIZE, pdata);
00626       }
00627 
00628       return *this;
00629     }
00630 
00631     //*************************************************************************
00632     /// swap
00633     //*************************************************************************
00634     void swap(ibitset& other)
00635     {
00636       std::swap_ranges(pdata, pdata + SIZE, other.pdata);
00637     }
00638 
00639   protected:
00640 
00641     //*************************************************************************
00642     /// Initialise from an unsigned long long.
00643     //*************************************************************************
00644     ibitset& initialise(unsigned long long value)
00645     {
00646       reset();
00647 
00648       const size_t SHIFT = (integral_limits<unsigned long long>::bits <= (int)BITS_PER_ELEMENT) ? 0 : BITS_PER_ELEMENT;
00649 
00650       // Can we do it in one hit?
00651       if (SHIFT == 0)
00652       {
00653         pdata[0] = element_t(value);
00654       }
00655       else
00656       {
00657         size_t i = 0;
00658 
00659         while ((value != 0) && (i < SIZE))
00660         {
00661           pdata[i++] = value & ALL_SET;
00662           value = value >> SHIFT;
00663         }
00664       }
00665 
00666       pdata[SIZE - 1] &= TOP_MASK;
00667 
00668       return *this;
00669     }
00670 
00671     //*************************************************************************
00672     /// Invert
00673     //*************************************************************************
00674     void invert()
00675     {
00676       for (size_t i = 0; i < SIZE; ++i)
00677       {
00678         pdata[i] = ~pdata[i];
00679       }
00680     }
00681 
00682     //*************************************************************************
00683     /// Gets a reference to the specified bit.
00684     //*************************************************************************
00685     bit_reference get_bit_reference(size_t position)
00686     {
00687       return bit_reference(*this, position);
00688     }
00689 
00690     //*************************************************************************
00691     /// Constructor.
00692     //*************************************************************************
00693     ibitset(size_t nbits_, size_t size_, element_t* pdata_)
00694       : NBITS(nbits_),
00695         SIZE(size_),
00696         pdata(pdata_)
00697     {
00698       size_t allocated_bits = SIZE * BITS_PER_ELEMENT;
00699       size_t top_mask_shift = ((BITS_PER_ELEMENT - (allocated_bits - NBITS)) % BITS_PER_ELEMENT);
00700       TOP_MASK = element_t(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift));
00701     }
00702 
00703     //*************************************************************************
00704     /// Compare bitsets.
00705     //*************************************************************************
00706     static bool is_equal(const ibitset& lhs, const ibitset&rhs)
00707     {
00708       return std::equal(lhs.pdata, lhs.pdata + lhs.SIZE, rhs.pdata);
00709     }
00710 
00711     element_t TOP_MASK;
00712 
00713   private:
00714 
00715     // Disable copy construction.
00716     ibitset(const ibitset&);
00717 
00718     const size_t NBITS;
00719     const size_t SIZE;
00720     element_t*   pdata;
00721   };
00722 
00723   //*************************************************************************
00724   /// The class emulates an array of bool elements, but optimized for space allocation.
00725   /// Will accommodate any number of bits.
00726   /// Does not use std::string.
00727   ///\tparam N The number of bits.
00728   ///\ingroup bitset
00729   //*************************************************************************
00730   template <const size_t MAXN>
00731   class bitset : public etl::ibitset
00732   {
00733 
00734     static const size_t ARRAY_SIZE = (MAXN % BITS_PER_ELEMENT == 0) ? MAXN / BITS_PER_ELEMENT : MAXN / BITS_PER_ELEMENT + 1;
00735 
00736   public:
00737 
00738     static const size_t ALLOCATED_BITS = ARRAY_SIZE * BITS_PER_ELEMENT;
00739 
00740   public:
00741 
00742     //*************************************************************************
00743     /// Default constructor.
00744     //*************************************************************************
00745     bitset()
00746       : etl::ibitset(MAXN, ARRAY_SIZE, data)
00747     {
00748       reset();
00749     }
00750 
00751     //*************************************************************************
00752     /// Copy constructor.
00753     //*************************************************************************
00754     bitset(const bitset<MAXN>& other)
00755       : etl::ibitset(MAXN, ARRAY_SIZE, data)
00756     {
00757       etl::copy_n(other.data, ARRAY_SIZE, data);
00758     }
00759 
00760     //*************************************************************************
00761     /// Construct from a value.
00762     //*************************************************************************
00763     bitset(unsigned long long value)
00764       : etl::ibitset(MAXN, ARRAY_SIZE, data)
00765     {
00766       initialise(value);
00767     }
00768 
00769     //*************************************************************************
00770     /// Construct from a string.
00771     //*************************************************************************
00772     bitset(const char* text)
00773       : etl::ibitset(MAXN, ARRAY_SIZE, data)
00774     {
00775       set(text);
00776     }
00777 
00778     //*************************************************************************
00779     /// Set all of the bits.
00780     //*************************************************************************
00781     bitset<MAXN>& set()
00782     {
00783       etl::ibitset::set();
00784       return *this;
00785     }
00786 
00787     //*************************************************************************
00788     /// Set the bit at the position.
00789     //*************************************************************************
00790     bitset<MAXN>& set(size_t position, bool value = true)
00791     {
00792       etl::ibitset::set(position, value);
00793       return *this;
00794     }
00795 
00796     //*************************************************************************
00797     /// Set from a string.
00798     //*************************************************************************
00799     bitset<MAXN>& set(const char* text)
00800     {
00801       ETL_ASSERT(text != 0, ETL_ERROR(bitset_nullptr));
00802       etl::ibitset::set(text);
00803 
00804       return *this;
00805     }
00806 
00807     //*************************************************************************
00808     /// Reset all of the bits.
00809     //*************************************************************************
00810     bitset<MAXN>& reset()
00811     {
00812       ibitset::reset();
00813       return *this;
00814     }
00815 
00816     //*************************************************************************
00817     /// Reset the bit at the position.
00818     //*************************************************************************
00819     bitset<MAXN>& reset(size_t position)
00820     {
00821       etl::ibitset::reset(position);
00822       return *this;
00823     }
00824 
00825     //*************************************************************************
00826     /// Flip all of the bits.
00827     //*************************************************************************
00828     bitset<MAXN>& flip()
00829     {
00830       ibitset::flip();
00831       return *this;
00832     }
00833 
00834     //*************************************************************************
00835     /// Flip the bit at the position.
00836     //*************************************************************************
00837     bitset<MAXN>& flip(size_t position)
00838     {
00839       etl::ibitset::flip(position);
00840       return *this;
00841     }
00842 
00843     //*************************************************************************
00844     /// operator =
00845     //*************************************************************************
00846     bitset<MAXN>& operator =(const bitset<MAXN>& other)
00847     {
00848       if (this != &other)
00849       {
00850         etl::copy_n(other.data, ARRAY_SIZE, data);
00851       }
00852 
00853       return *this;
00854     }
00855 
00856     //*************************************************************************
00857     /// operator &=
00858     //*************************************************************************
00859     bitset<MAXN>& operator &=(const bitset<MAXN>& other)
00860     {
00861       etl::ibitset::operator &=(other);
00862       return *this;
00863     }
00864 
00865     //*************************************************************************
00866     /// operator |=
00867     //*************************************************************************
00868     bitset<MAXN>& operator |=(const bitset<MAXN>& other)
00869     {
00870       etl::ibitset::operator |=(other);
00871       return *this;
00872     }
00873 
00874     //*************************************************************************
00875     /// operator ^=
00876     //*************************************************************************
00877     bitset<MAXN>& operator ^=(const bitset<MAXN>& other)
00878     {
00879       ibitset::operator ^=(other);
00880       return *this;
00881     }
00882 
00883     //*************************************************************************
00884     /// operator ~
00885     //*************************************************************************
00886     bitset<MAXN> operator ~() const
00887     {
00888       etl::bitset<MAXN> temp(*this);
00889 
00890       temp.invert();
00891 
00892       return temp;
00893     }
00894 
00895     //*************************************************************************
00896     /// operator <<
00897     //*************************************************************************
00898     bitset<MAXN> operator<<(size_t shift) const
00899     {
00900       etl::bitset<MAXN> temp(*this);
00901 
00902       temp <<= shift;
00903 
00904       return temp;
00905     }
00906 
00907     //*************************************************************************
00908     /// operator <<=
00909     //*************************************************************************
00910     bitset<MAXN>& operator<<=(size_t shift)
00911     {
00912       etl::ibitset::operator <<=(shift);
00913       return *this;
00914     }
00915 
00916     //*************************************************************************
00917     /// operator >>
00918     //*************************************************************************
00919     bitset<MAXN> operator>>(size_t shift) const
00920     {
00921       bitset<MAXN> temp(*this);
00922 
00923       temp >>= shift;
00924 
00925       return temp;
00926     }
00927 
00928     //*************************************************************************
00929     /// operator >>=
00930     //*************************************************************************
00931     bitset<MAXN>& operator>>=(size_t shift)
00932     {
00933       etl::ibitset::operator >>=(shift);
00934       return *this;
00935     }
00936 
00937     //*************************************************************************
00938     /// operator ==
00939     //*************************************************************************
00940     friend bool operator == (const bitset<MAXN>& lhs, const bitset<MAXN>& rhs)
00941     {
00942       return etl::ibitset::is_equal(lhs, rhs);
00943     }
00944 
00945   private:
00946 
00947     element_t data[ARRAY_SIZE];
00948   };
00949 
00950   //***************************************************************************
00951   /// operator &
00952   ///\ingroup bitset
00953   //***************************************************************************
00954   template <const size_t MAXN>
00955   bitset<MAXN> operator & (const bitset<MAXN>& lhs, const bitset<MAXN>& rhs)
00956   {
00957     bitset<MAXN> temp(lhs);
00958     temp &= rhs;
00959     return temp;
00960   }
00961 
00962   //***************************************************************************
00963   /// operator |
00964   ///\ingroup bitset
00965   //***************************************************************************
00966   template<const size_t MAXN>
00967   bitset<MAXN> operator | (const bitset<MAXN>& lhs, const bitset<MAXN>& rhs)
00968   {
00969     bitset<MAXN> temp(lhs);
00970     temp |= rhs;
00971     return temp;
00972   }
00973 
00974   //***************************************************************************
00975   /// operator ^
00976   ///\ingroup bitset
00977   //***************************************************************************
00978   template<const size_t MAXN>
00979   bitset<MAXN> operator ^ (const bitset<MAXN>& lhs, const bitset<MAXN>& rhs)
00980   {
00981     bitset<MAXN> temp(lhs);
00982     temp ^= rhs;
00983     return temp;
00984   }
00985 
00986   //***************************************************************************
00987   /// operator !=
00988   ///\ingroup bitset
00989   //***************************************************************************
00990   template<const size_t MAXN>
00991   bool operator != (const bitset<MAXN>& lhs, const bitset<MAXN>& rhs)
00992   {
00993     return !(lhs == rhs);
00994   }
00995 }
00996 
00997 //*************************************************************************
00998 /// swap
00999 //*************************************************************************
01000 template <const size_t MAXN>
01001 void swap(etl::bitset<MAXN>& lhs, etl::bitset<MAXN>& rhs)
01002 {
01003   lhs.swap(rhs);
01004 }
01005 
01006 #ifdef ETL_COMPILER_MICROSOFT
01007 #define min(a,b) (((a) < (b)) ? (a) : (b))
01008 #endif
01009 
01010 #endif
01011