Stefan Scholz / ETL
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers reference_flat_multiset.h Source File

reference_flat_multiset.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) 2017 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_REFERENCE_FLAT_MULTISET__
00032 #define __ETL_REFERENCE_FLAT_MULTISET__
00033 
00034 #include <iterator>
00035 #include <algorithm>
00036 #include <functional>
00037 #include <utility>
00038 #include <stddef.h>
00039 
00040 #include "platform.h "
00041 #include "type_traits.h "
00042 #include "vector.h "
00043 #include "pool.h "
00044 #include "error_handler.h "
00045 #include "exception.h "
00046 
00047 #undef ETL_FILE
00048 #define ETL_FILE "33"
00049 
00050 namespace etl
00051 {
00052   //***************************************************************************
00053   ///\ingroup reference_flat_multiset
00054   /// Exception base for reference_flat_multisets
00055   //***************************************************************************
00056   class flat_multiset_exception : public exception
00057   {
00058   public:
00059 
00060     flat_multiset_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
00061       : exception(reason_, file_name_, line_number_)
00062     {
00063     }
00064   };
00065 
00066   //***************************************************************************
00067   ///\ingroup reference_flat_multiset
00068   /// Vector full exception.
00069   //***************************************************************************
00070   class flat_multiset_full : public flat_multiset_exception
00071   {
00072   public:
00073 
00074     flat_multiset_full(string_type file_name_, numeric_type line_number_)
00075       : flat_multiset_exception(ETL_ERROR_TEXT("flat_multiset:full", ETL_FILE"A"), file_name_, line_number_)
00076     {
00077     }
00078   };
00079 
00080   //***************************************************************************
00081   ///\ingroup reference_flat_multiset
00082   /// Vector iterator exception.
00083   //***************************************************************************
00084   class flat_multiset_iterator : public flat_multiset_exception
00085   {
00086   public:
00087 
00088     flat_multiset_iterator(string_type file_name_, numeric_type line_number_)
00089       : flat_multiset_exception(ETL_ERROR_TEXT("flat_multiset:iterator", ETL_FILE"C"), file_name_, line_number_)
00090     {
00091     }
00092   };
00093 
00094   //***************************************************************************
00095   /// The base class for specifically sized reference_flat_multisets.
00096   /// Can be used as a reference type for all reference_flat_multisets containing a specific type.
00097   ///\ingroup reference_flat_multiset
00098   //***************************************************************************
00099   template <typename T, typename TKeyCompare = std::less<T> >
00100   class ireference_flat_multiset
00101   {
00102   public:
00103 
00104     typedef T                 key_type;
00105     typedef T                 value_type;
00106     typedef TKeyCompare       key_compare;
00107     typedef value_type&       reference;
00108     typedef const value_type& const_reference;
00109     typedef value_type*       pointer;
00110     typedef const value_type* const_pointer;
00111     typedef size_t            size_type;
00112 
00113   protected:
00114 
00115     typedef etl::ivector<value_type*>  lookup_t ;
00116 
00117   public:
00118 
00119     //*************************************************************************
00120     class iterator : public std::iterator<std::bidirectional_iterator_tag, value_type>
00121     {
00122     public:
00123 
00124       friend class ireference_flat_multiset;
00125 
00126       iterator()
00127       {
00128       }
00129 
00130       iterator(typename lookup_t::iterator ilookup_)
00131         : ilookup(ilookup_)
00132       {
00133       }
00134 
00135       iterator(const iterator& other)
00136         : ilookup(other.ilookup)
00137       {
00138       }
00139 
00140       iterator& operator =(const iterator& other)
00141       {
00142         ilookup = other.ilookup;
00143         return *this;
00144       }
00145 
00146       iterator& operator ++()
00147       {
00148         ++ilookup;
00149         return *this;
00150       }
00151 
00152       iterator operator ++(int)
00153       {
00154         iterator temp(*this);
00155         ++ilookup;
00156         return temp;
00157       }
00158 
00159       iterator& operator --()
00160       {
00161         --ilookup;
00162         return *this;
00163       }
00164 
00165       iterator operator --(int)
00166       {
00167         iterator temp(*this);
00168         --ilookup;
00169         return temp;
00170       }
00171 
00172       reference operator *()
00173       {
00174         return *(*ilookup);
00175       }
00176 
00177       const_reference operator *() const
00178       {
00179         return *(*ilookup);
00180       }
00181 
00182       pointer operator &()
00183       {
00184         return etl::addressof(*(*ilookup));
00185       }
00186 
00187       const_pointer operator &() const
00188       {
00189         return &(*(*ilookup));
00190       }
00191 
00192       pointer operator ->()
00193       {
00194         return etl::addressof(*(*ilookup));
00195       }
00196 
00197       const_pointer operator ->() const
00198       {
00199         return etl::addressof(*(*ilookup));
00200       }
00201 
00202       friend bool operator == (const iterator& lhs, const iterator& rhs)
00203       {
00204         return lhs.ilookup == rhs.ilookup;
00205       }
00206 
00207       friend bool operator != (const iterator& lhs, const iterator& rhs)
00208       {
00209         return !(lhs == rhs);
00210       }
00211 
00212     private:
00213 
00214       typename lookup_t::iterator ilookup;
00215     };
00216 
00217     //*************************************************************************
00218     class const_iterator : public std::iterator<std::bidirectional_iterator_tag, const value_type>
00219     {
00220     public:
00221 
00222       friend class ireference_flat_multiset;
00223 
00224       const_iterator()
00225       {
00226       }
00227 
00228       const_iterator(typename lookup_t::const_iterator ilookup_)
00229         : ilookup(ilookup_)
00230       {
00231       }
00232 
00233       const_iterator(const iterator& other)
00234         : ilookup(other.ilookup)
00235       {
00236       }
00237 
00238       const_iterator(const const_iterator& other)
00239         : ilookup(other.ilookup)
00240       {
00241       }
00242 
00243       const_iterator& operator =(const iterator& other)
00244       {
00245         ilookup = other.ilookup;
00246         return *this;
00247       }
00248 
00249       const_iterator& operator =(const const_iterator& other)
00250       {
00251         ilookup = other.ilookup;
00252         return *this;
00253       }
00254 
00255       const_iterator& operator ++()
00256       {
00257         ++ilookup;
00258         return *this;
00259       }
00260 
00261       const_iterator operator ++(int)
00262       {
00263         const_iterator temp(*this);
00264         ++ilookup;
00265         return temp;
00266       }
00267 
00268       const_iterator& operator --()
00269       {
00270         --ilookup;
00271         return *this;
00272       }
00273 
00274       const_iterator operator --(int)
00275       {
00276         const_iterator temp(*this);
00277         --ilookup;
00278         return temp;
00279       }
00280 
00281       const_reference operator *() const
00282       {
00283         return *(*ilookup);
00284       }
00285 
00286       const_pointer operator &() const
00287       {
00288         return etl::addressof(*(*ilookup));
00289       }
00290 
00291       const_pointer operator ->() const
00292       {
00293         return etl::addressof(*(*ilookup));
00294       }
00295 
00296       friend bool operator == (const const_iterator& lhs, const const_iterator& rhs)
00297       {
00298         return lhs.ilookup == rhs.ilookup;
00299       }
00300 
00301       friend bool operator != (const const_iterator& lhs, const const_iterator& rhs)
00302       {
00303         return !(lhs == rhs);
00304       }
00305 
00306     private:
00307 
00308       typename lookup_t::const_iterator ilookup;
00309     };
00310 
00311   protected:
00312 
00313     typedef typename etl::parameter_type<T>::type parameter_t;
00314 
00315   public:
00316 
00317     typedef std::reverse_iterator<iterator>       reverse_iterator;
00318     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00319     typedef typename std::iterator_traits<iterator>::difference_type difference_type;
00320 
00321     //*********************************************************************
00322     /// Returns an iterator to the beginning of the reference_flat_multiset.
00323     ///\return An iterator to the beginning of the reference_flat_multiset.
00324     //*********************************************************************
00325     iterator begin()
00326     {
00327       return iterator(lookup.begin());
00328     }
00329 
00330     //*********************************************************************
00331     /// Returns a const_iterator to the beginning of the reference_flat_multiset.
00332     ///\return A const iterator to the beginning of the reference_flat_multiset.
00333     //*********************************************************************
00334     const_iterator begin() const
00335     {
00336       return const_iterator(lookup.begin());
00337     }
00338 
00339     //*********************************************************************
00340     /// Returns an iterator to the end of the reference_flat_multiset.
00341     ///\return An iterator to the end of the reference_flat_multiset.
00342     //*********************************************************************
00343     iterator end()
00344     {
00345       return iterator(lookup.end());
00346     }
00347 
00348     //*********************************************************************
00349     /// Returns a const_iterator to the end of the reference_flat_multiset.
00350     ///\return A const iterator to the end of the reference_flat_multiset.
00351     //*********************************************************************
00352     const_iterator end() const
00353     {
00354       return const_iterator(lookup.end());
00355     }
00356 
00357     //*********************************************************************
00358     /// Returns a const_iterator to the beginning of the reference_flat_multiset.
00359     ///\return A const iterator to the beginning of the reference_flat_multiset.
00360     //*********************************************************************
00361     const_iterator cbegin() const
00362     {
00363       return const_iterator(lookup.cbegin());
00364     }
00365 
00366     //*********************************************************************
00367     /// Returns a const_iterator to the end of the reference_flat_multiset.
00368     ///\return A const iterator to the end of the reference_flat_multiset.
00369     //*********************************************************************
00370     const_iterator cend() const
00371     {
00372       return const_iterator(lookup.cend());
00373     }
00374 
00375     //*********************************************************************
00376     /// Returns an reverse iterator to the reverse beginning of the reference_flat_multiset.
00377     ///\return Iterator to the reverse beginning of the reference_flat_multiset.
00378     //*********************************************************************
00379     reverse_iterator rbegin()
00380     {
00381       return reverse_iterator(lookup.rbegin());
00382     }
00383 
00384     //*********************************************************************
00385     /// Returns a const reverse iterator to the reverse beginning of the reference_flat_multiset.
00386     ///\return Const iterator to the reverse beginning of the reference_flat_multiset.
00387     //*********************************************************************
00388     const_reverse_iterator rbegin() const
00389     {
00390       return const_reverse_iterator(lookup.rbegin());
00391     }
00392 
00393     //*********************************************************************
00394     /// Returns a reverse iterator to the end + 1 of the reference_flat_multiset.
00395     ///\return Reverse iterator to the end + 1 of the reference_flat_multiset.
00396     //*********************************************************************
00397     reverse_iterator rend()
00398     {
00399       return reverse_iterator(lookup.rend());
00400     }
00401 
00402     //*********************************************************************
00403     /// Returns a const reverse iterator to the end + 1 of the reference_flat_multiset.
00404     ///\return Const reverse iterator to the end + 1 of the reference_flat_multiset.
00405     //*********************************************************************
00406     const_reverse_iterator rend() const
00407     {
00408       return const_reverse_iterator(lookup.rend());
00409     }
00410 
00411     //*********************************************************************
00412     /// Returns a const reverse iterator to the reverse beginning of the reference_flat_multiset.
00413     ///\return Const reverse iterator to the reverse beginning of the reference_flat_multiset.
00414     //*********************************************************************
00415     const_reverse_iterator crbegin() const
00416     {
00417       return const_reverse_iterator(lookup.crbegin());
00418     }
00419 
00420     //*********************************************************************
00421     /// Returns a const reverse iterator to the end + 1 of the reference_flat_multiset.
00422     ///\return Const reverse iterator to the end + 1 of the reference_flat_multiset.
00423     //*********************************************************************
00424     const_reverse_iterator crend() const
00425     {
00426       return const_reverse_iterator(lookup.crend());
00427     }
00428 
00429     //*********************************************************************
00430     /// Assigns values to the reference_flat_multiset.
00431     /// If asserts or exceptions are enabled, emits reference_flat_multiset_full if the reference_flat_multiset does not have enough free space.
00432     /// If asserts or exceptions are enabled, emits reference_flat_multiset_iterator if the iterators are reversed.
00433     ///\param first The iterator to the first element.
00434     ///\param last  The iterator to the last element + 1.
00435     //*********************************************************************
00436     template <typename TIterator>
00437     void assign(TIterator first, TIterator last)
00438     {
00439 #if defined(ETL_DEBUG)
00440       difference_type d = std::distance(first, last);
00441       ETL_ASSERT(d <= difference_type(capacity()), ETL_ERROR(flat_multiset_full));
00442 #endif
00443 
00444       clear();
00445 
00446       while (first != last)
00447       {
00448         insert(*first++);
00449       }
00450     }
00451 
00452     //*********************************************************************
00453     /// Inserts a value to the reference_flat_multiset.
00454     /// If asserts or exceptions are enabled, emits reference_flat_multiset_full if the reference_flat_multiset is already full.
00455     ///\param value    The value to insert.
00456     //*********************************************************************
00457     std::pair<iterator, bool> insert(value_type& value)
00458     {
00459       std::pair<iterator, bool> result(end(), false);
00460 
00461       ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full));
00462 
00463       iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare());
00464 
00465       if (i_element == end())
00466       {
00467         // At the end. Doesn't exist.
00468         lookup.push_back(&value);
00469         result.first = --end();
00470         result.second = true;
00471       }
00472       else
00473       {
00474         // Not at the end.
00475         lookup.insert(i_element.ilookup, &value);
00476         result.first = i_element;
00477         result.second = true;
00478       }
00479 
00480       return result;
00481     }
00482 
00483     //*********************************************************************
00484     /// Inserts a value to the reference_flat_multiset.
00485     /// If asserts or exceptions are enabled, emits reference_flat_multiset_full if the reference_flat_multiset is already full.
00486     ///\param position The position to insert at.
00487     ///\param value    The value to insert.
00488     //*********************************************************************
00489     iterator insert(iterator position, value_type& value)
00490     {
00491       return insert(value).first;
00492     }
00493 
00494     //*********************************************************************
00495     /// Inserts a range of values to the reference_flat_multiset.
00496     /// If asserts or exceptions are enabled, emits reference_flat_multiset_full if the reference_flat_multiset does not have enough free space.
00497     ///\param position The position to insert at.
00498     ///\param first    The first element to add.
00499     ///\param last     The last + 1 element to add.
00500     //*********************************************************************
00501     template <class TIterator>
00502     void insert(TIterator first, TIterator last)
00503     {
00504       while (first != last)
00505       {
00506         insert(*first++);
00507       }
00508     }
00509 
00510     //*********************************************************************
00511     /// Erases an element.
00512     ///\param key The key to erase.
00513     ///\return The number of elements erased. 0 or 1.
00514     //*********************************************************************
00515     size_t erase(parameter_t key)
00516     {
00517       std::pair<iterator, iterator> range = equal_range(key);
00518 
00519       if (range.first == end())
00520       {
00521         return 0;
00522       }
00523       else
00524       {
00525         size_t d = std::distance(range.first, range.second);
00526         erase(range.first, range.second);
00527         return d;
00528       }
00529     }
00530 
00531     //*********************************************************************
00532     /// Erases an element.
00533     ///\param i_element Iterator to the element.
00534     //*********************************************************************
00535     void erase(iterator i_element)
00536     {
00537       lookup.erase(i_element.ilookup);
00538     }
00539 
00540     //*********************************************************************
00541     /// Erases a range of elements.
00542     /// The range includes all the elements between first and last, including the
00543     /// element pointed by first, but not the one pointed by last.
00544     ///\param first Iterator to the first element.
00545     ///\param last  Iterator to the last element.
00546     //*********************************************************************
00547     void erase(iterator first, iterator last)
00548     {
00549       lookup.erase(first.ilookup, last.ilookup);;
00550     }
00551 
00552     //*************************************************************************
00553     /// Clears the reference_flat_multiset.
00554     //*************************************************************************
00555     void clear()
00556     {
00557       erase(begin(), end());
00558     }
00559 
00560     //*********************************************************************
00561     /// Finds an element.
00562     ///\param key The key to search for.
00563     ///\return An iterator pointing to the element or end() if not found.
00564     //*********************************************************************
00565     iterator find(parameter_t key)
00566     {
00567       iterator itr = std::lower_bound(begin(), end(), key, TKeyCompare());
00568 
00569       if (itr != end())
00570       {
00571         if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
00572         {
00573           return itr;
00574         }
00575         else
00576         {
00577           return end();
00578         }
00579       }
00580 
00581       return end();
00582     }
00583 
00584     //*********************************************************************
00585     /// Finds an element.
00586     ///\param key The key to search for.
00587     ///\return An iterator pointing to the element or end() if not found.
00588     //*********************************************************************
00589     const_iterator find(parameter_t key) const
00590     {
00591       const_iterator itr = std::lower_bound(begin(), end(), key, TKeyCompare());
00592 
00593       if (itr != end())
00594       {
00595         if (!key_compare()(*itr, key) && !key_compare()(key, *itr))
00596         {
00597           return itr;
00598         }
00599         else
00600         {
00601           return end();
00602         }
00603       }
00604 
00605       return end();
00606     }
00607 
00608     //*********************************************************************
00609     /// Counts an element.
00610     ///\param key The key to search for.
00611     ///\return 1 if the key exists, otherwise 0.
00612     //*********************************************************************
00613     size_t count(parameter_t key) const
00614     {
00615       std::pair<const_iterator, const_iterator> range = equal_range(key);
00616 
00617       return std::distance(range.first, range.second);
00618     }
00619 
00620     //*********************************************************************
00621     /// Finds the lower bound of a key
00622     ///\param key The key to search for.
00623     ///\return An iterator.
00624     //*********************************************************************
00625     iterator lower_bound(parameter_t key)
00626     {
00627       return std::lower_bound(begin(), end(), key, TKeyCompare());
00628     }
00629 
00630     //*********************************************************************
00631     /// Finds the lower bound of a key
00632     ///\param key The key to search for.
00633     ///\return An iterator.
00634     //*********************************************************************
00635     const_iterator lower_bound(parameter_t key) const
00636     {
00637       return std::lower_bound(cbegin(), cend(), key, TKeyCompare());
00638     }
00639 
00640     //*********************************************************************
00641     /// Finds the upper bound of a key
00642     ///\param key The key to search for.
00643     ///\return An iterator.
00644     //*********************************************************************
00645     iterator upper_bound(parameter_t key)
00646     {
00647       return std::upper_bound(begin(), end(), key, TKeyCompare());
00648     }
00649 
00650     //*********************************************************************
00651     /// Finds the upper bound of a key
00652     ///\param key The key to search for.
00653     ///\return An iterator.
00654     //*********************************************************************
00655     const_iterator upper_bound(parameter_t key) const
00656     {
00657       return std::upper_bound(cbegin(), cend(), key, TKeyCompare());
00658     }
00659 
00660     //*********************************************************************
00661     /// Finds the range of equal elements of a key
00662     ///\param key The key to search for.
00663     ///\return An iterator pair.
00664     //*********************************************************************
00665     std::pair<iterator, iterator> equal_range(parameter_t key)
00666     {
00667       return std::equal_range(begin(), end(), key, TKeyCompare());
00668     }
00669 
00670     //*********************************************************************
00671     /// Finds the range of equal elements of a key
00672     ///\param key The key to search for.
00673     ///\return An iterator pair.
00674     //*********************************************************************
00675     std::pair<const_iterator, const_iterator> equal_range(parameter_t key) const
00676     {
00677       return std::equal_range(begin(), end(), key, TKeyCompare());
00678     }
00679 
00680     //*************************************************************************
00681     /// Gets the current size of the reference_flat_multiset.
00682     ///\return The current size of the reference_flat_multiset.
00683     //*************************************************************************
00684     size_type size() const
00685     {
00686       return lookup.size();
00687     }
00688 
00689     //*************************************************************************
00690     /// Checks the 'empty' state of the reference_flat_multiset.
00691     ///\return <b>true</b> if empty.
00692     //*************************************************************************
00693     bool empty() const
00694     {
00695       return lookup.empty();
00696     }
00697 
00698     //*************************************************************************
00699     /// Checks the 'full' state of the reference_flat_multiset.
00700     ///\return <b>true</b> if full.
00701     //*************************************************************************
00702     bool full() const
00703     {
00704       return lookup.full();
00705     }
00706 
00707     //*************************************************************************
00708     /// Returns the capacity of the reference_flat_multiset.
00709     ///\return The capacity of the reference_flat_multiset.
00710     //*************************************************************************
00711     size_type capacity() const
00712     {
00713       return lookup.capacity();
00714     }
00715 
00716     //*************************************************************************
00717     /// Returns the maximum possible size of the reference_flat_multiset.
00718     ///\return The maximum size of the reference_flat_multiset.
00719     //*************************************************************************
00720     size_type max_size() const
00721     {
00722       return lookup.max_size();
00723     }
00724 
00725     //*************************************************************************
00726     /// Returns the remaining capacity.
00727     ///\return The remaining capacity.
00728     //*************************************************************************
00729     size_t available() const
00730     {
00731       return lookup.available();
00732     }
00733 
00734   protected:
00735 
00736     //*********************************************************************
00737     /// Constructor.
00738     //*********************************************************************
00739     ireference_flat_multiset(lookup_t & lookup_)
00740       : lookup(lookup_)
00741     {
00742     }
00743 
00744     //*********************************************************************
00745     /// Inserts a value to the reference_flat_set.
00746     ///\param i_element The place to insert.
00747     ///\param value     The value to insert.
00748     //*********************************************************************
00749     std::pair<iterator, bool> insert_at(iterator i_element, reference value)
00750     {
00751       std::pair<iterator, bool> result(end(), false);
00752 
00753       if (i_element == end())
00754       {
00755         // At the end.
00756         ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full));
00757 
00758         lookup.push_back(&value);
00759         result.first = --end();
00760         result.second = true;
00761       }
00762       else
00763       {
00764         // Not at the end.
00765         result.first = i_element;
00766 
00767         // A new one.
00768         ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full));
00769         lookup.insert(i_element.ilookup, &value);
00770         result.second = true;
00771       }
00772 
00773       return result;
00774     }
00775 
00776   private:
00777 
00778     // Disable copy construction.
00779     ireference_flat_multiset(const ireference_flat_multiset&);
00780     ireference_flat_multiset& operator =(const ireference_flat_multiset&);
00781 
00782     lookup_t& lookup;
00783   };
00784 
00785   //***************************************************************************
00786   /// An reference flat set
00787   ///\ingroup reference_flat_multiset
00788   //***************************************************************************
00789   template <typename TKey, const size_t MAX_SIZE_, typename TKeyCompare = std::less<TKey> >
00790   class reference_flat_multiset : public ireference_flat_multiset<TKey, TKeyCompare>
00791   {
00792   public:
00793 
00794     static const size_t MAX_SIZE = MAX_SIZE_;
00795 
00796     //*************************************************************************
00797     /// Constructor.
00798     //*************************************************************************
00799     reference_flat_multiset()
00800       : ireference_flat_multiset<TKey, TKeyCompare>(lookup)
00801     {
00802     }
00803 
00804     //*************************************************************************
00805     /// Copy constructor.
00806     //*************************************************************************
00807     reference_flat_multiset(const reference_flat_multiset& other)
00808       : ireference_flat_multiset<TKey, TKeyCompare>(lookup)
00809     {
00810       ireference_flat_multiset<TKey, TKeyCompare>::assign(other.cbegin(), other.cend());
00811     }
00812 
00813     //*************************************************************************
00814     /// Constructor, from an iterator range.
00815     ///\tparam TIterator The iterator type.
00816     ///\param first The iterator to the first element.
00817     ///\param last  The iterator to the last element + 1.
00818     //*************************************************************************
00819     template <typename TIterator>
00820     reference_flat_multiset(TIterator first, TIterator last)
00821       : ireference_flat_multiset<TKey, TKeyCompare>(lookup)
00822     {
00823       ireference_flat_multiset<TKey, TKeyCompare>::assign(first, last);
00824     }
00825 
00826     //*************************************************************************
00827     /// Destructor.
00828     //*************************************************************************
00829     ~reference_flat_multiset()
00830     {
00831       ireference_flat_multiset<TKey, TKeyCompare>::clear();
00832     }
00833 
00834   private:
00835 
00836     typedef TKey value_type;
00837 
00838     // The vector that stores pointers to the nodes.
00839     etl::vector<value_type*, MAX_SIZE>  lookup;
00840   };
00841 
00842   //***************************************************************************
00843   /// Equal operator.
00844   ///\param lhs Reference to the first reference_flat_multiset.
00845   ///\param rhs Reference to the second reference_flat_multiset.
00846   ///\return <b>true</b> if the arrays are equal, otherwise <b>false</b>
00847   ///\ingroup reference_flat_multiset
00848   //***************************************************************************
00849   template <typename T, typename TKeyCompare>
00850   bool operator ==(const etl::ireference_flat_multiset<T, TKeyCompare>& lhs, const etl::ireference_flat_multiset<T, TKeyCompare>& rhs)
00851   {
00852     return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin());
00853   }
00854 
00855   //***************************************************************************
00856   /// Not equal operator.
00857   ///\param lhs Reference to the first reference_flat_multiset.
00858   ///\param rhs Reference to the second reference_flat_multiset.
00859   ///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b>
00860   ///\ingroup reference_flat_multiset
00861   //***************************************************************************
00862   template <typename T, typename TKeyCompare>
00863   bool operator !=(const etl::ireference_flat_multiset<T, TKeyCompare>& lhs, const etl::ireference_flat_multiset<T, TKeyCompare>& rhs)
00864   {
00865     return !(lhs == rhs);
00866   }
00867 }
00868 
00869 #undef ETL_FILE
00870 #endif
00871