Loading...
Searching...
No Matches
indirect_vector.h
Go to the documentation of this file.
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2019 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_INDIRECT_VECTOR_INCLUDED
#define ETL_INDIRECT_VECTOR_INCLUDED
#include "platform.h"
#include "functional.h"
#include "initializer_list.h"
#include "iterator.h"
#include "pool.h"
#include "static_assert.h"
#include "utility.h"
#include "vector.h"
//*****************************************************************************
//*****************************************************************************
namespace etl
{
//***************************************************************************
//***************************************************************************
class indirect_vector_buffer_missmatch : public vector_exception
{
public:
indirect_vector_buffer_missmatch(string_type file_name_, numeric_type line_number_)
: vector_exception(ETL_ERROR_TEXT("indirect_vector:buffer_missmatch", ETL_INDIRECT_VECTOR_FILE_ID"A"), file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
template <typename T>
class iindirect_vector
{
public:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
#if ETL_USING_CPP11
typedef T&& rvalue_reference;
#endif
typedef T* pointer;
typedef const T* const_pointer;
typedef typename etl::ivector<T*>::iterator indirect_iterator;
typedef typename etl::ivector<T*>::const_iterator indirect_const_iterator;
typedef typename etl::ivector<T*>::size_type size_type;
typedef typename etl::ivector<T*>::difference_type difference_type;
//*************************************************************************
//*************************************************************************
template <typename TUnaryFunction, typename TReturnType = void>
class unary_function_adaptor
{
public:
unary_function_adaptor(TUnaryFunction unary_function_)
: unary_function(unary_function_)
{
}
TReturnType operator()(const_pointer indirect_itr)
{
return unary_function(*indirect_itr);
}
TUnaryFunction unary_function;
};
//*************************************************************************
template <typename TUnaryFunction>
class unary_function_adaptor<TUnaryFunction, void>
{
public:
unary_function_adaptor(TUnaryFunction unary_function_)
: unary_function(unary_function_)
{
}
void operator()(const_pointer indirect_itr)
{
unary_function(*indirect_itr);
}
TUnaryFunction unary_function;
};
//*************************************************************************
//*************************************************************************
template <typename TBinaryFunction, typename TReturnType = void>
class binary_function_adaptor
{
public:
binary_function_adaptor(TBinaryFunction binary_function_)
: binary_function(binary_function_)
{
}
TReturnType operator()(const_pointer indirect_itr_lhs, const_pointer indirect_itr_rhs)
{
return binary_function(*indirect_itr_lhs, *indirect_itr_rhs);
}
TBinaryFunction binary_function;
};
//*************************************************************************
template <typename TBinaryFunction>
class binary_function_adaptor<TBinaryFunction, void>
{
public:
binary_function_adaptor(TBinaryFunction binary_function_)
: binary_function(binary_function_)
{
}
void operator()(const_pointer indirect_itr_lhs, const_pointer indirect_itr_rhs)
{
binary_function(*indirect_itr_lhs, *indirect_itr_rhs);
}
TBinaryFunction binary_function;
};
//*************************************************************************
//*************************************************************************
class iterator : public etl::iterator<ETL_OR_STD::random_access_iterator_tag, T>
{
public:
friend class iindirect_vector;
friend class const_iterator;
iterator()
: lookup_itr()
{
}
iterator(const iterator& other)
: lookup_itr(other.lookup_itr)
{
}
iterator& operator++()
{
++lookup_itr;
return *this;
}
iterator operator++(int)
{
iterator temp(*this);
++lookup_itr;
return temp;
}
iterator& operator--()
{
--lookup_itr;
return *this;
}
iterator operator--(int)
{
iterator temp(*this);
--lookup_itr;
return temp;
}
iterator& operator=(const iterator& other)
{
lookup_itr = other.lookup_itr;
return *this;
}
iterator operator+=(difference_type n)
{
lookup_itr += n;
return *this;
}
iterator operator-=(difference_type n)
{
lookup_itr -= n;
return *this;
}
reference operator*() const
{
return **lookup_itr;
}
pointer operator&() const
{
return &(**lookup_itr);
}
pointer operator->() const
{
return &(**lookup_itr);
}
friend iterator operator+(const iterator& lhs, difference_type offset)
{
iterator result(lhs);
result += offset;
return result;
}
friend iterator operator-(const iterator& lhs, difference_type offset)
{
iterator result(lhs);
result -= offset;
return result;
}
indirect_iterator indirection()
{
return lookup_itr;
}
indirect_const_iterator indirection() const
{
return lookup_itr;
}
friend difference_type operator-(const iterator& lhs, const iterator& rhs)
{
return lhs.lookup_itr - rhs.lookup_itr;
}
friend bool operator==(const iterator& lhs, const iterator& rhs)
{
return lhs.lookup_itr == rhs.lookup_itr;
}
friend bool operator!=(const iterator& lhs, const iterator& rhs)
{
return !(lhs == rhs);
}
friend bool operator<(const iterator& lhs, const iterator& rhs)
{
return lhs.lookup_itr < rhs.lookup_itr;
}
friend bool operator<=(const iterator& lhs, const iterator& rhs)
{
return lhs.lookup_itr <= rhs.lookup_itr;
}
private:
iterator(indirect_iterator itr_)
: lookup_itr(itr_)
{
}
indirect_iterator lookup_itr;
};
//*************************************************************************
//*************************************************************************
class const_iterator : public etl::iterator<ETL_OR_STD::random_access_iterator_tag, const T>
{
public:
friend class iindirect_vector;
const_iterator()
: lookup_itr()
{
}
const_iterator(const const_iterator& other)
: lookup_itr(other.lookup_itr)
{
}
const_iterator(const typename iindirect_vector::iterator& other)
: lookup_itr(other.lookup_itr)
{
}
const_iterator& operator++()
{
++lookup_itr;
return *this;
}
const_iterator operator++(int)
{
const_iterator temp(*this);
++lookup_itr;
return temp;
}
const_iterator& operator--()
{
--lookup_itr;
return *this;
}
const_iterator operator--(int)
{
const_iterator temp(*this);
--lookup_itr;
return temp;
}
const_iterator operator+=(difference_type n)
{
lookup_itr += n;
return *this;
}
const_iterator operator-=(difference_type n)
{
lookup_itr -= n;
return *this;
}
const_iterator& operator=(const const_iterator& other)
{
lookup_itr = other.lookup_itr;
return *this;
}
const_reference operator*() const
{
return **lookup_itr;
}
const_pointer operator&() const
{
return &(**lookup_itr);
}
const_pointer operator->() const
{
return &(**lookup_itr);
}
indirect_const_iterator indirection() const
{
return lookup_itr;
}
friend const_iterator operator+(const const_iterator& lhs, difference_type offset)
{
const_iterator result(lhs);
result += offset;
return result;
}
friend const_iterator operator-(const const_iterator& lhs, difference_type offset)
{
const_iterator result(lhs);
result -= offset;
return result;
}
friend difference_type operator-(const const_iterator& lhs, const const_iterator& rhs)
{
return lhs.lookup_itr - rhs.lookup_itr;
}
friend bool operator==(const const_iterator& lhs, const const_iterator& rhs)
{
return lhs.lookup_itr == rhs.lookup_itr;
}
friend bool operator!=(const const_iterator& lhs, const const_iterator& rhs)
{
return !(lhs == rhs);
}
friend bool operator<(const const_iterator& lhs, const const_iterator& rhs)
{
return lhs.lookup_itr < rhs.lookup_itr;
}
friend bool operator<=(const const_iterator& lhs, const const_iterator& rhs)
{
return lhs.lookup_itr <= rhs.lookup_itr;
}
private:
typedef typename etl::ivector<T*>::const_iterator lookup_itr_t;
const_iterator(indirect_const_iterator itr_)
: lookup_itr(itr_)
{
}
indirect_const_iterator lookup_itr;
};
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
protected:
typedef typename etl::parameter_type<T>::type parameter_t;
public:
//*********************************************************************
//*********************************************************************
iterator begin()
{
return iterator(lookup.begin());
}
//*********************************************************************
//*********************************************************************
const_iterator begin() const
{
return const_iterator(lookup.begin());
}
//*********************************************************************
//*********************************************************************
iterator end()
{
return iterator(lookup.end());
}
//*********************************************************************
//*********************************************************************
const_iterator end() const
{
return const_iterator(lookup.end());
}
//*********************************************************************
//*********************************************************************
const_iterator cbegin() const
{
return const_iterator(lookup.begin());
}
//*********************************************************************
//*********************************************************************
const_iterator cend() const
{
return const_iterator(lookup.cend());
}
//*********************************************************************
//*********************************************************************
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
//*********************************************************************
//*********************************************************************
const_reverse_iterator rbegin() const
{
return const_reverse_iterator(end());
}
//*********************************************************************
//*********************************************************************
reverse_iterator rend()
{
return reverse_iterator(begin());
}
//*********************************************************************
//*********************************************************************
const_reverse_iterator rend() const
{
return const_reverse_iterator(begin());
}
//*********************************************************************
//*********************************************************************
const_reverse_iterator crbegin() const
{
return const_reverse_iterator(cend());
}
//*********************************************************************
//*********************************************************************
const_reverse_iterator crend() const
{
return const_reverse_iterator(cbegin());
}
//*********************************************************************
//*********************************************************************
void resize(size_t new_size)
{
resize(new_size, T());
}
//*********************************************************************
//*********************************************************************
void resize(size_t new_size, const_reference value)
{
ETL_ASSERT(new_size <= capacity(), ETL_ERROR(vector_full));
if (new_size <= capacity())
{
if (new_size > size())
{
size_type n = new_size - size();
while (n-- != 0U)
{
T* p = storage.create<T>(value);
lookup.push_back(p);
}
}
else
{
size_type n = size() - new_size;
while (n-- != 0U)
{
pop_back();
}
}
}
}
//*********************************************************************
//*********************************************************************
void reserve(size_t n)
{
(void)n; // Stop 'unused parameter' warning in release mode.
ETL_ASSERT(n <= capacity(), ETL_ERROR(vector_out_of_bounds));
}
//*********************************************************************
//*********************************************************************
reference operator[](size_t i)
{
return *lookup[i];
}
//*********************************************************************
//*********************************************************************
const_reference operator[](size_t i) const
{
return *lookup[i];
}
//*********************************************************************
//*********************************************************************
reference at(size_t i)
{
return *lookup.at(i);
}
//*********************************************************************
//*********************************************************************
const_reference at(size_t i) const
{
return *lookup.at(i);
}
//*********************************************************************
//*********************************************************************
reference front()
{
return *(lookup.front());
}
//*********************************************************************
//*********************************************************************
const_reference front() const
{
return *(lookup.front());
}
//*********************************************************************
//*********************************************************************
reference back()
{
return *(lookup.back());
}
//*********************************************************************
//*********************************************************************
const_reference back() const
{
return *(lookup.back());
}
//*********************************************************************
//*********************************************************************
template <typename TIterator>
void assign(TIterator first, TIterator last)
{
ETL_STATIC_ASSERT((etl::is_same<typename etl::remove_cv<T>::type,
typename etl::remove_cv< typename etl::iterator_traits< TIterator>::value_type>::type>::value),
"Iterator type does not match container type");
#if ETL_IS_DEBUG_BUILD
difference_type d = etl::distance(first, last);
ETL_ASSERT(static_cast<size_t>(d) <= capacity(), ETL_ERROR(vector_full));
#endif
initialise();
while (first != last)
{
T* p = storage.create<T>(*first);
lookup.push_back(p);
++first;
}
}
//*********************************************************************
//*********************************************************************
void assign(size_t n, parameter_t value)
{
ETL_ASSERT(n <= capacity(), ETL_ERROR(vector_full));
initialise();
while (n-- != 0U)
{
T* p = storage.create<T>(value);
lookup.push_back(p);
}
}
//*************************************************************************
//*************************************************************************
void clear()
{
initialise();
}
//*************************************************************************
//*************************************************************************
void fill(const T& value)
{
etl::fill(begin(), end(), value);
}
//*********************************************************************
//*********************************************************************
void push_back(const_reference value)
{
ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(vector_full));
T* p = storage.create<T>(value);
lookup.push_back(p);
}
#if ETL_USING_CPP11
//*********************************************************************
//*********************************************************************
void push_back(rvalue_reference value)
{
ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(vector_full));
T* p = storage.create<T>(etl::move(value));
lookup.push_back(p);
}
#endif
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_VECTOR_FORCE_CPP03_IMPLEMENTATION)
//*********************************************************************
//*********************************************************************
template <typename... Args>
reference emplace_back(Args&&... args)
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
T* p = storage.create<T>(etl::forward<Args>(args)...);
lookup.push_back(p);
return back();
}
#else
//*********************************************************************
//*********************************************************************
reference emplace_back()
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
T* p = storage.create<T>();
lookup.push_back(p);
return back();
}
//*********************************************************************
//*********************************************************************
template <typename T1>
reference emplace_back(const T1& value1)
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
T* p = storage.create<T>(value1);
lookup.push_back(p);
return back();
}
//*********************************************************************
//*********************************************************************
template <typename T1, typename T2>
reference emplace_back(const T1& value1, const T2& value2)
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
T* p = storage.create<T>(value1, value2);
lookup.push_back(p);
return back();
}
//*********************************************************************
//*********************************************************************
template <typename T1, typename T2, typename T3>
reference emplace_back(const T1& value1, const T2& value2, const T3& value3)
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
T* p = storage.create<T>(value1, value2, value3);
lookup.push_back(p);
return back();
}
//*********************************************************************
//*********************************************************************
template <typename T1, typename T2, typename T3, typename T4>
reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(vector_full));
T* p = storage.create<T>(value1, value2, value3, value4);
lookup.push_back(p);
return back();
}
#endif
//*************************************************************************
//*************************************************************************
void pop_back()
{
ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(vector_empty));
reference object = back();
storage.destroy<T>(etl::addressof(object));
lookup.pop_back();
}
//*********************************************************************
//*********************************************************************
iterator insert(const_iterator position, const_reference value)
{
ETL_ASSERT(size() != capacity(), ETL_ERROR(vector_full));
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
T* p = storage.create<T>(value);
position = iterator(lookup.insert(position.lookup_itr, p));
return to_iterator(position);
}
#if ETL_USING_CPP11
//*********************************************************************
//*********************************************************************
iterator insert(const_iterator position, rvalue_reference value)
{
ETL_ASSERT(size() != capacity(), ETL_ERROR(vector_full));
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
T* p = storage.create<T>(etl::move(value));
position = iterator(lookup.insert(position.lookup_itr, p));
return to_iterator(position);
}
#endif
//*************************************************************************
//*************************************************************************
#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_VECTOR_FORCE_CPP03_IMPLEMENTATION)
template <typename... Args>
iterator emplace(const_iterator position, Args&&... args)
{
ETL_ASSERT(!full(), ETL_ERROR(vector_full));
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
T* p = storage.create<T>(etl::forward<Args>(args)...);
position = iterator(lookup.insert(position.lookup_itr, p));
return to_iterator(position);
}
#else
iterator emplace(const_iterator position)
{
ETL_ASSERT(!full(), ETL_ERROR(vector_full));
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
T* p = storage.create<T>();
position = iterator(lookup.insert(position.lookup_itr, p));
return to_iterator(position);
}
template <typename T1>
iterator emplace(const_iterator position, const T1& value1)
{
ETL_ASSERT(!full(), ETL_ERROR(vector_full));
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
T* p = storage.create<T>(value1);
position = iterator(lookup.insert(position.lookup_itr, p));
return to_iterator(position);
}
template <typename T1, typename T2>
iterator emplace(const_iterator position, const T1& value1, const T2& value2)
{
ETL_ASSERT(!full(), ETL_ERROR(vector_full));
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
T* p = storage.create<T>(value1, value2);
position = iterator(lookup.insert(position.lookup_itr, p));
return to_iterator(position);
}
template <typename T1, typename T2, typename T3>
iterator emplace(const_iterator position, const T1& value1, const T2& value2, const T3& value3)
{
ETL_ASSERT(!full(), ETL_ERROR(vector_full));
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
T* p = storage.create<T>(value1, value2, value3);
position = iterator(lookup.insert(position.lookup_itr, p));
return to_iterator(position);
}
template <typename T1, typename T2, typename T3, typename T4>
iterator emplace(const_iterator position, const T1& value1, const T2& value2, const T3& value3, const T4& value4)
{
ETL_ASSERT(!full(), ETL_ERROR(vector_full));
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
T* p = storage.create<T>(value1, value2, value3, value4);
position = iterator(lookup.insert(position.lookup_itr, p));
return to_iterator(position);
}
#endif
//*********************************************************************
//*********************************************************************
iterator insert(const_iterator position, size_t n, parameter_t value)
{
ETL_ASSERT((size() + n) <= capacity(), ETL_ERROR(vector_full));
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
iterator position_ = to_iterator(position);
// Make space for the new lookup pointers.
typename etl::ivector<T*>::iterator lookup_itr = position_.lookup_itr;
lookup.insert(lookup_itr, n, ETL_NULLPTR);
while (n-- != 0U)
{
T* p = storage.create<T>(value);
*lookup_itr++ = p;
}
return position_;
}
//*********************************************************************
//*********************************************************************
template <class TIterator>
iterator insert(const_iterator position, TIterator first, TIterator last)
{
size_t count = size_t(etl::distance(first, last));
ETL_ASSERT((size() + count) <= capacity(), ETL_ERROR(vector_full));
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(vector_out_of_bounds));
// Make space for the new lookup pointers.
typename etl::ivector<T*>::iterator lookup_itr = to_iterator(position).lookup_itr;
lookup.insert(lookup_itr, count, ETL_NULLPTR);
while (first != last)
{
T* p = storage.create<T>(*first);
*lookup_itr++ = p;
++first;
}
return to_iterator(position);
}
//*********************************************************************
//*********************************************************************
iterator erase(iterator i_element)
{
ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(vector_out_of_bounds));
storage.destroy<T>(etl::addressof(*i_element));
return iterator(lookup.erase(i_element.lookup_itr));
}
//*********************************************************************
//*********************************************************************
iterator erase(const_iterator i_element)
{
ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(vector_out_of_bounds));
storage.destroy<T>(etl::addressof(*i_element));
return iterator(lookup.erase(i_element.lookup_itr));
}
//*********************************************************************
//*********************************************************************
iterator erase(const_iterator first, const_iterator last)
{
ETL_ASSERT_CHECK_EXTRA(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(vector_out_of_bounds));
iterator element = to_iterator(first);
while (element != last)
{
storage.destroy<T>(etl::addressof(*element));
++element;
}
lookup.erase(first.lookup_itr, last.lookup_itr);
return to_iterator(last);
}
//*************************************************************************
//*************************************************************************
iindirect_vector& operator=(const iindirect_vector& rhs)
{
if (&rhs != this)
{
assign(rhs.cbegin(), rhs.cend());
}
return *this;
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
iindirect_vector& operator=(iindirect_vector&& rhs)
{
if (&rhs != this)
{
clear();
iterator itr = rhs.begin();
while (itr != rhs.end())
{
push_back(etl::move(*itr));
++itr;
}
rhs.initialise();
}
return *this;
}
#endif
//*************************************************************************
//*************************************************************************
size_type size() const
{
return lookup.size();
}
//*************************************************************************
//*************************************************************************
size_type capacity() const
{
return lookup.capacity();
}
//*************************************************************************
//*************************************************************************
bool empty() const
{
return lookup.empty();
}
//*************************************************************************
//*************************************************************************
bool full() const
{
return lookup.full();
}
//*************************************************************************
//*************************************************************************
size_type max_size() const
{
return lookup.max_size();
}
//*************************************************************************
//*************************************************************************
size_type available() const
{
return lookup.available();
}
protected:
//*********************************************************************
//*********************************************************************
iindirect_vector(etl::ivector<T*>& lookup_, etl::ipool& storage_)
: lookup(lookup_)
, storage(storage_)
{
}
//*********************************************************************
//*********************************************************************
void initialise()
{
if ETL_IF_CONSTEXPR (etl::is_trivially_destructible<T>::value)
{
storage.release_all();
}
else
{
iterator itr = begin();
while (itr != end())
{
storage.destroy<T>(etl::addressof(*itr));
++itr;
}
}
lookup.clear();
}
#if ETL_USING_CPP11
//*********************************************************************
//*********************************************************************
void move_container(iindirect_vector&& other)
{
if (this != &other)
{
initialise();
typename iindirect_vector<T>::iterator itr = other.begin();
while (itr != other.end())
{
push_back(etl::move(*itr));
++itr;
}
other.initialise();
}
}
#endif
etl::ivector<T*>& lookup;
etl::ipool& storage;
private:
// Disable copy construction.
iindirect_vector(const iindirect_vector&) ETL_DELETE;
//*************************************************************************
//*************************************************************************
#if defined(ETL_POLYMORPHIC_INDIRECT_VECTOR) || defined(ETL_POLYMORPHIC_CONTAINERS)
public:
virtual
#else
protected:
#endif
~iindirect_vector()
{
}
protected:
//*************************************************************************
//*************************************************************************
iterator to_iterator(const_iterator itr) const
{
return iterator(const_cast<indirect_iterator>(itr.lookup_itr));
}
};
//***************************************************************************
//***************************************************************************
template <typename T>
bool operator==(const etl::iindirect_vector<T>& lhs, const etl::iindirect_vector<T>& rhs)
{
return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin());
}
//***************************************************************************
//***************************************************************************
template <typename T>
bool operator!=(const etl::iindirect_vector<T>& lhs, const etl::iindirect_vector<T>& rhs)
{
return !(lhs == rhs);
}
//***************************************************************************
//***************************************************************************
template <typename T>
bool operator<(const etl::iindirect_vector<T>& lhs, const etl::iindirect_vector<T>& rhs)
{
return etl::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
//***************************************************************************
//***************************************************************************
template <typename T>
bool operator>(const etl::iindirect_vector<T>& lhs, const etl::iindirect_vector<T>& rhs)
{
return (rhs < lhs);
}
//***************************************************************************
//***************************************************************************
template <typename T>
bool operator<=(const etl::iindirect_vector<T>& lhs, const etl::iindirect_vector<T>& rhs)
{
return !(lhs > rhs);
}
//***************************************************************************
//***************************************************************************
template <typename T>
bool operator>=(const etl::iindirect_vector<T>& lhs, const etl::iindirect_vector<T>& rhs)
{
return !(lhs < rhs);
}
//***************************************************************************
//***************************************************************************
template <typename T, const size_t MAX_SIZE_>
class indirect_vector : public etl::iindirect_vector<T>
{
public:
ETL_STATIC_ASSERT((MAX_SIZE_ > 0U), "Zero capacity etl::indirect_vector is not valid");
static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_;
//*************************************************************************
//*************************************************************************
indirect_vector()
: etl::iindirect_vector<T>(lookup_vector, storage_pool)
{
}
//*************************************************************************
//*************************************************************************
explicit indirect_vector(size_t initial_size)
: etl::iindirect_vector<T>(lookup_vector, storage_pool)
{
this->resize(initial_size);
}
//*************************************************************************
//*************************************************************************
indirect_vector(size_t initial_size, typename etl::iindirect_vector<T>::parameter_t value)
: etl::iindirect_vector<T>(lookup_vector, storage_pool)
{
this->resize(initial_size, value);
}
//*************************************************************************
//*************************************************************************
template <typename TIterator>
indirect_vector(TIterator first, TIterator last)
: etl::iindirect_vector<T>(lookup_vector, storage_pool)
{
this->assign(first, last);
}
#if ETL_HAS_INITIALIZER_LIST
//*************************************************************************
//*************************************************************************
indirect_vector(std::initializer_list<T> init)
: etl::iindirect_vector<T>(lookup_vector, storage_pool)
{
this->assign(init.begin(), init.end());
}
#endif
//*************************************************************************
//*************************************************************************
indirect_vector(const indirect_vector& other)
: etl::iindirect_vector<T>(lookup_vector, storage_pool)
{
this->assign(other.begin(), other.end());
}
//*************************************************************************
//*************************************************************************
indirect_vector& operator=(const indirect_vector& rhs)
{
if (&rhs != this)
{
this->assign(rhs.cbegin(), rhs.cend());
}
return *this;
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
indirect_vector(indirect_vector&& other)
: etl::iindirect_vector<T>(lookup_vector, storage_pool)
{
this->move_container(etl::move(other));
}
//*************************************************************************
//*************************************************************************
indirect_vector& operator=(indirect_vector&& rhs)
{
this->move_container(etl::move(rhs));
return *this;
}
#endif
//*************************************************************************
//*************************************************************************
~indirect_vector()
{
this->clear();
}
private:
etl::vector<T*, MAX_SIZE> lookup_vector;
etl::pool<T, MAX_SIZE> storage_pool;
};
template <typename T, const size_t MAX_SIZE_>
ETL_CONSTANT size_t indirect_vector<T, MAX_SIZE_>::MAX_SIZE;
//*************************************************************************
//*************************************************************************
#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST
template <typename T, typename... Ts>
indirect_vector(T, Ts...) -> indirect_vector<etl::enable_if_t<(etl::is_same_v<T, Ts> && ...), T>, 1U + sizeof...(Ts)>;
#endif
//*************************************************************************
//*************************************************************************
#if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST
template <typename... T>
constexpr auto make_indirect_vector(T&&... t) -> etl::indirect_vector<typename etl::common_type_t<T...>, sizeof...(T)>
{
return {etl::forward<T>(t)...};
}
#endif
//***************************************************************************
//***************************************************************************
template <typename T>
class indirect_vector_ext : public etl::iindirect_vector<T>
{
public:
//*************************************************************************
//*************************************************************************
indirect_vector_ext(etl::ivector<T*>& lookup_, etl::ipool& pool_)
: etl::iindirect_vector<T>(lookup_, pool_)
{
ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
}
//*************************************************************************
//*************************************************************************
explicit indirect_vector_ext(size_t initial_size, etl::ivector<T*>& lookup_, etl::ipool& pool_)
: etl::iindirect_vector<T>(lookup_, pool_)
{
ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
this->resize(initial_size);
}
//*************************************************************************
//*************************************************************************
indirect_vector_ext(size_t initial_size, typename etl::iindirect_vector<T>::parameter_t value, etl::ivector<T*>& lookup_, etl::ipool& pool_)
: etl::iindirect_vector<T>(lookup_, pool_)
{
ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
this->resize(initial_size, value);
}
//*************************************************************************
//*************************************************************************
template <typename TIterator>
indirect_vector_ext(TIterator first, TIterator last, etl::ivector<T*>& lookup_, etl::ipool& pool_)
: etl::iindirect_vector<T>(lookup_, pool_)
{
ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
this->assign(first, last);
}
#if ETL_HAS_INITIALIZER_LIST
//*************************************************************************
//*************************************************************************
indirect_vector_ext(std::initializer_list<T> init, etl::ivector<T*>& lookup_, etl::ipool& pool_)
: etl::iindirect_vector<T>(lookup_, pool_)
{
ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
this->assign(init.begin(), init.end());
}
#endif
//*************************************************************************
//*************************************************************************
indirect_vector_ext(const indirect_vector_ext& other, etl::ivector<T*>& lookup_, etl::ipool& pool_)
: etl::iindirect_vector<T>(lookup_, pool_)
{
ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
this->assign(other.begin(), other.end());
}
//*************************************************************************
//*************************************************************************
indirect_vector_ext(const indirect_vector_ext& other) ETL_DELETE;
//*************************************************************************
//*************************************************************************
indirect_vector_ext& operator=(const indirect_vector_ext& rhs)
{
if (&rhs != this)
{
this->assign(rhs.cbegin(), rhs.cend());
}
return *this;
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
indirect_vector_ext(indirect_vector_ext&& other, etl::ivector<T*>& lookup_, etl::ipool& pool_)
: etl::iindirect_vector<T>(lookup_, pool_)
{
ETL_ASSERT(lookup_.capacity() <= pool_.capacity(), ETL_ERROR(indirect_vector_buffer_missmatch));
this->move_container(etl::move(other));
}
//*************************************************************************
//*************************************************************************
indirect_vector_ext(indirect_vector_ext&& other) ETL_DELETE;
//*************************************************************************
//*************************************************************************
indirect_vector_ext& operator=(indirect_vector_ext&& rhs)
{
this->move_container(etl::move(rhs));
return *this;
}
#endif
//*************************************************************************
//*************************************************************************
~indirect_vector_ext()
{
this->clear();
}
};
} // namespace etl
#endif
etl::iindirect_vector::const_iterator
const_iterator.
Definition indirect_vector.h:314
etl::iindirect_vector::iterator
iterator.
Definition indirect_vector.h:176
etl::ivector
Definition vector.h:65
functional.h
etl::const_iterator
ETL_ASSERT
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
etl::iindirect_vector::at
reference at(size_t i)
Definition indirect_vector.h:656
etl::iindirect_vector::crend
const_reverse_iterator crend() const
Definition indirect_vector.h:565
etl::iindirect_vector::resize
void resize(size_t new_size)
Definition indirect_vector.h:576
etl::iindirect_vector::to_iterator
iterator to_iterator(const_iterator itr) const
Convert from const_iterator to iterator.
Definition indirect_vector.h:1327
etl::iindirect_vector::clear
void clear()
Clears the indirect_vector.
Definition indirect_vector.h:771
etl::indirect_vector_ext::operator=
indirect_vector_ext & operator=(const indirect_vector_ext &rhs)
Assignment operator.
Definition indirect_vector.h:1648
etl::indirect_vector_ext::indirect_vector_ext
indirect_vector_ext(size_t initial_size, typename etl::iindirect_vector< T >::parameter_t value, etl::ivector< T * > &lookup_, etl::ipool &pool_)
Definition indirect_vector.h:1597
etl::indirect_vector::~indirect_vector
~indirect_vector()
Destructor.
Definition indirect_vector.h:1528
etl::iindirect_vector::assign
void assign(TIterator first, TIterator last)
Definition indirect_vector.h:727
etl::iindirect_vector::available
size_type available() const
Definition indirect_vector.h:1236
etl::iindirect_vector::operator[]
const_reference operator[](size_t i) const
Definition indirect_vector.h:644
etl::indirect_vector_ext::indirect_vector_ext
indirect_vector_ext(const indirect_vector_ext &other) ETL_DELETE
Copy constructor (Deleted).
etl::iindirect_vector::back
reference back()
Definition indirect_vector.h:701
etl::iindirect_vector::operator=
iindirect_vector & operator=(const iindirect_vector &rhs)
Assignment operator.
Definition indirect_vector.h:1154
etl::iindirect_vector::end
iterator end()
Definition indirect_vector.h:480
etl::iindirect_vector::end
const_iterator end() const
Definition indirect_vector.h:489
etl::indirect_vector_ext::indirect_vector_ext
indirect_vector_ext(size_t initial_size, etl::ivector< T * > &lookup_, etl::ipool &pool_)
Definition indirect_vector.h:1585
etl::iindirect_vector::empty
bool empty() const
Definition indirect_vector.h:1209
etl::indirect_vector::indirect_vector
indirect_vector(size_t initial_size, typename etl::iindirect_vector< T >::parameter_t value)
Definition indirect_vector.h:1452
etl::iindirect_vector::emplace_back
reference emplace_back(const T1 &value1, const T2 &value2, const T3 &value3)
Definition indirect_vector.h:885
etl::iindirect_vector::rend
reverse_iterator rend()
Definition indirect_vector.h:536
etl::indirect_vector_ext::indirect_vector_ext
indirect_vector_ext(const indirect_vector_ext &other, etl::ivector< T * > &lookup_, etl::ipool &pool_)
Construct a copy.
Definition indirect_vector.h:1633
etl::iindirect_vector::emplace_back
reference emplace_back(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition indirect_vector.h:901
etl::iindirect_vector::erase
iterator erase(const_iterator i_element)
Definition indirect_vector.h:1116
etl::iindirect_vector::reserve
void reserve(size_t n)
Definition indirect_vector.h:623
etl::iindirect_vector::pop_back
void pop_back()
Removes an element from the end of the indirect_vector.
Definition indirect_vector.h:914
etl::iindirect_vector::full
bool full() const
Definition indirect_vector.h:1218
etl::iindirect_vector::size
size_type size() const
Definition indirect_vector.h:1191
etl::iindirect_vector::cend
const_iterator cend() const
Definition indirect_vector.h:507
etl::iindirect_vector::assign
void assign(size_t n, parameter_t value)
Definition indirect_vector.h:755
etl::indirect_vector::indirect_vector
indirect_vector(const indirect_vector &other)
Copy constructor.
Definition indirect_vector.h:1485
etl::iindirect_vector::cbegin
const_iterator cbegin() const
Definition indirect_vector.h:498
etl::iindirect_vector::back
const_reference back() const
Definition indirect_vector.h:712
etl::iindirect_vector::front
const_reference front() const
Definition indirect_vector.h:690
etl::indirect_vector_ext::indirect_vector_ext
indirect_vector_ext(etl::ivector< T * > &lookup_, etl::ipool &pool_)
Constructor.
Definition indirect_vector.h:1575
etl::indirect_vector::indirect_vector
indirect_vector(size_t initial_size)
Definition indirect_vector.h:1441
etl::iindirect_vector::~iindirect_vector
~iindirect_vector()
Destructor.
Definition indirect_vector.h:1318
etl::indirect_vector::indirect_vector
indirect_vector()
Constructor.
Definition indirect_vector.h:1432
etl::iindirect_vector::max_size
size_type max_size() const
Definition indirect_vector.h:1227
etl::iindirect_vector::begin
const_iterator begin() const
Definition indirect_vector.h:471
etl::iindirect_vector::initialise
void initialise()
Initialise the indirect_vector.
Definition indirect_vector.h:1255
etl::indirect_vector_ext::~indirect_vector_ext
~indirect_vector_ext()
Destructor.
Definition indirect_vector.h:1688
etl::iindirect_vector::at
const_reference at(size_t i) const
Definition indirect_vector.h:668
etl::iindirect_vector::emplace_back
reference emplace_back(const T1 &value1, const T2 &value2)
Definition indirect_vector.h:869
etl::iindirect_vector::begin
iterator begin()
Definition indirect_vector.h:462
etl::iindirect_vector::fill
void fill(const T &value)
Fills the buffer.
Definition indirect_vector.h:779
etl::iindirect_vector::insert
iterator insert(const_iterator position, TIterator first, TIterator last)
Definition indirect_vector.h:1074
etl::iindirect_vector::emplace
iterator emplace(const_iterator position)
Emplaces a value to the vector at the specified position.
Definition indirect_vector.h:977
etl::iindirect_vector::rend
const_reverse_iterator rend() const
Definition indirect_vector.h:545
etl::iindirect_vector::rbegin
const_reverse_iterator rbegin() const
Definition indirect_vector.h:527
etl::iindirect_vector::resize
void resize(size_t new_size, const_reference value)
Definition indirect_vector.h:589
etl::iindirect_vector::erase
iterator erase(iterator i_element)
Definition indirect_vector.h:1101
etl::indirect_vector::indirect_vector
indirect_vector(TIterator first, TIterator last)
Definition indirect_vector.h:1465
etl::iindirect_vector::rbegin
reverse_iterator rbegin()
Definition indirect_vector.h:517
etl::iindirect_vector::crbegin
const_reverse_iterator crbegin() const
Definition indirect_vector.h:556
etl::indirect_vector::operator=
indirect_vector & operator=(const indirect_vector &rhs)
Assignment operator.
Definition indirect_vector.h:1494
etl::iindirect_vector::erase
iterator erase(const_iterator first, const_iterator last)
Definition indirect_vector.h:1134
etl::iindirect_vector::emplace_back
reference emplace_back(const T1 &value1)
Definition indirect_vector.h:853
etl::iindirect_vector::front
reference front()
Definition indirect_vector.h:679
etl::indirect_vector_ext::indirect_vector_ext
indirect_vector_ext(TIterator first, TIterator last, etl::ivector< T * > &lookup_, etl::ipool &pool_)
Definition indirect_vector.h:1611
etl::iindirect_vector::emplace_back
reference emplace_back()
Definition indirect_vector.h:837
etl::iindirect_vector::capacity
size_type capacity() const
Definition indirect_vector.h:1200
etl::iindirect_vector::iindirect_vector
iindirect_vector(etl::ivector< T * > &lookup_, etl::ipool &storage_)
Constructor.
Definition indirect_vector.h:1246
etl::iindirect_vector::operator[]
reference operator[](size_t i)
Definition indirect_vector.h:634
etl::iindirect_vector::push_back
void push_back(const_reference value)
Definition indirect_vector.h:790
etl::iindirect_vector::insert
iterator insert(const_iterator position, const_reference value)
Definition indirect_vector.h:930
etl::iindirect_vector::insert
iterator insert(const_iterator position, size_t n, parameter_t value)
Definition indirect_vector.h:1045
etl::iindirect_vector
Definition indirect_vector.h:74
etl::indirect_vector
Definition indirect_vector.h:1422
etl::indirect_vector_ext
Template deduction guides.
Definition indirect_vector.h:1569
etl::addressof
ETL_CONSTEXPR17 etl::enable_if<!etl::is_same< T, etl::nullptr_t >::value, T >::type * addressof(T &t)
Definition addressof.h:52
etl::ipool::capacity
size_t capacity() const
Returns the maximum number of items in the pool.
Definition ipool.h:507
etl::ipool::create
T * create()
Definition ipool.h:351
etl::ipool
Definition ipool.h:110
etl::pool
Definition pool.h:54
etl::indirect_vector_buffer_missmatch
Definition indirect_vector.h:57
etl::vector
Definition vector.h:1830
etl::vector_empty
Definition vector_base.h:80
etl::vector_full
Definition vector_base.h:66
etl::vector_out_of_bounds
Definition vector_base.h:94
initializer_list.h
iterator.h
etl
Definition absolute.h:40
etl::operator==
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1078
etl::operator>
bool operator>(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1130
etl::operator>=
bool operator>=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1144
etl::operator!=
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1090
etl::operator<
bool operator<(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1103
etl::operator<=
bool operator<=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1117
platform.h
pool.h
etl::iterator
iterator
Definition iterator.h:482
etl::type
etl::parameter_type::type
etl::conditional< etl::is_fundamental< T >::value||etl::is_pointer< T >::value, T, constT & >::type type
By default fundamental and pointer types are passed by value.
Definition parameter_type.h:46
etl::remove_cv
remove_cv
Definition type_traits.h:325
operator==
ETL_CONSTEXPR14 bool operator==(const etl::to_arithmetic_result< T > &lhs, const etl::to_arithmetic_result< T > &rhs)
Equality test for etl::to_arithmetic_result.
Definition to_arithmetic.h:903
operator!=
ETL_CONSTEXPR14 bool operator!=(const etl::to_arithmetic_result< T > &lhs, const etl::to_arithmetic_result< T > &rhs)
Inequality test for etl::to_arithmetic_result.
Definition to_arithmetic.h:937
utility.h
vector.h