diff --git a/src/flat_map.h b/src/flat_map.h index f323a367..12cca227 100644 --- a/src/flat_map.h +++ b/src/flat_map.h @@ -37,18 +37,18 @@ SOFTWARE. #include "iflat_map.h" #include "vector.h" +#include "pool.h" //***************************************************************************** ///\defgroup flat_map flat_map /// A flat_map with the capacity defined at compile time. /// Has insertion of O(N) and flat_map of O(logN) -/// Duplicate entries and not allowed. +/// Duplicate entries are not allowed. ///\ingroup containers //***************************************************************************** namespace etl { - template > //*************************************************************************** /// A flat_map implementation that uses a fixed size buffer. ///\tparam TKey The key type. @@ -57,6 +57,7 @@ namespace etl ///\tparam MAX_SIZE_ The maximum number of elements that can be stored. ///\ingroup flat_map //*************************************************************************** + template > class flat_map : public iflat_map { public: @@ -67,7 +68,7 @@ namespace etl /// Constructor. //************************************************************************* flat_map() - : iflat_map(buffer) + : iflat_map(lookup, storage) { } @@ -75,7 +76,7 @@ namespace etl /// Copy constructor. //************************************************************************* flat_map(const flat_map& other) - : iflat_map(buffer) + : iflat_map(lookup, storage) { iflat_map::assign(other.cbegin(), other.cend()); } @@ -88,11 +89,19 @@ namespace etl //************************************************************************* template flat_map(TIterator first, TIterator last) - : iflat_map(buffer) + : iflat_map(lookup, storage) { iflat_map::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~flat_map() + { + iflat_map::clear(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -108,7 +117,13 @@ namespace etl private: - etl::vector::value_type, MAX_SIZE> buffer; ///::value_type node_t; + + // The pool of nodes. + etl::pool storage; + + // The vector that stores pointers to the nodes. + etl::vector lookup; }; } diff --git a/src/flat_multimap.h b/src/flat_multimap.h index b0d3722b..603ff4b5 100644 --- a/src/flat_multimap.h +++ b/src/flat_multimap.h @@ -37,6 +37,7 @@ SOFTWARE. #include "iflat_multimap.h" #include "vector.h" +#include "pool.h" //***************************************************************************** ///\defgroup flat_multimap flat_multimap @@ -67,7 +68,7 @@ namespace etl /// Constructor. //************************************************************************* flat_multimap() - : iflat_multimap(buffer) + : iflat_multimap(lookup, storage) { } @@ -75,7 +76,7 @@ namespace etl /// Copy constructor. //************************************************************************* flat_multimap(const flat_multimap& other) - : iflat_multimap(buffer) + : iflat_multimap(lookup, storage) { iflat_multimap::assign(other.cbegin(), other.cend()); } @@ -88,11 +89,19 @@ namespace etl //************************************************************************* template flat_multimap(TIterator first, TIterator last) - : iflat_multimap(buffer) + : iflat_multimap(lookup, storage) { iflat_multimap::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~flat_multimap() + { + iflat_multimap::clear(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -108,7 +117,13 @@ namespace etl private: - etl::vector::value_type, MAX_SIZE> buffer; ///::value_type node_t; + + // The pool of nodes. + etl::pool storage; + + // The vector that stores pointers to the nodes. + etl::vector lookup; }; } diff --git a/src/flat_multiset.h b/src/flat_multiset.h index 3f5c47f9..be7a9273 100644 --- a/src/flat_multiset.h +++ b/src/flat_multiset.h @@ -37,6 +37,7 @@ SOFTWARE. #include "iflat_multiset.h" #include "vector.h" +#include "pool.h" //***************************************************************************** ///\defgroup flat_multiset flat_multiset @@ -66,7 +67,7 @@ namespace etl /// Constructor. //************************************************************************* flat_multiset() - : iflat_multiset(buffer) + : iflat_multiset(lookup, storage) { } @@ -74,7 +75,7 @@ namespace etl /// Copy constructor. //************************************************************************* flat_multiset(const flat_multiset& other) - : iflat_multiset(buffer) + : iflat_multiset(lookup, storage) { iflat_multiset::assign(other.cbegin(), other.cend()); } @@ -87,11 +88,19 @@ namespace etl //************************************************************************* template flat_multiset(TIterator first, TIterator last) - : iflat_multiset(buffer) + : iflat_multiset(lookup, storage) { iflat_multiset::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~flat_multiset() + { + iflat_multiset::clear(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -107,7 +116,13 @@ namespace etl private: - etl::vector buffer; ///::value_type node_t; + + // The pool of nodes. + etl::pool storage; + + // The vector that stores pointers to the nodes. + etl::vector lookup; }; } diff --git a/src/flat_set.h b/src/flat_set.h index 07ce888a..4a01b066 100644 --- a/src/flat_set.h +++ b/src/flat_set.h @@ -37,6 +37,7 @@ SOFTWARE. #include "iflat_set.h" #include "vector.h" +#include "pool.h" //***************************************************************************** ///\defgroup flat_set flat_set @@ -66,7 +67,7 @@ namespace etl /// Constructor. //************************************************************************* flat_set() - : iflat_set(buffer) + : iflat_set(lookup, storage) { } @@ -74,7 +75,7 @@ namespace etl /// Copy constructor. //************************************************************************* flat_set(const flat_set& other) - : iflat_set(buffer) + : iflat_set(lookup, storage) { iflat_set::assign(other.cbegin(), other.cend()); } @@ -87,11 +88,19 @@ namespace etl //************************************************************************* template flat_set(TIterator first, TIterator last) - : iflat_set(buffer) + : iflat_set(lookup, storage) { iflat_set::assign(first, last); } + //************************************************************************* + /// Destructor. + //************************************************************************* + ~flat_set() + { + iflat_set::clear(); + } + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -107,7 +116,13 @@ namespace etl private: - etl::vector buffer; ///::value_type node_t; + + // The pool of nodes. + etl::pool storage; + + // The vector that stores pointers to the nodes. + etl::vector lookup; }; } diff --git a/src/iflat_map.h b/src/iflat_map.h index ded0c413..20dbed02 100644 --- a/src/iflat_map.h +++ b/src/iflat_map.h @@ -43,6 +43,7 @@ SOFTWARE. #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" +#include "ipool.h" #include "error_handler.h" namespace etl @@ -61,22 +62,229 @@ namespace etl private: - typedef etl::ivector buffer_t; + typedef etl::ivector lookup_t; + typedef etl::ipool storage_t; public: - typedef TKey key_type; - typedef TMapped mapped_type; - typedef TKeyCompare key_compare; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef typename buffer_t::iterator iterator; - typedef typename buffer_t::const_iterator const_iterator; - typedef typename buffer_t::reverse_iterator reverse_iterator; - typedef typename buffer_t::const_reverse_iterator const_reverse_iterator; - typedef size_t size_type; + typedef TKey key_type; + typedef TMapped mapped_type; + typedef TKeyCompare key_compare; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + + //************************************************************************* + class iterator : public std::iterator + { + public: + + friend class iflat_map; + + iterator() + { + } + + iterator(typename lookup_t::iterator ilookup) + : ilookup(ilookup) + { + } + + iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + iterator& operator ++() + { + ++ilookup; + return *this; + } + + iterator operator ++(int) + { + iterator temp(*this); + ++ilookup; + return temp; + } + + iterator& operator --() + { + --ilookup; + return *this; + } + + iterator operator --(int) + { + iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return &(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const iterator& lhs, const iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const iterator& lhs, const iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::iterator ilookup; + }; + + //************************************************************************* + class const_iterator : public std::iterator + { + public: + + friend class iflat_map; + + const_iterator() + { + } + + const_iterator(typename lookup_t::const_iterator ilookup) + : ilookup(ilookup) + { + } + + const_iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator(const const_iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator =(const const_iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator ++() + { + ++ilookup; + return *this; + } + + const_iterator operator ++(int) + { + const_iterator temp(*this); + ++ilookup; + return temp; + } + + const_iterator& operator --() + { + --ilookup; + return *this; + } + + const_iterator operator --(int) + { + const_iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return etl::addressof(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const const_iterator& lhs, const const_iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const const_iterator& lhs, const const_iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::const_iterator ilookup; + }; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; typedef typename std::iterator_traits::difference_type difference_type; protected: @@ -111,7 +319,7 @@ namespace etl //********************************************************************* iterator begin() { - return buffer.begin(); + return iterator(lookup.begin()); } //********************************************************************* @@ -120,7 +328,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return buffer.begin(); + return const_iterator(lookup.begin()); } //********************************************************************* @@ -129,7 +337,7 @@ namespace etl //********************************************************************* iterator end() { - return buffer.end(); + return iterator(lookup.end()); } //********************************************************************* @@ -138,7 +346,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return buffer.end(); + return const_iterator(lookup.end()); } //********************************************************************* @@ -147,7 +355,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return buffer.cbegin(); + return const_iterator(lookup.cbegin()); } //********************************************************************* @@ -156,7 +364,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return buffer.cend(); + return const_iterator(lookup.cend()); } //********************************************************************* @@ -165,7 +373,7 @@ namespace etl //********************************************************************* reverse_iterator rbegin() { - return buffer.rbegin(); + return reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -174,7 +382,7 @@ namespace etl //********************************************************************* const_reverse_iterator rbegin() const { - return buffer.rbegin(); + return reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -183,7 +391,7 @@ namespace etl //********************************************************************* reverse_iterator rend() { - return buffer.rend(); + return reverse_iterator(lookup.rend()); } //********************************************************************* @@ -192,7 +400,7 @@ namespace etl //********************************************************************* const_reverse_iterator rend() const { - return buffer.rend(); + return const_reverse_iterator(lookup.rend()); } //********************************************************************* @@ -201,7 +409,7 @@ namespace etl //********************************************************************* const_reverse_iterator crbegin() const { - return buffer.crbegin(); + return const_reverse_iterator(lookup.crbegin()); } //********************************************************************* @@ -210,7 +418,7 @@ namespace etl //********************************************************************* const_reverse_iterator crend() const { - return buffer.crend(); + return const_reverse_iterator(lookup.crend()); } //********************************************************************* @@ -224,9 +432,9 @@ namespace etl if (i_element == end()) { - // Doesn't exist, so create a new one. - value_type value(key, mapped_type()); - i_element = insert(value).first; + std::pair result = insert_at(i_element, value_type(key, mapped_type())); + + i_element = result.first; } return i_element->second; @@ -255,7 +463,7 @@ namespace etl //********************************************************************* const mapped_type& at(key_value_parameter_t key) const { - typename buffer_t::const_iterator i_element = lower_bound(key); + typename const_iterator i_element = lower_bound(key); ETL_ASSERT(i_element != end(), ETL_ERROR(flat_map_out_of_bounds)); @@ -292,33 +500,9 @@ namespace etl //********************************************************************* std::pair insert(const value_type& value) { - std::pair result(end(), false); - iterator i_element = lower_bound(value.first); - if (i_element == end()) - { - // At the end. - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_map_full)); - buffer.push_back(value); - result.first = end() - 1; - result.second = true; - } - else - { - // Not at the end. - // Existing element? - if (value.first != i_element->first) - { - // A new one. - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_map_full)); - buffer.insert(i_element, value); - result.first = i_element; - result.second = true; - } - } - - return result; + return insert_at(i_element, value); } //********************************************************************* @@ -363,7 +547,10 @@ namespace etl } else { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; return 1; } } @@ -374,7 +561,10 @@ namespace etl //********************************************************************* void erase(iterator i_element) { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; } //********************************************************************* @@ -386,7 +576,17 @@ namespace etl //********************************************************************* void erase(iterator first, iterator last) { - buffer.erase(first, last); + iterator itr = first; + + while (itr != last) + { + itr->~value_type(); + storage.release(etl::addressof(*itr)); + ++itr; + --construct_count; + } + + lookup.erase(first.ilookup, last.ilookup); } //************************************************************************* @@ -394,7 +594,7 @@ namespace etl //************************************************************************* void clear() { - buffer.clear(); + erase(begin(), end()); } //********************************************************************* @@ -538,7 +738,7 @@ namespace etl //************************************************************************* size_type size() const { - return buffer.size(); + return lookup.size(); } //************************************************************************* @@ -547,7 +747,7 @@ namespace etl //************************************************************************* bool empty() const { - return buffer.empty(); + return lookup.empty(); } //************************************************************************* @@ -556,7 +756,7 @@ namespace etl //************************************************************************* bool full() const { - return buffer.full(); + return lookup.full(); } //************************************************************************* @@ -565,7 +765,7 @@ namespace etl //************************************************************************* size_type capacity() const { - return buffer.capacity(); + return lookup.capacity(); } //************************************************************************* @@ -574,7 +774,7 @@ namespace etl //************************************************************************* size_type max_size() const { - return buffer.max_size(); + return lookup.max_size(); } //************************************************************************* @@ -583,7 +783,7 @@ namespace etl //************************************************************************* size_t available() const { - return buffer.available(); + return lookup.available(); } protected: @@ -591,17 +791,61 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iflat_map(buffer_t& buffer) - : buffer(buffer) + iflat_map(lookup_t& lookup_, storage_t& storage_) + : lookup(lookup_), + storage(storage_) { } private: + //********************************************************************* + /// Inserts a value to the flat_map. + ///\param i_element The place to insert. + ///\param value The value to insert. + //********************************************************************* + std::pair insert_at(iterator i_element, const value_type& value) + { + std::pair result(end(), false); + + if (i_element == end()) + { + // At the end. + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_map_full)); + + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.push_back(pvalue); + result.first = --end(); + result.second = true; + ++construct_count; + } + else + { + // Not at the end. + result.first = i_element; + + // Existing element? + if (value.first != i_element->first) + { + // A new one. + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_map_full)); + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.insert(i_element.ilookup, pvalue); + result.second = true; + ++construct_count; + } + } + + return result; + } + // Disable copy construction. iflat_map(const iflat_map&); - buffer_t& buffer; + lookup_t& lookup; + storage_t& storage; }; //*************************************************************************** diff --git a/src/iflat_multimap.h b/src/iflat_multimap.h index 86728f0b..f16abda9 100644 --- a/src/iflat_multimap.h +++ b/src/iflat_multimap.h @@ -44,6 +44,7 @@ SOFTWARE. #include "parameter_type.h" #include "ivector.h" #include "error_handler.h" +#include "ipool.h" namespace etl { @@ -61,22 +62,229 @@ namespace etl private: - typedef etl::ivector buffer_t; + typedef etl::ivector lookup_t; + typedef etl::ipool storage_t; public: - typedef TKey key_type; - typedef TMapped mapped_type; - typedef TKeyCompare key_compare; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef typename buffer_t::iterator iterator; - typedef typename buffer_t::const_iterator const_iterator; - typedef typename buffer_t::reverse_iterator reverse_iterator; - typedef typename buffer_t::const_reverse_iterator const_reverse_iterator; - typedef size_t size_type; + typedef TKey key_type; + typedef TMapped mapped_type; + typedef TKeyCompare key_compare; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + + //************************************************************************* + class iterator : public std::iterator + { + public: + + friend class iflat_multimap; + + iterator() + { + } + + iterator(typename lookup_t::iterator ilookup) + : ilookup(ilookup) + { + } + + iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + iterator& operator ++() + { + ++ilookup; + return *this; + } + + iterator operator ++(int) + { + iterator temp(*this); + ++ilookup; + return temp; + } + + iterator& operator --() + { + --ilookup; + return *this; + } + + iterator operator --(int) + { + iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return &(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const iterator& lhs, const iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const iterator& lhs, const iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::iterator ilookup; + }; + + //************************************************************************* + class const_iterator : public std::iterator + { + public: + + friend class iflat_multimap; + + const_iterator() + { + } + + const_iterator(typename lookup_t::const_iterator ilookup) + : ilookup(ilookup) + { + } + + const_iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator(const const_iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator =(const const_iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator ++() + { + ++ilookup; + return *this; + } + + const_iterator operator ++(int) + { + const_iterator temp(*this); + ++ilookup; + return temp; + } + + const_iterator& operator --() + { + --ilookup; + return *this; + } + + const_iterator operator --(int) + { + const_iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return etl::addressof(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const const_iterator& lhs, const const_iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const const_iterator& lhs, const const_iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::const_iterator ilookup; + }; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; typedef typename std::iterator_traits::difference_type difference_type; protected: @@ -111,7 +319,7 @@ namespace etl //********************************************************************* iterator begin() { - return buffer.begin(); + return iterator(lookup.begin()); } //********************************************************************* @@ -120,7 +328,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return buffer.begin(); + return const_iterator(lookup.begin()); } //********************************************************************* @@ -129,7 +337,7 @@ namespace etl //********************************************************************* iterator end() { - return buffer.end(); + return iterator(lookup.end()); } //********************************************************************* @@ -138,7 +346,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return buffer.end(); + return const_iterator(lookup.end()); } //********************************************************************* @@ -147,7 +355,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return buffer.cbegin(); + return const_iterator(lookup.cbegin()); } //********************************************************************* @@ -156,7 +364,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return buffer.cend(); + return const_iterator(lookup.cend()); } //********************************************************************* @@ -165,7 +373,7 @@ namespace etl //********************************************************************* reverse_iterator rbegin() { - return buffer.rbegin(); + return reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -174,7 +382,7 @@ namespace etl //********************************************************************* const_reverse_iterator rbegin() const { - return buffer.rbegin(); + return const_reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -183,7 +391,7 @@ namespace etl //********************************************************************* reverse_iterator rend() { - return buffer.rend(); + return reverse_iterator(lookup.rend()); } //********************************************************************* @@ -192,7 +400,7 @@ namespace etl //********************************************************************* const_reverse_iterator rend() const { - return buffer.rend(); + return const_reverse_iterator(lookup.rend()); } //********************************************************************* @@ -201,7 +409,7 @@ namespace etl //********************************************************************* const_reverse_iterator crbegin() const { - return buffer.crbegin(); + return const_reverse_iterator(lookup.crbegin()); } //********************************************************************* @@ -210,7 +418,7 @@ namespace etl //********************************************************************* const_reverse_iterator crend() const { - return buffer.crend(); + return const_reverse_iterator(lookup.crend()); } //********************************************************************* @@ -243,28 +451,13 @@ namespace etl //********************************************************************* std::pair insert(const value_type& value) { - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_multimap_full)); + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multimap_full)); - std::pair result(end(), false); +std::pair result(end(), false); iterator i_element = lower_bound(value.first); - if (i_element == end()) - { - // At the end. - buffer.push_back(value); - result.first = end() - 1; - result.second = true; - } - else - { - // Not at the end. - buffer.insert(i_element, value); - result.first = i_element; - result.second = true; - } - - return result; + return insert_at(i_element, value); } //********************************************************************* @@ -301,7 +494,7 @@ namespace etl //********************************************************************* size_t erase(key_value_parameter_t key) { - std::pair range = equal_range(key); + std::pair range = equal_range(key); if (range.first == end()) { @@ -309,8 +502,8 @@ namespace etl } else { - size_t count = std::distance(range.first, range.second); - erase(range.first, range.second); + size_t count = std::distance(range.first, range.second); + erase(range.first, range.second); return count; } } @@ -321,7 +514,10 @@ namespace etl //********************************************************************* void erase(iterator i_element) { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; } //********************************************************************* @@ -333,7 +529,17 @@ namespace etl //********************************************************************* void erase(iterator first, iterator last) { - buffer.erase(first, last); + iterator itr = first; + + while (itr != last) + { + itr->~value_type(); + storage.release(etl::addressof(*itr)); + ++itr; + --construct_count; + } + + lookup.erase(first.ilookup, last.ilookup); } //************************************************************************* @@ -341,7 +547,7 @@ namespace etl //************************************************************************* void clear() { - buffer.clear(); + erase(begin(), end()); } //********************************************************************* @@ -487,7 +693,7 @@ namespace etl //************************************************************************* size_type size() const { - return buffer.size(); + return lookup.size(); } //************************************************************************* @@ -496,7 +702,7 @@ namespace etl //************************************************************************* bool empty() const { - return buffer.empty(); + return lookup.empty(); } //************************************************************************* @@ -505,7 +711,7 @@ namespace etl //************************************************************************* bool full() const { - return buffer.full(); + return lookup.full(); } //************************************************************************* @@ -514,7 +720,7 @@ namespace etl //************************************************************************* size_type capacity() const { - return buffer.capacity(); + return lookup.capacity(); } //************************************************************************* @@ -523,7 +729,7 @@ namespace etl //************************************************************************* size_type max_size() const { - return buffer.max_size(); + return lookup.max_size(); } //************************************************************************* @@ -532,7 +738,7 @@ namespace etl //************************************************************************* size_t available() const { - return buffer.available(); + return lookup.available(); } protected: @@ -540,17 +746,52 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iflat_multimap(buffer_t& buffer) - : buffer(buffer) + iflat_multimap(lookup_t& lookup_, storage_t& storage_) + : lookup(lookup_), + storage(storage_) { } private: + //********************************************************************* + /// Inserts a value to the flat_multimap. + ///\param i_element The place to insert. + ///\param value The value to insert. + //********************************************************************* + std::pair insert_at(iterator i_element, const value_type& value) + { + std::pair result(end(), false); + + if (i_element == end()) + { + // At the end. + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.push_back(pvalue); + result.first = --end(); + result.second = true; + } + else + { + // Not at the end. + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.insert(i_element.ilookup, pvalue); + result.first = i_element; + result.second = true; + } + + ++construct_count; + + return result; + } + // Disable copy construction. iflat_multimap(const iflat_multimap&); - buffer_t& buffer; + lookup_t& lookup; + storage_t& storage; }; //*************************************************************************** diff --git a/src/iflat_multiset.h b/src/iflat_multiset.h index 4a40ba7a..541e723a 100644 --- a/src/iflat_multiset.h +++ b/src/iflat_multiset.h @@ -44,6 +44,7 @@ SOFTWARE. #include "parameter_type.h" #include "ivector.h" #include "error_handler.h" +#include "ipool.h" namespace etl { @@ -55,26 +56,237 @@ namespace etl template > class iflat_multiset : public flat_multiset_base { + public: + + typedef T key_type; + typedef T value_type; + private: - typedef etl::ivector buffer_t; + typedef etl::ivector lookup_t; + typedef etl::ipool storage_t; public: - typedef T key_type; - typedef T value_type; - typedef TKeyCompare key_compare; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef typename buffer_t::iterator iterator; - typedef typename buffer_t::const_iterator const_iterator; - typedef typename buffer_t::reverse_iterator reverse_iterator; - typedef typename buffer_t::const_reverse_iterator const_reverse_iterator; - typedef size_t size_type; + typedef TKeyCompare key_compare; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + + //************************************************************************* + class iterator : public std::iterator + { + public: + + friend class iflat_multiset; + + iterator() + { + } + + iterator(typename lookup_t::iterator ilookup) + : ilookup(ilookup) + { + } + + iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + iterator& operator ++() + { + ++ilookup; + return *this; + } + + iterator operator ++(int) + { + iterator temp(*this); + ++ilookup; + return temp; + } + + iterator& operator --() + { + --ilookup; + return *this; + } + + iterator operator --(int) + { + iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return &(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const iterator& lhs, const iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const iterator& lhs, const iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::iterator ilookup; + }; + + //************************************************************************* + class const_iterator : public std::iterator + { + public: + + friend class iflat_multiset; + + const_iterator() + { + } + + const_iterator(typename lookup_t::const_iterator ilookup) + : ilookup(ilookup) + { + } + + const_iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator(const const_iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator =(const const_iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator ++() + { + ++ilookup; + return *this; + } + + const_iterator operator ++(int) + { + const_iterator temp(*this); + ++ilookup; + return temp; + } + + const_iterator& operator --() + { + --ilookup; + return *this; + } + + const_iterator operator --(int) + { + const_iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return etl::addressof(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const const_iterator& lhs, const const_iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const const_iterator& lhs, const const_iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::const_iterator ilookup; + }; + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; typedef typename std::iterator_traits::difference_type difference_type; + protected: typedef typename parameter_type::type parameter_t; @@ -87,7 +299,7 @@ namespace etl //********************************************************************* iterator begin() { - return buffer.begin(); + return iterator(lookup.begin()); } //********************************************************************* @@ -96,7 +308,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return buffer.begin(); + return const_iterator(lookup.begin()); } //********************************************************************* @@ -105,7 +317,7 @@ namespace etl //********************************************************************* iterator end() { - return buffer.end(); + return iterator(lookup.end()); } //********************************************************************* @@ -114,7 +326,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return buffer.end(); + return const_iterator(lookup.end()); } //********************************************************************* @@ -123,7 +335,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return buffer.cbegin(); + return const_iterator(lookup.cbegin()); } //********************************************************************* @@ -132,7 +344,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return buffer.cend(); + return const_iterator(lookup.cend()); } //********************************************************************* @@ -141,7 +353,7 @@ namespace etl //********************************************************************* reverse_iterator rbegin() { - return buffer.rbegin(); + return reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -150,7 +362,7 @@ namespace etl //********************************************************************* const_reverse_iterator rbegin() const { - return buffer.rbegin(); + return const_reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -159,7 +371,7 @@ namespace etl //********************************************************************* reverse_iterator rend() { - return buffer.rend(); + return reverse_iterator(lookup.rend()); } //********************************************************************* @@ -168,7 +380,7 @@ namespace etl //********************************************************************* const_reverse_iterator rend() const { - return buffer.rend(); + return const_reverse_iterator(lookup.rend()); } //********************************************************************* @@ -177,7 +389,7 @@ namespace etl //********************************************************************* const_reverse_iterator crbegin() const { - return buffer.crbegin(); + return const_reverse_iterator(lookup.crbegin()); } //********************************************************************* @@ -186,7 +398,7 @@ namespace etl //********************************************************************* const_reverse_iterator crend() const { - return buffer.crend(); + return const_reverse_iterator(lookup.crend()); } //********************************************************************* @@ -221,25 +433,31 @@ namespace etl { std::pair result(end(), false); - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_multiset_full)); + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full)); iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare()); if (i_element == end()) { // At the end. - buffer.push_back(value); - result.first = end() - 1; + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.push_back(pvalue); + result.first = --end(); result.second = true; } else { // Not at the end. - buffer.insert(i_element, value); + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.insert(i_element.ilookup, pvalue); result.first = i_element; result.second = true; } - + + ++construct_count; + return result; } @@ -277,7 +495,7 @@ namespace etl //********************************************************************* size_t erase(parameter_t key) { - std::pair range = equal_range(key); + std::pair range = equal_range(key); if (range.first == end()) { @@ -285,9 +503,9 @@ namespace etl } else { - size_t count = std::distance(range.first, range.second); - erase(range.first, range.second); - return count; + size_t count = std::distance(range.first, range.second); + erase(range.first, range.second); + return count; } } @@ -297,7 +515,10 @@ namespace etl //********************************************************************* void erase(iterator i_element) { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; } //********************************************************************* @@ -309,7 +530,17 @@ namespace etl //********************************************************************* void erase(iterator first, iterator last) { - buffer.erase(first, last); + iterator itr = first; + + while (itr != last) + { + itr->~value_type(); + storage.release(etl::addressof(*itr)); + ++itr; + --construct_count; + } + + lookup.erase(first.ilookup, last.ilookup); } //************************************************************************* @@ -317,7 +548,7 @@ namespace etl //************************************************************************* void clear() { - buffer.clear(); + erase(begin(), end()); } //********************************************************************* @@ -377,7 +608,7 @@ namespace etl { std::pair range = equal_range(key); - return std::distance(range.first, range.second); + return std::distance(range.first, range.second); } //********************************************************************* @@ -459,7 +690,7 @@ namespace etl //************************************************************************* size_type size() const { - return buffer.size(); + return lookup.size(); } //************************************************************************* @@ -468,7 +699,7 @@ namespace etl //************************************************************************* bool empty() const { - return buffer.empty(); + return lookup.empty(); } //************************************************************************* @@ -477,7 +708,7 @@ namespace etl //************************************************************************* bool full() const { - return buffer.full(); + return lookup.full(); } //************************************************************************* @@ -486,7 +717,7 @@ namespace etl //************************************************************************* size_type capacity() const { - return buffer.capacity(); + return lookup.capacity(); } //************************************************************************* @@ -495,7 +726,7 @@ namespace etl //************************************************************************* size_type max_size() const { - return buffer.max_size(); + return lookup.max_size(); } //************************************************************************* @@ -504,7 +735,7 @@ namespace etl //************************************************************************* size_t available() const { - return buffer.available(); + return lookup.available(); } protected: @@ -512,8 +743,9 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iflat_multiset(buffer_t& buffer) - : buffer(buffer) + iflat_multiset(lookup_t& lookup_, storage_t& storage_) + : lookup(lookup_), + storage(storage_) { } @@ -522,7 +754,8 @@ namespace etl // Disable copy construction. iflat_multiset(const iflat_multiset&); - buffer_t& buffer; + lookup_t& lookup; + storage_t& storage; }; //*************************************************************************** diff --git a/src/iflat_set.h b/src/iflat_set.h index e692e143..c5cbaf78 100644 --- a/src/iflat_set.h +++ b/src/iflat_set.h @@ -43,6 +43,7 @@ SOFTWARE. #include "type_traits.h" #include "parameter_type.h" #include "ivector.h" +#include "ipool.h" #include "error_handler.h" namespace etl @@ -55,25 +56,230 @@ namespace etl template > class iflat_set : public flat_set_base { + public: + + typedef T key_type; + typedef T value_type; + typedef TKeyCompare key_compare; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef size_t size_type; + private: - typedef etl::ivector buffer_t; + typedef etl::ivector lookup_t; + typedef etl::ipool storage_t; public: - typedef T key_type; - typedef T value_type; - typedef TKeyCompare key_compare; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef typename buffer_t::iterator iterator; - typedef typename buffer_t::const_iterator const_iterator; - typedef typename buffer_t::reverse_iterator reverse_iterator; - typedef typename buffer_t::const_reverse_iterator const_reverse_iterator; - typedef size_t size_type; - typedef typename std::iterator_traits::difference_type difference_type; + //************************************************************************* + class iterator : public std::iterator + { + public: + + friend class iflat_set; + + iterator() + { + } + + iterator(typename lookup_t::iterator ilookup) + : ilookup(ilookup) + { + } + + iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + iterator& operator ++() + { + ++ilookup; + return *this; + } + + iterator operator ++(int) + { + iterator temp(*this); + ++ilookup; + return temp; + } + + iterator& operator --() + { + --ilookup; + return *this; + } + + iterator operator --(int) + { + iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return &(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const iterator& lhs, const iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const iterator& lhs, const iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::iterator ilookup; + }; + + //************************************************************************* + class const_iterator : public std::iterator + { + public: + + friend class iflat_set; + + const_iterator() + { + } + + const_iterator(typename lookup_t::const_iterator ilookup) + : ilookup(ilookup) + { + } + + const_iterator(const iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator(const const_iterator& other) + : ilookup(other.ilookup) + { + } + + const_iterator& operator =(const iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator =(const const_iterator& other) + { + ilookup = other.ilookup; + return *this; + } + + const_iterator& operator ++() + { + ++ilookup; + return *this; + } + + const_iterator operator ++(int) + { + const_iterator temp(*this); + ++ilookup; + return temp; + } + + const_iterator& operator --() + { + --ilookup; + return *this; + } + + const_iterator operator --(int) + { + const_iterator temp(*this); + --ilookup; + return temp; + } + + reference operator *() + { + return *(*ilookup); + } + + const_reference operator *() const + { + return *(*ilookup); + } + + pointer operator &() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator &() const + { + return etl::addressof(*(*ilookup)); + } + + pointer operator ->() + { + return etl::addressof(*(*ilookup)); + } + + const_pointer operator ->() const + { + return etl::addressof(*(*ilookup)); + } + + friend bool operator == (const const_iterator& lhs, const const_iterator& rhs) + { + return lhs.ilookup == rhs.ilookup; + } + + friend bool operator != (const const_iterator& lhs, const const_iterator& rhs) + { + return !(lhs == rhs); + } + + private: + + typename lookup_t::const_iterator ilookup; + }; protected: @@ -81,13 +287,17 @@ namespace etl public: + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef typename std::iterator_traits::difference_type difference_type; + //********************************************************************* /// Returns an iterator to the beginning of the flat_set. ///\return An iterator to the beginning of the flat_set. //********************************************************************* iterator begin() { - return buffer.begin(); + return iterator(lookup.begin()); } //********************************************************************* @@ -96,7 +306,7 @@ namespace etl //********************************************************************* const_iterator begin() const { - return buffer.begin(); + return const_iterator(lookup.begin()); } //********************************************************************* @@ -105,7 +315,7 @@ namespace etl //********************************************************************* iterator end() { - return buffer.end(); + return iterator(lookup.end()); } //********************************************************************* @@ -114,7 +324,7 @@ namespace etl //********************************************************************* const_iterator end() const { - return buffer.end(); + return const_iterator(lookup.end()); } //********************************************************************* @@ -123,7 +333,7 @@ namespace etl //********************************************************************* const_iterator cbegin() const { - return buffer.cbegin(); + return const_iterator(lookup.cbegin()); } //********************************************************************* @@ -132,7 +342,7 @@ namespace etl //********************************************************************* const_iterator cend() const { - return buffer.cend(); + return const_iterator(lookup.cend()); } //********************************************************************* @@ -141,7 +351,7 @@ namespace etl //********************************************************************* reverse_iterator rbegin() { - return buffer.rbegin(); + return reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -150,7 +360,7 @@ namespace etl //********************************************************************* const_reverse_iterator rbegin() const { - return buffer.rbegin(); + return const_reverse_iterator(lookup.rbegin()); } //********************************************************************* @@ -159,7 +369,7 @@ namespace etl //********************************************************************* reverse_iterator rend() { - return buffer.rend(); + return reverse_iterator(lookup.rend()); } //********************************************************************* @@ -168,7 +378,7 @@ namespace etl //********************************************************************* const_reverse_iterator rend() const { - return buffer.rend(); + return const_reverse_iterator(lookup.rend()); } //********************************************************************* @@ -177,7 +387,7 @@ namespace etl //********************************************************************* const_reverse_iterator crbegin() const { - return buffer.crbegin(); + return const_reverse_iterator(lookup.crbegin()); } //********************************************************************* @@ -186,7 +396,7 @@ namespace etl //********************************************************************* const_reverse_iterator crend() const { - return buffer.crend(); + return const_reverse_iterator(lookup.crend()); } //********************************************************************* @@ -221,16 +431,19 @@ namespace etl { std::pair result(end(), false); - ETL_ASSERT(!buffer.full(), ETL_ERROR(flat_set_full)); + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_set_full)); iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare()); if (i_element == end()) { // At the end. Doesn't exist. - buffer.push_back(value); - result.first = end() - 1; + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.push_back(pvalue); + result.first = --end(); result.second = true; + ++construct_count; } else { @@ -238,9 +451,12 @@ namespace etl // Does not exist already? if (*i_element != value) { - buffer.insert(i_element, value); + value_type* pvalue = storage.allocate(); + ::new (pvalue) value_type(value); + lookup.insert(i_element.ilookup, pvalue); result.first = i_element; result.second = true; + ++construct_count; } else { @@ -294,7 +510,10 @@ namespace etl } else { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; return 1; } } @@ -305,7 +524,10 @@ namespace etl //********************************************************************* void erase(iterator i_element) { - buffer.erase(i_element); + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; } //********************************************************************* @@ -317,7 +539,17 @@ namespace etl //********************************************************************* void erase(iterator first, iterator last) { - buffer.erase(first, last); + iterator itr = first; + + while (itr != last) + { + itr->~value_type(); + storage.release(etl::addressof(*itr)); + ++itr; + --construct_count; + } + + lookup.erase(first.ilookup, last.ilookup);; } //************************************************************************* @@ -325,7 +557,7 @@ namespace etl //************************************************************************* void clear() { - buffer.clear(); + erase(begin(), end()); } //********************************************************************* @@ -465,7 +697,7 @@ namespace etl //************************************************************************* size_type size() const { - return buffer.size(); + return lookup.size(); } //************************************************************************* @@ -474,7 +706,7 @@ namespace etl //************************************************************************* bool empty() const { - return buffer.empty(); + return lookup.empty(); } //************************************************************************* @@ -483,7 +715,7 @@ namespace etl //************************************************************************* bool full() const { - return buffer.full(); + return lookup.full(); } //************************************************************************* @@ -492,7 +724,7 @@ namespace etl //************************************************************************* size_type capacity() const { - return buffer.capacity(); + return lookup.capacity(); } //************************************************************************* @@ -501,7 +733,7 @@ namespace etl //************************************************************************* size_type max_size() const { - return buffer.max_size(); + return lookup.max_size(); } //************************************************************************* @@ -510,7 +742,7 @@ namespace etl //************************************************************************* size_t available() const { - return buffer.available(); + return lookup.available(); } protected: @@ -518,8 +750,9 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iflat_set(buffer_t& buffer) - : buffer(buffer) + iflat_set(lookup_t& lookup_, storage_t& storage) + : lookup(lookup_), + storage(storage) { } @@ -528,7 +761,8 @@ namespace etl // Disable copy construction. iflat_set(const iflat_set&); - buffer_t& buffer; + lookup_t& lookup; + storage_t& storage; }; //*************************************************************************** diff --git a/src/private/flat_map_base.h b/src/private/flat_map_base.h index eb237767..420ad2a9 100644 --- a/src/private/flat_map_base.h +++ b/src/private/flat_map_base.h @@ -40,6 +40,7 @@ SOFTWARE. #include "../exception.h" #include "../ivector.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "2" @@ -97,6 +98,10 @@ namespace etl public: typedef size_t size_type; + + protected: + + etl::debug_count construct_count; ///< Internal debugging. }; } diff --git a/src/private/flat_multimap_base.h b/src/private/flat_multimap_base.h index b9c0fc2b..3b65031c 100644 --- a/src/private/flat_multimap_base.h +++ b/src/private/flat_multimap_base.h @@ -40,6 +40,7 @@ SOFTWARE. #include "../exception.h" #include "../ivector.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "3" @@ -83,6 +84,10 @@ namespace etl public: typedef size_t size_type; + + protected: + + etl::debug_count construct_count; }; } diff --git a/src/private/flat_multiset_base.h b/src/private/flat_multiset_base.h index 3bcd337e..b2408b15 100644 --- a/src/private/flat_multiset_base.h +++ b/src/private/flat_multiset_base.h @@ -40,6 +40,7 @@ SOFTWARE. #include "../exception.h" #include "../ivector.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "4" @@ -86,6 +87,10 @@ namespace etl protected: + protected: + + etl::debug_count construct_count; + //************************************************************************* /// Constructor. //************************************************************************* diff --git a/src/private/flat_set_base.h b/src/private/flat_set_base.h index d494cfb4..33deaf5a 100644 --- a/src/private/flat_set_base.h +++ b/src/private/flat_set_base.h @@ -38,8 +38,8 @@ SOFTWARE. #include #include "../exception.h" -#include "../ivector.h" #include "../error_handler.h" +#include "../debug_count.h" #undef ETL_FILE #define ETL_FILE "5" @@ -97,6 +97,10 @@ namespace etl public: typedef size_t size_type; + + protected: + + etl::debug_count construct_count; }; } diff --git a/test/test_flat_map.cpp b/test/test_flat_map.cpp index 37d3444a..42ddb365 100644 --- a/test/test_flat_map.cpp +++ b/test/test_flat_map.cpp @@ -36,12 +36,30 @@ SOFTWARE. #include #include +#include + #include "data.h" #include "../src/flat_map.h" namespace { + static const size_t SIZE = 10; + + typedef TestDataDC DC; + typedef TestDataNDC NDC; + + typedef std::pair ElementDC; + typedef std::pair ElementNDC; + + typedef etl::flat_map DataDC; + typedef etl::flat_map DataNDC; + typedef etl::iflat_map IDataDC; + typedef etl::iflat_map IDataNDC; + + typedef std::map Compare_DataDC; + typedef std::map Compare_DataNDC; + //************************************************************************* template bool Check_Equal(T1 begin1, T1 end1, T2 begin2) @@ -60,23 +78,40 @@ namespace return true; } + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::const_iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::const_iterator& itr) + { + os << itr->first; + + return os; + } + SUITE(test_flat_map) { - static const size_t SIZE = 10; - - typedef TestDataDC DC; - typedef TestDataNDC NDC; - - typedef std::pair ElementDC; - typedef std::pair ElementNDC; - - typedef etl::flat_map DataDC; - typedef etl::flat_map DataNDC; - typedef etl::iflat_map IDataNDC; - - typedef std::map Compare_DataDC; - typedef std::map Compare_DataNDC; - NDC N0 = NDC("A"); NDC N1 = NDC("B"); NDC N2 = NDC("C"); @@ -399,6 +434,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -407,16 +444,20 @@ namespace Compare_DataNDC compare_data; DataNDC data; - data.insert(DataNDC::value_type(0, N0)); + std::pair result; + + result = data.insert(std::make_pair(0, N0)); compare_data.insert(std::make_pair(0, N0)); bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); - + CHECK(isEqual); + CHECK(result.second); + CHECK(*result.first == std::make_pair(0, N0)); - data.insert(std::make_pair(2, N2)); + result = data.insert(std::make_pair(2, N2)); compare_data.insert(std::make_pair(2, N2)); isEqual = Check_Equal(data.begin(), @@ -424,8 +465,10 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK(result.second); + CHECK(*result.first == std::make_pair(2, N2)); - data.insert(std::make_pair(1, N1)); + result = data.insert(std::make_pair(1, N1)); compare_data.insert(std::make_pair(1, N1)); isEqual = Check_Equal(data.begin(), @@ -433,6 +476,10 @@ namespace compare_data.begin()); CHECK(isEqual); + CHECK(result.second); + CHECK(*result.first == std::make_pair(1, N1)); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -441,23 +488,30 @@ namespace Compare_DataNDC compare_data; DataNDC data; - data.insert(DataNDC::value_type(0, N0)); - compare_data.insert(std::make_pair(0, N0)); + std::pair result1; + std::pair result2; + + result1 = data.insert(DataNDC::value_type(0, N0)); + result2 = compare_data.insert(std::make_pair(0, N0)); bool isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + CHECK(result1.second); + CHECK(*result1.first == std::make_pair(0, N0)); - data.insert(std::make_pair(0, N2)); - compare_data.insert(std::make_pair(0, N2)); + result1 = data.insert(std::make_pair(0, N2)); + result2 = compare_data.insert(std::make_pair(0, N2)); isEqual = Check_Equal(data.begin(), data.end(), compare_data.begin()); CHECK(isEqual); + CHECK(!result1.second); + CHECK(*result1.first != std::make_pair(0, N2)); } //************************************************************************* diff --git a/test/test_flat_multimap.cpp b/test/test_flat_multimap.cpp index c0d6260a..339b80fd 100644 --- a/test/test_flat_multimap.cpp +++ b/test/test_flat_multimap.cpp @@ -42,67 +42,100 @@ SOFTWARE. namespace { - SUITE(test_flat_multimap) - { - static const size_t SIZE = 10; + static const size_t SIZE = 10; - typedef TestDataDC DC; - typedef TestDataNDC NDC; + typedef TestDataDC DC; + typedef TestDataNDC NDC; - typedef std::pair ElementDC; - typedef std::pair ElementNDC; + typedef std::pair ElementDC; + typedef std::pair ElementNDC; - typedef etl::flat_multimap DataDC; - typedef etl::flat_multimap DataNDC; - typedef etl::iflat_multimap IDataNDC; + typedef etl::flat_multimap DataDC; + typedef etl::flat_multimap DataNDC; + typedef etl::iflat_multimap IDataDC; + typedef etl::iflat_multimap IDataNDC; - typedef std::multimap Compare_DataDC; - typedef std::multimap Compare_DataNDC; + typedef std::multimap Compare_DataDC; + typedef std::multimap Compare_DataNDC; - NDC N0 = NDC("A"); - NDC N1 = NDC("B"); - NDC N2 = NDC("C"); - NDC N3 = NDC("D"); - NDC N4 = NDC("E"); - NDC N5 = NDC("F"); - NDC N6 = NDC("G"); - NDC N7 = NDC("H"); - NDC N8 = NDC("I"); - NDC N9 = NDC("J"); - NDC N10 = NDC("K"); - NDC N11 = NDC("L"); - NDC N12 = NDC("M"); - NDC N13 = NDC("N"); - NDC N14 = NDC("O"); - NDC N15 = NDC("P"); - NDC N16 = NDC("Q"); - NDC N17 = NDC("R"); - NDC N18 = NDC("S"); - NDC N19 = NDC("T"); + NDC N0 = NDC("A"); + NDC N1 = NDC("B"); + NDC N2 = NDC("C"); + NDC N3 = NDC("D"); + NDC N4 = NDC("E"); + NDC N5 = NDC("F"); + NDC N6 = NDC("G"); + NDC N7 = NDC("H"); + NDC N8 = NDC("I"); + NDC N9 = NDC("J"); + NDC N10 = NDC("K"); + NDC N11 = NDC("L"); + NDC N12 = NDC("M"); + NDC N13 = NDC("N"); + NDC N14 = NDC("O"); + NDC N15 = NDC("P"); + NDC N16 = NDC("Q"); + NDC N17 = NDC("R"); + NDC N18 = NDC("S"); + NDC N19 = NDC("T"); - std::vector initial_data; - std::vector excess_data; - std::vector different_data; + std::vector initial_data; + std::vector excess_data; + std::vector different_data; std::vector multi_data; - //************************************************************************* - template - bool Check_Equal(T1 begin1, T1 end1, T2 begin2) + //************************************************************************* + template + bool Check_Equal(T1 begin1, T1 end1, T2 begin2) + { + while (begin1 != end1) { - while (begin1 != end1) + if ((begin1->first != begin2->first) || (begin1->second != begin2->second)) { - if ((begin1->first != begin2->first) || (begin1->second != begin2->second)) - { - return false; - } - - ++begin1; - ++begin2; + return false; } - return true; + ++begin1; + ++begin2; } + return true; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::const_iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::iterator& itr) + { + os << itr->first; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::const_iterator& itr) + { + os << itr->first; + + return os; + } + + SUITE(test_flat_multimap) + { //************************************************************************* struct SetupFixture { @@ -127,16 +160,16 @@ namespace ElementNDC(15, N15), ElementNDC(16, N16), ElementNDC(17, N17), ElementNDC(18, N18), ElementNDC(19, N19) }; - ElementNDC n4[] = - { - ElementNDC(0, N0), ElementNDC(1, N1), ElementNDC(2, N2), ElementNDC(1, N3), ElementNDC(3, N4), - ElementNDC(4, N5), ElementNDC(4, N6), ElementNDC(5, N7), ElementNDC(4, N8), ElementNDC(0, N9) - }; + ElementNDC n4[] = + { + ElementNDC(0, N0), ElementNDC(1, N1), ElementNDC(2, N2), ElementNDC(1, N3), ElementNDC(3, N4), + ElementNDC(4, N5), ElementNDC(4, N6), ElementNDC(5, N7), ElementNDC(4, N8), ElementNDC(0, N9) + }; initial_data.assign(std::begin(n), std::end(n)); excess_data.assign(std::begin(n2), std::end(n2)); different_data.assign(std::begin(n3), std::end(n3)); - multi_data.assign(std::begin(n4), std::end(n4)); + multi_data.assign(std::begin(n4), std::end(n4)); } }; @@ -263,6 +296,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -297,6 +332,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -331,6 +368,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -339,6 +378,8 @@ namespace DataNDC data(initial_data.begin(), initial_data.end()); CHECK_THROW(data.insert(std::make_pair(10, N10)), etl::flat_multimap_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -355,6 +396,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -363,6 +406,8 @@ namespace DataNDC data; CHECK_THROW(data.insert(excess_data.begin(), excess_data.end()), etl::flat_multimap_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* diff --git a/test/test_flat_multiset.cpp b/test/test_flat_multiset.cpp index 7d54bc6c..0e870cd0 100644 --- a/test/test_flat_multiset.cpp +++ b/test/test_flat_multiset.cpp @@ -42,49 +42,81 @@ SOFTWARE. namespace { + static const size_t SIZE = 10; + + typedef TestDataDC DC; + typedef TestDataNDC NDC; + + typedef etl::flat_multiset DataDC; + typedef etl::flat_multiset DataNDC; + typedef etl::iflat_multiset IDataNDC; + + typedef std::multiset Compare_DataDC; + typedef std::multiset Compare_DataNDC; + + NDC NX = NDC("@"); + NDC NY = NDC("["); + + NDC N0 = NDC("A"); + NDC N1 = NDC("B"); + NDC N2 = NDC("C"); + NDC N3 = NDC("D"); + NDC N4 = NDC("E"); + NDC N5 = NDC("F"); + NDC N6 = NDC("G"); + NDC N7 = NDC("H"); + NDC N8 = NDC("I"); + NDC N9 = NDC("J"); + NDC N10 = NDC("K"); + NDC N11 = NDC("L"); + NDC N12 = NDC("M"); + NDC N13 = NDC("N"); + NDC N14 = NDC("O"); + NDC N15 = NDC("P"); + NDC N16 = NDC("Q"); + NDC N17 = NDC("R"); + NDC N18 = NDC("S"); + NDC N19 = NDC("T"); + + std::vector initial_data; + std::vector excess_data; + std::vector different_data; + std::vector multi_data; + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::iterator& itr) + { + os << itr->value; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataDC::const_iterator& itr) + { + os << itr->value; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::iterator& itr) + { + os << itr->value; + + return os; + } + + //************************************************************************* + std::ostream& operator <<(std::ostream& os, const DataNDC::const_iterator& itr) + { + os << itr->value; + + return os; + } + SUITE(test_flat_multiset) { - static const size_t SIZE = 10; - - typedef TestDataDC DC; - typedef TestDataNDC NDC; - - typedef etl::flat_multiset DataDC; - typedef etl::flat_multiset DataNDC; - typedef etl::iflat_multiset IDataNDC; - - typedef std::multiset Compare_DataDC; - typedef std::multiset Compare_DataNDC; - - NDC NX = NDC("@"); - NDC NY = NDC("["); - - NDC N0 = NDC("A"); - NDC N1 = NDC("B"); - NDC N2 = NDC("C"); - NDC N3 = NDC("D"); - NDC N4 = NDC("E"); - NDC N5 = NDC("F"); - NDC N6 = NDC("G"); - NDC N7 = NDC("H"); - NDC N8 = NDC("I"); - NDC N9 = NDC("J"); - NDC N10 = NDC("K"); - NDC N11 = NDC("L"); - NDC N12 = NDC("M"); - NDC N13 = NDC("N"); - NDC N14 = NDC("O"); - NDC N15 = NDC("P"); - NDC N16 = NDC("Q"); - NDC N17 = NDC("R"); - NDC N18 = NDC("S"); - NDC N19 = NDC("T"); - - std::vector initial_data; - std::vector excess_data; - std::vector different_data; - std::vector multi_data; - //************************************************************************* struct SetupFixture { @@ -240,6 +272,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -274,6 +308,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -308,6 +344,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -316,6 +354,8 @@ namespace DataNDC data(initial_data.begin(), initial_data.end()); CHECK_THROW(data.insert(N10), etl::flat_multiset_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -332,6 +372,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -340,6 +382,8 @@ namespace DataNDC data; CHECK_THROW(data.insert(excess_data.begin(), excess_data.end()), etl::flat_multiset_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* diff --git a/test/test_flat_set.cpp b/test/test_flat_set.cpp index cab386c8..c770a1fa 100644 --- a/test/test_flat_set.cpp +++ b/test/test_flat_set.cpp @@ -40,50 +40,82 @@ SOFTWARE. #include "../src/flat_set.h" +static const size_t SIZE = 10; + +typedef TestDataDC DC; +typedef TestDataNDC NDC; + +typedef etl::flat_set DataDC; +typedef etl::flat_set DataNDC; +typedef etl::iflat_set IDataNDC; + +typedef std::set Compare_DataDC; +typedef std::set Compare_DataNDC; + +NDC NX = NDC("@"); +NDC NY = NDC("["); + +NDC N0 = NDC("A"); +NDC N1 = NDC("B"); +NDC N2 = NDC("C"); +NDC N3 = NDC("D"); +NDC N4 = NDC("E"); +NDC N5 = NDC("F"); +NDC N6 = NDC("G"); +NDC N7 = NDC("H"); +NDC N8 = NDC("I"); +NDC N9 = NDC("J"); +NDC N10 = NDC("K"); +NDC N11 = NDC("L"); +NDC N12 = NDC("M"); +NDC N13 = NDC("N"); +NDC N14 = NDC("O"); +NDC N15 = NDC("P"); +NDC N16 = NDC("Q"); +NDC N17 = NDC("R"); +NDC N18 = NDC("S"); +NDC N19 = NDC("T"); + +std::vector initial_data; +std::vector excess_data; +std::vector different_data; + +//************************************************************************* +std::ostream& operator <<(std::ostream& os, const DataDC::iterator& itr) +{ + os << itr->value; + + return os; +} + +//************************************************************************* +std::ostream& operator <<(std::ostream& os, const DataDC::const_iterator& itr) +{ + os << itr->value; + + return os; +} + +//************************************************************************* +std::ostream& operator <<(std::ostream& os, const DataNDC::iterator& itr) +{ + os << itr->value; + + return os; +} + +//************************************************************************* +std::ostream& operator <<(std::ostream& os, const DataNDC::const_iterator& itr) +{ + os << itr->value; + + return os; +} + namespace { SUITE(test_flat_set) { - static const size_t SIZE = 10; - - typedef TestDataDC DC; - typedef TestDataNDC NDC; - - typedef etl::flat_set DataDC; - typedef etl::flat_set DataNDC; - typedef etl::iflat_set IDataNDC; - - typedef std::set Compare_DataDC; - typedef std::set Compare_DataNDC; - - NDC NX = NDC("@"); - NDC NY = NDC("["); - - NDC N0 = NDC("A"); - NDC N1 = NDC("B"); - NDC N2 = NDC("C"); - NDC N3 = NDC("D"); - NDC N4 = NDC("E"); - NDC N5 = NDC("F"); - NDC N6 = NDC("G"); - NDC N7 = NDC("H"); - NDC N8 = NDC("I"); - NDC N9 = NDC("J"); - NDC N10 = NDC("K"); - NDC N11 = NDC("L"); - NDC N12 = NDC("M"); - NDC N13 = NDC("N"); - NDC N14 = NDC("O"); - NDC N15 = NDC("P"); - NDC N16 = NDC("Q"); - NDC N17 = NDC("R"); - NDC N18 = NDC("S"); - NDC N19 = NDC("T"); - - std::vector initial_data; - std::vector excess_data; - std::vector different_data; - //************************************************************************* struct SetupFixture { @@ -233,6 +265,8 @@ namespace compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -245,8 +279,8 @@ namespace compare_data.insert(N0); bool isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); @@ -254,19 +288,23 @@ namespace compare_data.insert(N2); isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); data.insert(N1); compare_data.insert(N1); + std::vector test(data.begin(), data.end()); + isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -295,6 +333,8 @@ namespace compare_data.insert(N2); CHECK_EQUAL(compare_data.size(), data.size()); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -303,6 +343,8 @@ namespace DataNDC data(initial_data.begin(), initial_data.end()); CHECK_THROW(data.insert(N10), etl::flat_set_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -315,10 +357,12 @@ namespace compare_data.insert(initial_data.begin(), initial_data.end()); bool isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -327,6 +371,8 @@ namespace DataNDC data; CHECK_THROW(data.insert(excess_data.begin(), excess_data.end()), etl::flat_set_full); + + CHECK(std::is_sorted(data.begin(), data.end())); } //************************************************************************* @@ -344,8 +390,8 @@ namespace CHECK_EQUAL(count_compare, count); bool isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); } @@ -366,8 +412,8 @@ namespace data.erase(i_data); bool isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); } @@ -394,8 +440,8 @@ namespace data.erase(i_data, i_data_end); bool isEqual = std::equal(data.begin(), - data.end(), - compare_data.begin()); + data.end(), + compare_data.begin()); CHECK(isEqual); }