From 513ef1ec79826562b0092787f16f220f2aac5dd6 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 17 Apr 2017 18:38:14 +0100 Subject: [PATCH] Added etl:: --- src/array.h | 2 +- src/flat_map.h | 2 +- src/flat_multimap.h | 834 ++++++++++++++++++++++++++++++++++++++++++- src/flat_multiset.h | 805 ++++++++++++++++++++++++++++++++++++++++- src/flat_set.h | 2 +- src/list.h | 2 +- src/priority_queue.h | 2 +- src/queue.h | 2 +- src/stack.h | 2 +- src/vector.h | 2 +- 10 files changed, 1627 insertions(+), 28 deletions(-) diff --git a/src/array.h b/src/array.h index 1e514c98..41075645 100644 --- a/src/array.h +++ b/src/array.h @@ -86,7 +86,7 @@ namespace etl { private: - typedef typename parameter_type::type parameter_t; + typedef typename etl::parameter_type::type parameter_t; public: diff --git a/src/flat_map.h b/src/flat_map.h index 58150fc1..f64e93f5 100644 --- a/src/flat_map.h +++ b/src/flat_map.h @@ -344,7 +344,7 @@ namespace etl protected: - typedef typename parameter_type::type key_value_parameter_t; + typedef typename etl::parameter_type::type key_value_parameter_t; private: diff --git a/src/flat_multimap.h b/src/flat_multimap.h index 603ff4b5..df9aea1f 100644 --- a/src/flat_multimap.h +++ b/src/flat_multimap.h @@ -33,11 +33,21 @@ SOFTWARE. #include #include +#include #include +#include -#include "iflat_multimap.h" +#include "platform.h" #include "vector.h" #include "pool.h" +#include "exception.h" +#include "error_handler.h" +#include "debug_count.h" +#include "type_traits.h" +#include "parameter_type.h" + +#undef ETL_FILE +#define ETL_FILE "3" //***************************************************************************** ///\defgroup flat_multimap flat_multimap @@ -49,7 +59,806 @@ SOFTWARE. namespace etl { - template > + //*************************************************************************** + ///\ingroup flat_multimap + /// Exception base for flat_multimaps + //*************************************************************************** + class flat_multimap_exception : public etl::exception + { + public: + + flat_multimap_exception(string_type what, string_type file_name, numeric_type line_number) + : exception(what, file_name, line_number) + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multimap + /// Vector full exception. + //*************************************************************************** + class flat_multimap_full : public etl::flat_multimap_exception + { + public: + + flat_multimap_full(string_type file_name, numeric_type line_number) + : etl::flat_multimap_exception(ETL_ERROR_TEXT("flat_multimap:full", ETL_FILE"A"), file_name, line_number) + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multimap + /// The base class for all templated flat_multimap types. + //*************************************************************************** + class flat_multimap_base + { + public: + + typedef size_t size_type; + + protected: + + etl::debug_count construct_count; + }; + + //*************************************************************************** + /// The base class for specifically sized flat_multimaps. + /// Can be used as a reference type for all flat_multimaps containing a specific type. + ///\ingroup flat_multimap + //*************************************************************************** + template > + class iflat_multimap : public etl::flat_multimap_base + { + public: + + typedef std::pair value_type; + + private: + + 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 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; + } + + const_reference operator *() const + { + return *(*ilookup); + } + + const_pointer operator &() const + { + 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 etl::parameter_type::type key_value_parameter_t; + + private: + + //********************************************************************* + /// How to compare elements and keys. + //********************************************************************* + class compare + { + public: + + bool operator ()(const value_type& element, key_type key) const + { + return key_compare()(element.first, key); + } + + bool operator ()(key_type key, const value_type& element) const + { + return key_compare()(key, element.first); + } + }; + + public: + + //********************************************************************* + /// Returns an iterator to the beginning of the flat_multimap. + ///\return An iterator to the beginning of the flat_multimap. + //********************************************************************* + iterator begin() + { + return iterator(lookup.begin()); + } + + //********************************************************************* + /// Returns a const_iterator to the beginning of the flat_multimap. + ///\return A const iterator to the beginning of the flat_multimap. + //********************************************************************* + const_iterator begin() const + { + return const_iterator(lookup.begin()); + } + + //********************************************************************* + /// Returns an iterator to the end of the flat_multimap. + ///\return An iterator to the end of the flat_multimap. + //********************************************************************* + iterator end() + { + return iterator(lookup.end()); + } + + //********************************************************************* + /// Returns a const_iterator to the end of the flat_multimap. + ///\return A const iterator to the end of the flat_multimap. + //********************************************************************* + const_iterator end() const + { + return const_iterator(lookup.end()); + } + + //********************************************************************* + /// Returns a const_iterator to the beginning of the flat_multimap. + ///\return A const iterator to the beginning of the flat_multimap. + //********************************************************************* + const_iterator cbegin() const + { + return const_iterator(lookup.cbegin()); + } + + //********************************************************************* + /// Returns a const_iterator to the end of the flat_multimap. + ///\return A const iterator to the end of the flat_multimap. + //********************************************************************* + const_iterator cend() const + { + return const_iterator(lookup.cend()); + } + + //********************************************************************* + /// Returns an reverse iterator to the reverse beginning of the flat_multimap. + ///\return Iterator to the reverse beginning of the flat_multimap. + //********************************************************************* + reverse_iterator rbegin() + { + return reverse_iterator(lookup.rbegin()); + } + + //********************************************************************* + /// Returns a const reverse iterator to the reverse beginning of the flat_multimap. + ///\return Const iterator to the reverse beginning of the flat_multimap. + //********************************************************************* + const_reverse_iterator rbegin() const + { + return const_reverse_iterator(lookup.rbegin()); + } + + //********************************************************************* + /// Returns a reverse iterator to the end + 1 of the flat_multimap. + ///\return Reverse iterator to the end + 1 of the flat_multimap. + //********************************************************************* + reverse_iterator rend() + { + return reverse_iterator(lookup.rend()); + } + + //********************************************************************* + /// Returns a const reverse iterator to the end + 1 of the flat_multimap. + ///\return Const reverse iterator to the end + 1 of the flat_multimap. + //********************************************************************* + const_reverse_iterator rend() const + { + return const_reverse_iterator(lookup.rend()); + } + + //********************************************************************* + /// Returns a const reverse iterator to the reverse beginning of the flat_multimap. + ///\return Const reverse iterator to the reverse beginning of the flat_multimap. + //********************************************************************* + const_reverse_iterator crbegin() const + { + return const_reverse_iterator(lookup.crbegin()); + } + + //********************************************************************* + /// Returns a const reverse iterator to the end + 1 of the flat_multimap. + ///\return Const reverse iterator to the end + 1 of the flat_multimap. + //********************************************************************* + const_reverse_iterator crend() const + { + return const_reverse_iterator(lookup.crend()); + } + + //********************************************************************* + /// Assigns values to the flat_multimap. + /// If asserts or exceptions are enabled, emits flat_multimap_full if the flat_multimap does not have enough free space. + /// If asserts or exceptions are enabled, emits flat_multimap_iterator if the iterators are reversed. + ///\param first The iterator to the first element. + ///\param last The iterator to the last element + 1. + //********************************************************************* + template + void assign(TIterator first, TIterator last) + { +#if defined(ETL_DEBUG) + difference_type count = std::distance(first, last); + ETL_ASSERT(count <= difference_type(capacity()), ETL_ERROR(flat_multimap_full)); +#endif + + clear(); + + while (first != last) + { + insert(*first++); + } + } + + //********************************************************************* + /// Inserts a value to the flat_multimap. + /// If asserts or exceptions are enabled, emits flat_multimap_full if the flat_multimap is already full. + ///\param value The value to insert. + //********************************************************************* + std::pair insert(const value_type& value) + { + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multimap_full)); + + std::pair result(end(), false); + + iterator i_element = lower_bound(value.first); + + return insert_at(i_element, value); + } + + //********************************************************************* + /// Inserts a value to the flast_multi. + /// If asserts or exceptions are enabled, emits flat_map_full if the flat_map is already full. + ///\param position The position to insert at. + ///\param value The value to insert. + //********************************************************************* + iterator insert(iterator position, const value_type& value) + { + return insert(value).first; + } + + //********************************************************************* + /// Inserts a range of values to the flat_multimap. + /// If asserts or exceptions are enabled, emits flat_multimap_full if the flat_multimap does not have enough free space. + ///\param position The position to insert at. + ///\param first The first element to add. + ///\param last The last + 1 element to add. + //********************************************************************* + template + void insert(TIterator first, TIterator last) + { + while (first != last) + { + insert(*first++); + } + } + + //********************************************************************* + /// Erases an element. + ///\param key The key to erase. + ///\return The number of elements erased. 0 or 1. + //********************************************************************* + size_t erase(key_value_parameter_t key) + { + std::pair range = equal_range(key); + + if (range.first == end()) + { + return 0; + } + else + { + size_t count = std::distance(range.first, range.second); + erase(range.first, range.second); + return count; + } + } + + //********************************************************************* + /// Erases an element. + ///\param i_element Iterator to the element. + //********************************************************************* + void erase(iterator i_element) + { + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; + } + + //********************************************************************* + /// Erases a range of elements. + /// The range includes all the elements between first and last, including the + /// element pointed by first, but not the one pointed by last. + ///\param first Iterator to the first element. + ///\param last Iterator to the last element. + //********************************************************************* + void erase(iterator first, iterator last) + { + iterator itr = first; + + while (itr != last) + { + itr->~value_type(); + storage.release(etl::addressof(*itr)); + ++itr; + --construct_count; + } + + lookup.erase(first.ilookup, last.ilookup); + } + + //************************************************************************* + /// Clears the flat_multimap. + //************************************************************************* + void clear() + { + erase(begin(), end()); + } + + //********************************************************************* + /// Finds an element. + ///\param key The key to search for. + ///\return An iterator pointing to the element or end() if not found. + //********************************************************************* + iterator find(key_value_parameter_t key) + { + iterator itr = lower_bound(key); + + if (itr != end()) + { + if (!key_compare()(itr->first, key) && !key_compare()(key, itr->first)) + { + return itr; + } + else + { + return end(); + } + } + + return end(); + } + + //********************************************************************* + /// Finds an element. + ///\param key The key to search for. + ///\return An iterator pointing to the element or end() if not found. + //********************************************************************* + const_iterator find(key_value_parameter_t key) const + { + const_iterator itr = lower_bound(key); + + if (itr != end()) + { + if (!key_compare()(itr->first, key) && !key_compare()(key, itr->first)) + { + return itr; + } + else + { + return end(); + } + } + + return end(); + } + + //********************************************************************* + /// Counts an element. + ///\param key The key to search for. + ///\return 1 if the key exists, otherwise 0. + //********************************************************************* + size_t count(key_value_parameter_t key) const + { + std::pair range = equal_range(key); + + return std::distance(range.first, range.second); + } + + //********************************************************************* + /// Finds the lower bound of a key + ///\param key The key to search for. + ///\return An iterator. + //********************************************************************* + iterator lower_bound(key_value_parameter_t key) + { + return std::lower_bound(begin(), end(), key, compare()); + } + + //********************************************************************* + /// Finds the lower bound of a key + ///\param key The key to search for. + ///\return An iterator. + //********************************************************************* + const_iterator lower_bound(key_value_parameter_t key) const + { + return std::lower_bound(cbegin(), cend(), key, compare()); + } + + //********************************************************************* + /// Finds the upper bound of a key + ///\param key The key to search for. + ///\return An iterator. + //********************************************************************* + iterator upper_bound(key_value_parameter_t key) + { + return std::upper_bound(begin(), end(), key, compare()); + } + + //********************************************************************* + /// Finds the upper bound of a key + ///\param key The key to search for. + ///\return An iterator. + //********************************************************************* + const_iterator upper_bound(key_value_parameter_t key) const + { + return std::upper_bound(begin(), end(), key, compare()); + } + + //********************************************************************* + /// Finds the range of equal elements of a key + ///\param key The key to search for. + ///\return An iterator pair. + //********************************************************************* + std::pair equal_range(key_value_parameter_t key) + { + iterator i_lower = std::lower_bound(begin(), end(), key, compare()); + + return std::make_pair(i_lower, std::upper_bound(i_lower, end(), key, compare())); + } + + //********************************************************************* + /// Finds the range of equal elements of a key + ///\param key The key to search for. + ///\return An iterator pair. + //********************************************************************* + std::pair equal_range(key_value_parameter_t key) const + { + const_iterator i_lower = std::lower_bound(cbegin(), cend(), key, compare()); + + return std::make_pair(i_lower, std::upper_bound(i_lower, cend(), key, compare())); + } + + //************************************************************************* + /// Assignment operator. + //************************************************************************* + iflat_multimap& operator = (const iflat_multimap& rhs) + { + if (&rhs != this) + { + assign(rhs.cbegin(), rhs.cend()); + } + + return *this; + } + + //************************************************************************* + /// Gets the current size of the flat_multiset. + ///\return The current size of the flat_multiset. + //************************************************************************* + size_type size() const + { + return lookup.size(); + } + + //************************************************************************* + /// Checks the 'empty' state of the flat_multiset. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return lookup.empty(); + } + + //************************************************************************* + /// Checks the 'full' state of the flat_multiset. + ///\return true if full. + //************************************************************************* + bool full() const + { + return lookup.full(); + } + + //************************************************************************* + /// Returns the capacity of the flat_multiset. + ///\return The capacity of the flat_multiset. + //************************************************************************* + size_type capacity() const + { + return lookup.capacity(); + } + + //************************************************************************* + /// Returns the maximum possible size of the flat_multiset. + ///\return The maximum size of the flat_multiset. + //************************************************************************* + size_type max_size() const + { + return lookup.max_size(); + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return lookup.available(); + } + + protected: + + //********************************************************************* + /// Constructor. + //********************************************************************* + 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&); + + lookup_t& lookup; + storage_t& storage; + }; + + //*************************************************************************** + /// Equal operator. + ///\param lhs Reference to the first flat_multimap. + ///\param rhs Reference to the second flat_multimap. + ///\return true if the arrays are equal, otherwise false + ///\ingroup flat_multimap + //*************************************************************************** + template + bool operator ==(const etl::iflat_multimap& lhs, const etl::iflat_multimap& rhs) + { + return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin()); + } + + //*************************************************************************** + /// Not equal operator. + ///\param lhs Reference to the first flat_multimap. + ///\param rhs Reference to the second flat_multimap. + ///\return true if the arrays are not equal, otherwise false + ///\ingroup flat_multimap + //*************************************************************************** + template + bool operator !=(const etl::iflat_multimap& lhs, const etl::iflat_multimap& rhs) + { + return !(lhs == rhs); + } + //*************************************************************************** /// A flat_multimap implementation that uses a fixed size buffer. ///\tparam TKey The key type. @@ -58,7 +867,8 @@ namespace etl ///\tparam MAX_SIZE_ The maximum number of elements that can be stored. ///\ingroup flat_multimap //*************************************************************************** - class flat_multimap : public iflat_multimap + template > + class flat_multimap : public etl::iflat_multimap { public: @@ -68,7 +878,7 @@ namespace etl /// Constructor. //************************************************************************* flat_multimap() - : iflat_multimap(lookup, storage) + : etl::iflat_multimap(lookup, storage) { } @@ -76,9 +886,9 @@ namespace etl /// Copy constructor. //************************************************************************* flat_multimap(const flat_multimap& other) - : iflat_multimap(lookup, storage) + : etl::iflat_multimap(lookup, storage) { - iflat_multimap::assign(other.cbegin(), other.cend()); + etl::iflat_multimap::assign(other.cbegin(), other.cend()); } //************************************************************************* @@ -89,9 +899,9 @@ namespace etl //************************************************************************* template flat_multimap(TIterator first, TIterator last) - : iflat_multimap(lookup, storage) + : etl::iflat_multimap(lookup, storage) { - iflat_multimap::assign(first, last); + etl::iflat_multimap::assign(first, last); } //************************************************************************* @@ -99,7 +909,7 @@ namespace etl //************************************************************************* ~flat_multimap() { - iflat_multimap::clear(); + etl::iflat_multimap::clear(); } //************************************************************************* @@ -109,7 +919,7 @@ namespace etl { if (&rhs != this) { - iflat_multimap::assign(rhs.cbegin(), rhs.cend()); + etl::iflat_multimap::assign(rhs.cbegin(), rhs.cend()); } return *this; @@ -117,7 +927,7 @@ namespace etl private: - typedef typename iflat_multimap::value_type node_t; + typedef typename etl::iflat_multimap::value_type node_t; // The pool of nodes. etl::pool storage; @@ -127,4 +937,6 @@ namespace etl }; } +#undef ETL_FILE + #endif diff --git a/src/flat_multiset.h b/src/flat_multiset.h index be7a9273..8d478ace 100644 --- a/src/flat_multiset.h +++ b/src/flat_multiset.h @@ -34,10 +34,22 @@ SOFTWARE. #include #include #include +#include +#include +#include -#include "iflat_multiset.h" +#include "platform.h" #include "vector.h" #include "pool.h" +#include "exception.h" +#include "vector.h" +#include "error_handler.h" +#include "debug_count.h" +#include "type_traits.h" +#include "parameter_type.h" + +#undef ETL_FILE +#define ETL_FILE "4" //***************************************************************************** ///\defgroup flat_multiset flat_multiset @@ -49,7 +61,779 @@ SOFTWARE. namespace etl { - template > + //*************************************************************************** + ///\ingroup flat_multiset + /// Exception base for flat_multisets + //*************************************************************************** + class flat_multiset_exception : public etl::exception + { + public: + + flat_multiset_exception(string_type what, string_type file_name, numeric_type line_number) + : etl::exception(what, file_name, line_number) + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multiset + /// Flat multiset full exception. + //*************************************************************************** + class flat_multiset_full : public etl::flat_multiset_exception + { + public: + + flat_multiset_full(string_type file_name, numeric_type line_number) + : etl::flat_multiset_exception(ETL_ERROR_TEXT("flat_multiset:full", ETL_FILE"A"), file_name, line_number) + { + } + }; + + //*************************************************************************** + ///\ingroup flat_multiset + /// The base class for all templated flat_multiset types. + //*************************************************************************** + class flat_multiset_base + { + public: + + typedef size_t size_type; + + protected: + + protected: + + etl::debug_count construct_count; + + //************************************************************************* + /// Constructor. + //************************************************************************* + flat_multiset_base() + { + } + }; + + //*************************************************************************** + /// The base class for specifically sized flat_multisets. + /// Can be used as a reference type for all flat_multisets containing a specific type. + ///\ingroup flat_multiset + //*************************************************************************** + template > + class iflat_multiset : public etl::flat_multiset_base + { + public: + + typedef T key_type; + typedef T value_type; + + private: + + typedef etl::ivector lookup_t; + typedef etl::ipool storage_t; + + public: + + 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; + } + + const_reference operator *() const + { + return *(*ilookup); + } + + const_pointer operator &() const + { + 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 etl::parameter_type::type parameter_t; + + public: + + //********************************************************************* + /// Returns an iterator to the beginning of the flat_multiset. + ///\return An iterator to the beginning of the flat_multiset. + //********************************************************************* + iterator begin() + { + return iterator(lookup.begin()); + } + + //********************************************************************* + /// Returns a const_iterator to the beginning of the flat_multiset. + ///\return A const iterator to the beginning of the flat_multiset. + //********************************************************************* + const_iterator begin() const + { + return const_iterator(lookup.begin()); + } + + //********************************************************************* + /// Returns an iterator to the end of the flat_multiset. + ///\return An iterator to the end of the flat_multiset. + //********************************************************************* + iterator end() + { + return iterator(lookup.end()); + } + + //********************************************************************* + /// Returns a const_iterator to the end of the flat_multiset. + ///\return A const iterator to the end of the flat_multiset. + //********************************************************************* + const_iterator end() const + { + return const_iterator(lookup.end()); + } + + //********************************************************************* + /// Returns a const_iterator to the beginning of the flat_multiset. + ///\return A const iterator to the beginning of the flat_multiset. + //********************************************************************* + const_iterator cbegin() const + { + return const_iterator(lookup.cbegin()); + } + + //********************************************************************* + /// Returns a const_iterator to the end of the flat_multiset. + ///\return A const iterator to the end of the flat_multiset. + //********************************************************************* + const_iterator cend() const + { + return const_iterator(lookup.cend()); + } + + //********************************************************************* + /// Returns an reverse iterator to the reverse beginning of the flat_multiset. + ///\return Iterator to the reverse beginning of the flat_multiset. + //********************************************************************* + reverse_iterator rbegin() + { + return reverse_iterator(lookup.rbegin()); + } + + //********************************************************************* + /// Returns a const reverse iterator to the reverse beginning of the flat_multiset. + ///\return Const iterator to the reverse beginning of the flat_multiset. + //********************************************************************* + const_reverse_iterator rbegin() const + { + return const_reverse_iterator(lookup.rbegin()); + } + + //********************************************************************* + /// Returns a reverse iterator to the end + 1 of the flat_multiset. + ///\return Reverse iterator to the end + 1 of the flat_multiset. + //********************************************************************* + reverse_iterator rend() + { + return reverse_iterator(lookup.rend()); + } + + //********************************************************************* + /// Returns a const reverse iterator to the end + 1 of the flat_multiset. + ///\return Const reverse iterator to the end + 1 of the flat_multiset. + //********************************************************************* + const_reverse_iterator rend() const + { + return const_reverse_iterator(lookup.rend()); + } + + //********************************************************************* + /// Returns a const reverse iterator to the reverse beginning of the flat_multiset. + ///\return Const reverse iterator to the reverse beginning of the flat_multiset. + //********************************************************************* + const_reverse_iterator crbegin() const + { + return const_reverse_iterator(lookup.crbegin()); + } + + //********************************************************************* + /// Returns a const reverse iterator to the end + 1 of the flat_multiset. + ///\return Const reverse iterator to the end + 1 of the flat_multiset. + //********************************************************************* + const_reverse_iterator crend() const + { + return const_reverse_iterator(lookup.crend()); + } + + //********************************************************************* + /// Assigns values to the flat_multiset. + /// If asserts or exceptions are enabled, emits flat_multiset_full if the flat_multiset does not have enough free space. + /// If asserts or exceptions are enabled, emits flat_multiset_iterator if the iterators are reversed. + ///\param first The iterator to the first element. + ///\param last The iterator to the last element + 1. + //********************************************************************* + template + void assign(TIterator first, TIterator last) + { +#if defined(ETL_DEBUG) + difference_type count = std::distance(first, last); + ETL_ASSERT(count <= difference_type(capacity()), ETL_ERROR(flat_multiset_full)); +#endif + + clear(); + + while (first != last) + { + insert(*first++); + } + } + + //********************************************************************* + /// Inserts a value to the flat_multiset. + /// If asserts or exceptions are enabled, emits flat_multiset_full if the flat_multiset is already full. + ///\param value The value to insert. + //********************************************************************* + std::pair insert(parameter_t value) + { + std::pair result(end(), false); + + 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. + 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; + } + + //********************************************************************* + /// Inserts a value to the flat_multiset. + /// If asserts or exceptions are enabled, emits flat_multiset_full if the flat_multiset is already full. + ///\param position The position to insert at. + ///\param value The value to insert. + //********************************************************************* + iterator insert(iterator position, parameter_t value) + { + return insert(value).first; + } + + //********************************************************************* + /// Inserts a range of values to the flat_multiset. + /// If asserts or exceptions are enabled, emits flat_multiset_full if the flat_multiset does not have enough free space. + ///\param position The position to insert at. + ///\param first The first element to add. + ///\param last The last + 1 element to add. + //********************************************************************* + template + void insert(TIterator first, TIterator last) + { + while (first != last) + { + insert(*first++); + } + } + + //********************************************************************* + /// Erases an element. + ///\param key The key to erase. + ///\return The number of elements erased. 0 or 1. + //********************************************************************* + size_t erase(parameter_t key) + { + std::pair range = equal_range(key); + + if (range.first == end()) + { + return 0; + } + else + { + size_t count = std::distance(range.first, range.second); + erase(range.first, range.second); + return count; + } + } + + //********************************************************************* + /// Erases an element. + ///\param i_element Iterator to the element. + //********************************************************************* + void erase(iterator i_element) + { + i_element->~value_type(); + storage.release(etl::addressof(*i_element)); + lookup.erase(i_element.ilookup); + --construct_count; + } + + //********************************************************************* + /// Erases a range of elements. + /// The range includes all the elements between first and last, including the + /// element pointed by first, but not the one pointed by last. + ///\param first Iterator to the first element. + ///\param last Iterator to the last element. + //********************************************************************* + void erase(iterator first, iterator last) + { + iterator itr = first; + + while (itr != last) + { + itr->~value_type(); + storage.release(etl::addressof(*itr)); + ++itr; + --construct_count; + } + + lookup.erase(first.ilookup, last.ilookup); + } + + //************************************************************************* + /// Clears the flat_multiset. + //************************************************************************* + void clear() + { + erase(begin(), end()); + } + + //********************************************************************* + /// Finds an element. + ///\param key The key to search for. + ///\return An iterator pointing to the element or end() if not found. + //********************************************************************* + iterator find(parameter_t key) + { + iterator itr = std::lower_bound(begin(), end(), key, TKeyCompare()); + + if (itr != end()) + { + if (!key_compare()(*itr, key) && !key_compare()(key, *itr)) + { + return itr; + } + else + { + return end(); + } + } + + return end(); + } + + //********************************************************************* + /// Finds an element. + ///\param key The key to search for. + ///\return An iterator pointing to the element or end() if not found. + //********************************************************************* + const_iterator find(parameter_t key) const + { + const_iterator itr = std::lower_bound(begin(), end(), key, TKeyCompare()); + + if (itr != end()) + { + if (!key_compare()(*itr, key) && !key_compare()(key, *itr)) + { + return itr; + } + else + { + return end(); + } + } + + return end(); + } + + //********************************************************************* + /// Counts an element. + ///\param key The key to search for. + ///\return 1 if the key exists, otherwise 0. + //********************************************************************* + size_t count(parameter_t key) const + { + std::pair range = equal_range(key); + + return std::distance(range.first, range.second); + } + + //********************************************************************* + /// Finds the lower bound of a key + ///\param key The key to search for. + ///\return An iterator. + //********************************************************************* + iterator lower_bound(parameter_t key) + { + return std::lower_bound(begin(), end(), key, TKeyCompare()); + } + + //********************************************************************* + /// Finds the lower bound of a key + ///\param key The key to search for. + ///\return An iterator. + //********************************************************************* + const_iterator lower_bound(parameter_t key) const + { + return std::lower_bound(cbegin(), cend(), key, TKeyCompare()); + } + + //********************************************************************* + /// Finds the upper bound of a key + ///\param key The key to search for. + ///\return An iterator. + //********************************************************************* + iterator upper_bound(parameter_t key) + { + return std::upper_bound(begin(), end(), key, TKeyCompare()); + } + + //********************************************************************* + /// Finds the upper bound of a key + ///\param key The key to search for. + ///\return An iterator. + //********************************************************************* + const_iterator upper_bound(parameter_t key) const + { + return std::upper_bound(cbegin(), cend(), key, TKeyCompare()); + } + + //********************************************************************* + /// Finds the range of equal elements of a key + ///\param key The key to search for. + ///\return An iterator pair. + //********************************************************************* + std::pair equal_range(parameter_t key) + { + return std::equal_range(begin(), end(), key, TKeyCompare()); + } + + //********************************************************************* + /// Finds the range of equal elements of a key + ///\param key The key to search for. + ///\return An iterator pair. + //********************************************************************* + std::pair equal_range(parameter_t key) const + { + return std::equal_range(cbegin(), cend(), key, TKeyCompare()); + } + + //************************************************************************* + /// Assignment operator. + //************************************************************************* + iflat_multiset& operator = (const iflat_multiset& rhs) + { + if (&rhs != this) + { + assign(rhs.cbegin(), rhs.cend()); + } + + return *this; + } + + //************************************************************************* + /// Gets the current size of the flat_multiset. + ///\return The current size of the flat_multiset. + //************************************************************************* + size_type size() const + { + return lookup.size(); + } + + //************************************************************************* + /// Checks the 'empty' state of the flat_multiset. + ///\return true if empty. + //************************************************************************* + bool empty() const + { + return lookup.empty(); + } + + //************************************************************************* + /// Checks the 'full' state of the flat_multiset. + ///\return true if full. + //************************************************************************* + bool full() const + { + return lookup.full(); + } + + //************************************************************************* + /// Returns the capacity of the flat_multiset. + ///\return The capacity of the flat_multiset. + //************************************************************************* + size_type capacity() const + { + return lookup.capacity(); + } + + //************************************************************************* + /// Returns the maximum possible size of the flat_multiset. + ///\return The maximum size of the flat_multiset. + //************************************************************************* + size_type max_size() const + { + return lookup.max_size(); + } + + //************************************************************************* + /// Returns the remaining capacity. + ///\return The remaining capacity. + //************************************************************************* + size_t available() const + { + return lookup.available(); + } + + protected: + + //********************************************************************* + /// Constructor. + //********************************************************************* + iflat_multiset(lookup_t& lookup_, storage_t& storage_) + : lookup(lookup_), + storage(storage_) + { + } + + private: + + // Disable copy construction. + iflat_multiset(const iflat_multiset&); + + lookup_t& lookup; + storage_t& storage; + }; + + //*************************************************************************** + /// Equal operator. + ///\param lhs Reference to the first flat_multiset. + ///\param rhs Reference to the second flat_multiset. + ///\return true if the arrays are equal, otherwise false + ///\ingroup flat_multiset + //*************************************************************************** + template + bool operator ==(const etl::iflat_multiset& lhs, const etl::iflat_multiset& rhs) + { + return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin()); + } + + //*************************************************************************** + /// Not equal operator. + ///\param lhs Reference to the first flat_multiset. + ///\param rhs Reference to the second flat_multiset. + ///\return true if the arrays are not equal, otherwise false + ///\ingroup flat_multiset + //*************************************************************************** + template + bool operator !=(const etl::iflat_multiset& lhs, const etl::iflat_multiset& rhs) + { + return !(lhs == rhs); + } + //*************************************************************************** /// A flat_multiset implementation that uses a fixed size buffer. ///\tparam T The value type. @@ -57,7 +841,8 @@ namespace etl ///\tparam MAX_SIZE_ The maximum number of elements that can be stored. ///\ingroup flat_multiset //*************************************************************************** - class flat_multiset : public iflat_multiset + template > + class flat_multiset : public etl::iflat_multiset { public: @@ -67,7 +852,7 @@ namespace etl /// Constructor. //************************************************************************* flat_multiset() - : iflat_multiset(lookup, storage) + : etl::iflat_multiset(lookup, storage) { } @@ -77,7 +862,7 @@ namespace etl flat_multiset(const flat_multiset& other) : iflat_multiset(lookup, storage) { - iflat_multiset::assign(other.cbegin(), other.cend()); + etl::iflat_multiset::assign(other.cbegin(), other.cend()); } //************************************************************************* @@ -90,7 +875,7 @@ namespace etl flat_multiset(TIterator first, TIterator last) : iflat_multiset(lookup, storage) { - iflat_multiset::assign(first, last); + etl::iflat_multiset::assign(first, last); } //************************************************************************* @@ -98,7 +883,7 @@ namespace etl //************************************************************************* ~flat_multiset() { - iflat_multiset::clear(); + etl::iflat_multiset::clear(); } //************************************************************************* @@ -108,7 +893,7 @@ namespace etl { if (&rhs != this) { - iflat_multiset::assign(rhs.cbegin(), rhs.cend()); + etl::iflat_multiset::assign(rhs.cbegin(), rhs.cend()); } return *this; @@ -116,7 +901,7 @@ namespace etl private: - typedef typename iflat_multiset::value_type node_t; + typedef typename etl::iflat_multiset::value_type node_t; // The pool of nodes. etl::pool storage; @@ -126,4 +911,6 @@ namespace etl }; } +#undef ETL_FILE + #endif diff --git a/src/flat_set.h b/src/flat_set.h index c5df9fc0..44f46ec3 100644 --- a/src/flat_set.h +++ b/src/flat_set.h @@ -338,7 +338,7 @@ namespace etl protected: - typedef typename parameter_type::type parameter_t; + typedef typename etl::parameter_type::type parameter_t; public: diff --git a/src/list.h b/src/list.h index 9617cabf..3d1191a0 100644 --- a/src/list.h +++ b/src/list.h @@ -333,7 +333,7 @@ namespace etl protected: - typedef typename parameter_type::value || is_pointer::value>::type parameter_t; + typedef typename etl::parameter_type::value || is_pointer::value>::type parameter_t; //************************************************************************* /// The data node element in the list. diff --git a/src/priority_queue.h b/src/priority_queue.h index 99cf461d..30525a11 100644 --- a/src/priority_queue.h +++ b/src/priority_queue.h @@ -128,7 +128,7 @@ namespace etl private: - typedef typename parameter_type::type parameter_t; + typedef typename etl::parameter_type::type parameter_t; public: diff --git a/src/queue.h b/src/queue.h index b72e4cef..282e09fe 100644 --- a/src/queue.h +++ b/src/queue.h @@ -195,7 +195,7 @@ namespace etl private: - typedef typename parameter_type::type parameter_t; + typedef typename etl::parameter_type::type parameter_t; public: diff --git a/src/stack.h b/src/stack.h index a19dfb4f..4224be47 100644 --- a/src/stack.h +++ b/src/stack.h @@ -194,7 +194,7 @@ namespace etl private: - typedef typename parameter_type::type parameter_t; + typedef typename etl::parameter_type::type parameter_t; public: diff --git a/src/vector.h b/src/vector.h index a6bfc5cb..5b78b160 100644 --- a/src/vector.h +++ b/src/vector.h @@ -89,7 +89,7 @@ namespace etl protected: - typedef typename parameter_type::type parameter_t; + typedef typename etl::parameter_type::type parameter_t; public: