mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-26 20:38:45 +08:00
Deleted files
This commit is contained in:
parent
c04379a442
commit
f416a99116
2031
src/ibasic_string.h
2031
src/ibasic_string.h
File diff suppressed because it is too large
Load Diff
712
src/ibitset.h
712
src/ibitset.h
@ -1,712 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
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_IBITSET__
|
||||
#define __ETL_IBITSET__
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "exception.h"
|
||||
#include "integral_limits.h"
|
||||
#include "binary.h"
|
||||
#include "algorithm.h"
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef ETL_COMPILER_MICROSOFT
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception base for bitset
|
||||
///\ingroup bitset
|
||||
//***************************************************************************
|
||||
class bitset_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
bitset_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Bitset nullptr exception.
|
||||
///\ingroup bitset
|
||||
//***************************************************************************
|
||||
class bitset_nullptr : public bitset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
bitset_nullptr(string_type file_name, numeric_type line_number)
|
||||
: bitset_exception("bitset: nullptr", file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The base class for etl::bitset
|
||||
///\ingroup bitset
|
||||
//*************************************************************************
|
||||
class ibitset
|
||||
{
|
||||
protected:
|
||||
|
||||
// The type used for each element in the array.
|
||||
#if !defined(ETL_BITSET_ELEMENT_TYPE)
|
||||
typedef uint_least8_t element_t;
|
||||
#else
|
||||
typedef ETL_BITSET_ELEMENT_TYPE element_t;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
static const element_t ALL_SET = etl::integral_limits<element_t>::max;
|
||||
static const element_t ALL_CLEAR = 0;
|
||||
|
||||
static const size_t BITS_PER_ELEMENT = etl::integral_limits<element_t>::bits;
|
||||
|
||||
enum
|
||||
{
|
||||
npos = etl::integral_limits<size_t>::max
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The reference type returned.
|
||||
//*************************************************************************
|
||||
class bit_reference
|
||||
{
|
||||
public:
|
||||
|
||||
friend class ibitset;
|
||||
|
||||
//*******************************
|
||||
/// Conversion operator.
|
||||
//*******************************
|
||||
operator bool() const
|
||||
{
|
||||
return p_bitset->test(position);
|
||||
}
|
||||
|
||||
//*******************************
|
||||
/// Assignment operator.
|
||||
//*******************************
|
||||
bit_reference& operator = (bool b)
|
||||
{
|
||||
p_bitset->set(position, b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*******************************
|
||||
/// Assignment operator.
|
||||
//*******************************
|
||||
bit_reference& operator = (const bit_reference& r)
|
||||
{
|
||||
p_bitset->set(position, bool(r));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*******************************
|
||||
/// Flip the bit.
|
||||
//*******************************
|
||||
bit_reference& flip()
|
||||
{
|
||||
p_bitset->flip(position);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*******************************
|
||||
/// Return the logical inverse of the bit.
|
||||
//*******************************
|
||||
bool operator~() const
|
||||
{
|
||||
return !p_bitset->test(position);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//*******************************
|
||||
/// Default constructor.
|
||||
//*******************************
|
||||
bit_reference()
|
||||
: p_bitset(nullptr),
|
||||
position(0)
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************
|
||||
/// Constructor.
|
||||
//*******************************
|
||||
bit_reference(ibitset& r_bitset, size_t position)
|
||||
: p_bitset(&r_bitset),
|
||||
position(position)
|
||||
{
|
||||
}
|
||||
|
||||
ibitset* p_bitset; ///< The bitset.
|
||||
size_t position; ///< The position in the bitset.
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The size of the bitset.
|
||||
//*************************************************************************
|
||||
size_t size() const
|
||||
{
|
||||
return NBITS;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Count the number of bits set.
|
||||
//*************************************************************************
|
||||
size_t count() const
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
for (size_t i = 0; i < SIZE; ++i)
|
||||
{
|
||||
n += etl::count_bits(pdata[i]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Tests a bit at a position.
|
||||
/// Positions greater than the number of configured bits will return <b>false</b>.
|
||||
//*************************************************************************
|
||||
bool test(size_t position) const
|
||||
{
|
||||
size_t index;
|
||||
element_t mask;
|
||||
|
||||
if (SIZE == 1)
|
||||
{
|
||||
index = 0;
|
||||
mask = element_t(1) << position;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = position >> etl::log2<BITS_PER_ELEMENT>::value;
|
||||
mask = element_t(1) << (position & (BITS_PER_ELEMENT - 1));
|
||||
}
|
||||
|
||||
return (pdata[index] & mask) != 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Set the bit at the position.
|
||||
//*************************************************************************
|
||||
ibitset& set()
|
||||
{
|
||||
for (size_t i = 0; i < SIZE; ++i)
|
||||
{
|
||||
pdata[i] = ALL_SET;
|
||||
}
|
||||
|
||||
pdata[SIZE - 1] &= TOP_MASK;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Set the bit at the position.
|
||||
//*************************************************************************
|
||||
ibitset& set(size_t position, bool value = true)
|
||||
{
|
||||
size_t index;
|
||||
element_t bit;
|
||||
|
||||
if (SIZE == 1)
|
||||
{
|
||||
index = 0;
|
||||
bit = element_t(1) << position;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = position >> etl::log2<BITS_PER_ELEMENT>::value;
|
||||
bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1));
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
pdata[index] |= bit;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdata[index] &= ~bit;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Set from a string.
|
||||
//*************************************************************************
|
||||
ibitset& set(const char* text)
|
||||
{
|
||||
reset();
|
||||
|
||||
size_t i = std::min(NBITS, strlen(text));
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
set(--i, *text++ == '1');
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Resets the bitset.
|
||||
//*************************************************************************
|
||||
ibitset& reset()
|
||||
{
|
||||
for (size_t i = 0; i < SIZE; ++i)
|
||||
{
|
||||
pdata[i] = ALL_CLEAR;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Reset the bit at the position.
|
||||
//*************************************************************************
|
||||
ibitset& reset(size_t position)
|
||||
{
|
||||
size_t index;
|
||||
element_t bit;
|
||||
|
||||
if (SIZE == 1)
|
||||
{
|
||||
index = 0;
|
||||
bit = element_t(1) << position;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = position >> etl::log2<BITS_PER_ELEMENT>::value;
|
||||
bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1));
|
||||
}
|
||||
|
||||
pdata[index] &= ~bit;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Flip all of the bits.
|
||||
//*************************************************************************
|
||||
ibitset& flip()
|
||||
{
|
||||
for (size_t i = 0; i < SIZE; ++i)
|
||||
{
|
||||
pdata[i] = ~pdata[i];
|
||||
}
|
||||
|
||||
pdata[SIZE - 1] &= TOP_MASK;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Flip the bit at the position.
|
||||
//*************************************************************************
|
||||
ibitset& flip(size_t position)
|
||||
{
|
||||
if (position < NBITS)
|
||||
{
|
||||
size_t index;
|
||||
element_t bit;
|
||||
|
||||
if (SIZE == 1)
|
||||
{
|
||||
index = 0;
|
||||
bit = element_t(1) << position;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = position >> log2<BITS_PER_ELEMENT>::value;
|
||||
bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1));
|
||||
}
|
||||
|
||||
pdata[index] ^= bit;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Are all the bits sets?
|
||||
//*************************************************************************
|
||||
bool all() const
|
||||
{
|
||||
// All but the last.
|
||||
for (size_t i = 0; i < (SIZE - 1); ++i)
|
||||
{
|
||||
if (pdata[i] != ALL_SET)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// The last.
|
||||
if (pdata[SIZE - 1] != (ALL_SET & TOP_MASK))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Are any of the bits set?
|
||||
//*************************************************************************
|
||||
bool any() const
|
||||
{
|
||||
return !none();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Are none of the bits set?
|
||||
//*************************************************************************
|
||||
bool none() const
|
||||
{
|
||||
for (size_t i = 0; i < SIZE; ++i)
|
||||
{
|
||||
if (pdata[i] != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Finds the first bit in the specified state.
|
||||
///\param state The state to search for.
|
||||
///\returns The position of the bit or SIZE if none were found.
|
||||
//*************************************************************************
|
||||
size_t find_first(bool state) const
|
||||
{
|
||||
return find_next(state, 0);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Finds the next bit in the specified state.
|
||||
///\param state The state to search for.
|
||||
///\param position The position to start from.
|
||||
///\returns The position of the bit or SIZE if none were found.
|
||||
//*************************************************************************
|
||||
size_t find_next(bool state, size_t position) const
|
||||
{
|
||||
// Where to start.
|
||||
size_t index;
|
||||
size_t bit;
|
||||
|
||||
if (SIZE == 1)
|
||||
{
|
||||
index = 0;
|
||||
bit = position;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = position >> log2<BITS_PER_ELEMENT>::value;
|
||||
bit = position & (BITS_PER_ELEMENT - 1);
|
||||
}
|
||||
|
||||
element_t mask = 1 << bit;
|
||||
|
||||
// For each element in the bitset...
|
||||
while (index < SIZE)
|
||||
{
|
||||
element_t value = pdata[index];
|
||||
|
||||
// Needs checking?
|
||||
if (( state && (value != ALL_CLEAR)) ||
|
||||
(!state && (value != ALL_SET)))
|
||||
{
|
||||
// For each bit in the element...
|
||||
while ((bit < BITS_PER_ELEMENT) && (position < NBITS))
|
||||
{
|
||||
// Equal to the required state?
|
||||
if (((value & mask) != 0) == state)
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
// Move on to the next bit.
|
||||
mask <<= 1;
|
||||
++position;
|
||||
++bit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
position += BITS_PER_ELEMENT;
|
||||
}
|
||||
|
||||
// Start at the beginning for all other elements.
|
||||
bit = 0;
|
||||
mask = 1;
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
return ibitset::npos;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Read [] operator.
|
||||
//*************************************************************************
|
||||
bool operator[] (size_t position) const
|
||||
{
|
||||
return test(position);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Write [] operator.
|
||||
//*************************************************************************
|
||||
bit_reference operator [] (size_t position)
|
||||
{
|
||||
return bit_reference(*this, position);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// operator &=
|
||||
//*************************************************************************
|
||||
ibitset& operator &=(const ibitset& other)
|
||||
{
|
||||
for (size_t i = 0; i < SIZE; ++i)
|
||||
{
|
||||
pdata[i] &= other.pdata[i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// operator |=
|
||||
//*************************************************************************
|
||||
ibitset& operator |=(const ibitset& other)
|
||||
{
|
||||
for (size_t i = 0; i < SIZE; ++i)
|
||||
{
|
||||
pdata[i] |= other.pdata[i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// operator ^=
|
||||
//*************************************************************************
|
||||
ibitset& operator ^=(const ibitset& other)
|
||||
{
|
||||
for (size_t i = 0; i < SIZE; ++i)
|
||||
{
|
||||
pdata[i] ^= other.pdata[i];
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// operator <<=
|
||||
//*************************************************************************
|
||||
ibitset& operator<<=(size_t shift)
|
||||
{
|
||||
if (SIZE == 1)
|
||||
{
|
||||
pdata[0] <<= shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t source = NBITS - shift - 1;
|
||||
size_t destination = NBITS - 1;
|
||||
|
||||
for (size_t i = 0; i < (NBITS - shift); ++i)
|
||||
{
|
||||
set(destination--, test(source--));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < shift; ++i)
|
||||
{
|
||||
reset(destination--);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// operator >>=
|
||||
//*************************************************************************
|
||||
ibitset& operator>>=(size_t shift)
|
||||
{
|
||||
if (SIZE == 1)
|
||||
{
|
||||
pdata[0] >>= shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t source = shift;
|
||||
size_t destination = 0;
|
||||
|
||||
for (size_t i = 0; i < (NBITS - shift); ++i)
|
||||
{
|
||||
set(destination++, test(source++));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < shift; ++i)
|
||||
{
|
||||
reset(destination++);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// operator =
|
||||
//*************************************************************************
|
||||
ibitset& operator =(const ibitset& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
etl::copy_n(other.pdata, SIZE, pdata);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// swap
|
||||
//*************************************************************************
|
||||
void swap(ibitset& other)
|
||||
{
|
||||
std::swap_ranges(pdata, pdata + SIZE, other.pdata);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Initialise from an unsigned long long.
|
||||
//*************************************************************************
|
||||
ibitset& initialise(unsigned long long value)
|
||||
{
|
||||
reset();
|
||||
|
||||
const size_t SHIFT = (integral_limits<unsigned long long>::bits <= (int)BITS_PER_ELEMENT) ? 0 : BITS_PER_ELEMENT;
|
||||
|
||||
// Can we do it in one hit?
|
||||
if (SHIFT == 0)
|
||||
{
|
||||
pdata[0] = element_t(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
while ((value != 0) && (i < SIZE))
|
||||
{
|
||||
pdata[i++] = value & ALL_SET;
|
||||
value = value >> SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
pdata[SIZE - 1] &= TOP_MASK;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Invert
|
||||
//*************************************************************************
|
||||
void invert()
|
||||
{
|
||||
for (size_t i = 0; i < SIZE; ++i)
|
||||
{
|
||||
pdata[i] = ~pdata[i];
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets a reference to the specified bit.
|
||||
//*************************************************************************
|
||||
bit_reference get_bit_reference(size_t position)
|
||||
{
|
||||
return bit_reference(*this, position);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor.
|
||||
//*************************************************************************
|
||||
ibitset(size_t nbits, size_t size, element_t* pdata)
|
||||
: NBITS(nbits),
|
||||
SIZE(size),
|
||||
pdata(pdata)
|
||||
{
|
||||
size_t allocated_bits = SIZE * BITS_PER_ELEMENT;
|
||||
size_t top_mask_shift = ((BITS_PER_ELEMENT - (allocated_bits - NBITS)) % BITS_PER_ELEMENT);
|
||||
TOP_MASK = element_t(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Compare bitsets.
|
||||
//*************************************************************************
|
||||
static bool is_equal(const ibitset& lhs, const ibitset&rhs)
|
||||
{
|
||||
return std::equal(lhs.pdata, lhs.pdata + lhs.SIZE, rhs.pdata);
|
||||
}
|
||||
|
||||
element_t TOP_MASK;
|
||||
|
||||
private:
|
||||
|
||||
// Disable copy construction.
|
||||
ibitset(const ibitset&);
|
||||
|
||||
const size_t NBITS;
|
||||
const size_t SIZE;
|
||||
element_t* pdata;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#ifdef ETL_COMPILER_MICROSOFT
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1468
src/ideque.h
1468
src/ideque.h
File diff suppressed because it is too large
Load Diff
864
src/iflat_map.h
864
src/iflat_map.h
@ -1,864 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove
|
||||
|
||||
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_IFLAT_MAP__
|
||||
#define __ETL_IFLAT_MAP__
|
||||
#define __ETL_IN_IFLAT_MAP_H__
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "private/flat_map_base.h"
|
||||
#include "type_traits.h"
|
||||
#include "parameter_type.h"
|
||||
#include "ivector.h"
|
||||
#include "ipool.h"
|
||||
#include "error_handler.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for specifically sized flat_maps.
|
||||
/// Can be used as a reference type for all flat_maps containing a specific type.
|
||||
///\ingroup flat_map
|
||||
//***************************************************************************
|
||||
template <typename TKey, typename TMapped, typename TKeyCompare = std::less<TKey> >
|
||||
class iflat_map : public flat_map_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::pair<const TKey, TMapped> value_type;
|
||||
|
||||
private:
|
||||
|
||||
typedef etl::ivector<value_type*> 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<std::bidirectional_iterator_tag, value_type>
|
||||
{
|
||||
public:
|
||||
|
||||
friend class iflat_map;
|
||||
|
||||
iterator()
|
||||
{
|
||||
}
|
||||
|
||||
iterator(typename lookup_t::iterator ilookup)
|
||||
: ilookup(ilookup)
|
||||
{
|
||||
}
|
||||
|
||||
iterator(const iterator& other)
|
||||
: ilookup(other.ilookup)
|
||||
{
|
||||
}
|
||||
|
||||
iterator& operator =(const iterator& other)
|
||||
{
|
||||
ilookup = other.ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator& operator ++()
|
||||
{
|
||||
++ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator ++(int)
|
||||
{
|
||||
iterator temp(*this);
|
||||
++ilookup;
|
||||
return temp;
|
||||
}
|
||||
|
||||
iterator& operator --()
|
||||
{
|
||||
--ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator --(int)
|
||||
{
|
||||
iterator temp(*this);
|
||||
--ilookup;
|
||||
return temp;
|
||||
}
|
||||
|
||||
reference operator *()
|
||||
{
|
||||
return *(*ilookup);
|
||||
}
|
||||
|
||||
const_reference operator *() const
|
||||
{
|
||||
return *(*ilookup);
|
||||
}
|
||||
|
||||
pointer operator &()
|
||||
{
|
||||
return etl::addressof(*(*ilookup));
|
||||
}
|
||||
|
||||
const_pointer operator &() const
|
||||
{
|
||||
return &(*(*ilookup));
|
||||
}
|
||||
|
||||
pointer operator ->()
|
||||
{
|
||||
return etl::addressof(*(*ilookup));
|
||||
}
|
||||
|
||||
const_pointer operator ->() const
|
||||
{
|
||||
return etl::addressof(*(*ilookup));
|
||||
}
|
||||
|
||||
friend bool operator == (const iterator& lhs, const iterator& rhs)
|
||||
{
|
||||
return lhs.ilookup == rhs.ilookup;
|
||||
}
|
||||
|
||||
friend bool operator != (const iterator& lhs, const iterator& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typename lookup_t::iterator ilookup;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
class const_iterator : public std::iterator<std::bidirectional_iterator_tag, const value_type>
|
||||
{
|
||||
public:
|
||||
|
||||
friend class iflat_map;
|
||||
|
||||
const_iterator()
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(typename lookup_t::const_iterator ilookup)
|
||||
: ilookup(ilookup)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(const iterator& other)
|
||||
: ilookup(other.ilookup)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(const const_iterator& other)
|
||||
: ilookup(other.ilookup)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator& operator =(const iterator& other)
|
||||
{
|
||||
ilookup = other.ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator& operator =(const const_iterator& other)
|
||||
{
|
||||
ilookup = other.ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator& operator ++()
|
||||
{
|
||||
++ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator operator ++(int)
|
||||
{
|
||||
const_iterator temp(*this);
|
||||
++ilookup;
|
||||
return temp;
|
||||
}
|
||||
|
||||
const_iterator& operator --()
|
||||
{
|
||||
--ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator operator --(int)
|
||||
{
|
||||
const_iterator temp(*this);
|
||||
--ilookup;
|
||||
return temp;
|
||||
}
|
||||
|
||||
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<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
|
||||
|
||||
protected:
|
||||
|
||||
typedef typename parameter_type<TKey>::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_map.
|
||||
///\return An iterator to the beginning of the flat_map.
|
||||
//*********************************************************************
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(lookup.begin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the beginning of the flat_map.
|
||||
///\return A const iterator to the beginning of the flat_map.
|
||||
//*********************************************************************
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(lookup.begin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns an iterator to the end of the flat_map.
|
||||
///\return An iterator to the end of the flat_map.
|
||||
//*********************************************************************
|
||||
iterator end()
|
||||
{
|
||||
return iterator(lookup.end());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the end of the flat_map.
|
||||
///\return A const iterator to the end of the flat_map.
|
||||
//*********************************************************************
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(lookup.end());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the beginning of the flat_map.
|
||||
///\return A const iterator to the beginning of the flat_map.
|
||||
//*********************************************************************
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(lookup.cbegin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the end of the flat_map.
|
||||
///\return A const iterator to the end of the flat_map.
|
||||
//*********************************************************************
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator(lookup.cend());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns an reverse iterator to the reverse beginning of the flat_map.
|
||||
///\return Iterator to the reverse beginning of the flat_map.
|
||||
//*********************************************************************
|
||||
reverse_iterator rbegin()
|
||||
{
|
||||
return reverse_iterator(lookup.rbegin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the reverse beginning of the flat_map.
|
||||
///\return Const iterator to the reverse beginning of the flat_map.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator rbegin() const
|
||||
{
|
||||
return reverse_iterator(lookup.rbegin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a reverse iterator to the end + 1 of the flat_map.
|
||||
///\return Reverse iterator to the end + 1 of the flat_map.
|
||||
//*********************************************************************
|
||||
reverse_iterator rend()
|
||||
{
|
||||
return reverse_iterator(lookup.rend());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the end + 1 of the flat_map.
|
||||
///\return Const reverse iterator to the end + 1 of the flat_map.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator rend() const
|
||||
{
|
||||
return const_reverse_iterator(lookup.rend());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the reverse beginning of the flat_map.
|
||||
///\return Const reverse iterator to the reverse beginning of the flat_map.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator crbegin() const
|
||||
{
|
||||
return const_reverse_iterator(lookup.crbegin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the end + 1 of the flat_map.
|
||||
///\return Const reverse iterator to the end + 1 of the flat_map.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator crend() const
|
||||
{
|
||||
return const_reverse_iterator(lookup.crend());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a reference to the value at index 'key'
|
||||
///\param i The index.
|
||||
///\return A reference to the value at index 'key'
|
||||
//*********************************************************************
|
||||
mapped_type& operator [](key_value_parameter_t key)
|
||||
{
|
||||
iterator i_element = lower_bound(key);
|
||||
|
||||
if (i_element == end())
|
||||
{
|
||||
std::pair<iterator, bool> result = insert_at(i_element, value_type(key, mapped_type()));
|
||||
|
||||
i_element = result.first;
|
||||
}
|
||||
|
||||
return i_element->second;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a reference to the value at index 'key'
|
||||
/// If asserts or exceptions are enabled, emits an etl::flat_map_out_of_bounds if the key is not in the range.
|
||||
///\param i The index.
|
||||
///\return A reference to the value at index 'key'
|
||||
//*********************************************************************
|
||||
mapped_type& at(key_value_parameter_t key)
|
||||
{
|
||||
iterator i_element = lower_bound(key);
|
||||
|
||||
ETL_ASSERT(i_element != end(), ETL_ERROR(flat_map_out_of_bounds));
|
||||
|
||||
return i_element->second;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reference to the value at index 'key'
|
||||
/// If asserts or exceptions are enabled, emits an etl::flat_map_out_of_bounds if the key is not in the range.
|
||||
///\param i The index.
|
||||
///\return A const reference to the value at index 'key'
|
||||
//*********************************************************************
|
||||
const mapped_type& at(key_value_parameter_t key) const
|
||||
{
|
||||
const_iterator i_element = lower_bound(key);
|
||||
|
||||
ETL_ASSERT(i_element != end(), ETL_ERROR(flat_map_out_of_bounds));
|
||||
|
||||
return i_element->second;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Assigns values to the flat_map.
|
||||
/// If ETL_THROW_EXCEPTIONS & _DEBUG are defined, emits flat_map_full if the flat_map does not have enough free space.
|
||||
/// If ETL_THROW_EXCEPTIONS & _DEBUG are defined, emits flat_map_iterator if the iterators are reversed.
|
||||
///\param first The iterator to the first element.
|
||||
///\param last The iterator to the last element + 1.
|
||||
//*********************************************************************
|
||||
template <typename TIterator>
|
||||
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_map_full));
|
||||
#endif
|
||||
|
||||
clear();
|
||||
|
||||
while (first != last)
|
||||
{
|
||||
insert(*first++);
|
||||
}
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts a value to the flat_map.
|
||||
/// If asserts or exceptions are enabled, emits flat_map_full if the flat_map is already full.
|
||||
///\param value The value to insert.
|
||||
//*********************************************************************
|
||||
std::pair<iterator, bool> insert(const value_type& value)
|
||||
{
|
||||
iterator i_element = lower_bound(value.first);
|
||||
|
||||
return insert_at(i_element, value);
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts a value to the flat_map.
|
||||
/// 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_map.
|
||||
/// If asserts or exceptions are enabled, emits flat_map_full if the flat_map 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 <class TIterator>
|
||||
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)
|
||||
{
|
||||
iterator i_element = find(key);
|
||||
|
||||
if (i_element == end())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i_element->~value_type();
|
||||
storage.release(etl::addressof(*i_element));
|
||||
lookup.erase(i_element.ilookup);
|
||||
--construct_count;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// 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_map.
|
||||
//*************************************************************************
|
||||
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
|
||||
{
|
||||
return (find(key) == end()) ? 0 : 1;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// 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<iterator, iterator> 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<const_iterator, const_iterator> 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_map& operator = (const iflat_map& rhs)
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
assign(rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the flat_map.
|
||||
///\return The current size of the flat_map.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return lookup.size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'empty' state of the flat_map.
|
||||
///\return <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return lookup.empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the flat_map.
|
||||
///\return <b>true</b> if full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return lookup.full();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the flat_map.
|
||||
///\return The capacity of the flat_map.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return lookup.capacity();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum possible size of the flat_map.
|
||||
///\return The maximum size of the flat_map.
|
||||
//*************************************************************************
|
||||
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_map(lookup_t& lookup_, storage_t& storage_)
|
||||
: lookup(lookup_),
|
||||
storage(storage_)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts a value to the flat_map.
|
||||
///\param i_element The place to insert.
|
||||
///\param value The value to insert.
|
||||
//*********************************************************************
|
||||
std::pair<iterator, bool> insert_at(iterator i_element, const value_type& value)
|
||||
{
|
||||
std::pair<iterator, bool> result(end(), false);
|
||||
|
||||
if (i_element == end())
|
||||
{
|
||||
// At the end.
|
||||
ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_map_full));
|
||||
|
||||
value_type* pvalue = storage.allocate<value_type>();
|
||||
::new (pvalue) value_type(value);
|
||||
lookup.push_back(pvalue);
|
||||
result.first = --end();
|
||||
result.second = true;
|
||||
++construct_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not at the end.
|
||||
result.first = i_element;
|
||||
|
||||
// Existing element?
|
||||
if (value.first != i_element->first)
|
||||
{
|
||||
// A new one.
|
||||
ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_map_full));
|
||||
value_type* pvalue = storage.allocate<value_type>();
|
||||
::new (pvalue) value_type(value);
|
||||
lookup.insert(i_element.ilookup, pvalue);
|
||||
result.second = true;
|
||||
++construct_count;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Disable copy construction.
|
||||
iflat_map(const iflat_map&);
|
||||
|
||||
lookup_t& lookup;
|
||||
storage_t& storage;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Equal operator.
|
||||
///\param lhs Reference to the first flat_map.
|
||||
///\param rhs Reference to the second flat_map.
|
||||
///\return <b>true</b> if the arrays are equal, otherwise <b>false</b>
|
||||
///\ingroup flat_map
|
||||
//***************************************************************************
|
||||
template <typename TKey, typename TMapped, typename TKeyCompare>
|
||||
bool operator ==(const etl::iflat_map<TKey, TMapped, TKeyCompare>& lhs, const etl::iflat_map<TKey, TMapped, TKeyCompare>& rhs)
|
||||
{
|
||||
return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Not equal operator.
|
||||
///\param lhs Reference to the first flat_map.
|
||||
///\param rhs Reference to the second flat_map.
|
||||
///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b>
|
||||
///\ingroup flat_map
|
||||
//***************************************************************************
|
||||
template <typename TKey, typename TMapped, typename TKeyCompare>
|
||||
bool operator !=(const etl::iflat_map<TKey, TMapped, TKeyCompare>& lhs, const etl::iflat_map<TKey, TMapped, TKeyCompare>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
}
|
||||
|
||||
#undef __ETL_IN_IFLAT_MAP_H__
|
||||
#endif
|
||||
@ -1,810 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove
|
||||
|
||||
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_IFLAT_MULTIMAP__
|
||||
#define __ETL_IFLAT_MULTIMAP__
|
||||
#define __ETL_IN_IFLAT_MULTIMAP_H__
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "private/flat_multimap_base.h"
|
||||
#include "type_traits.h"
|
||||
#include "parameter_type.h"
|
||||
#include "ivector.h"
|
||||
#include "error_handler.h"
|
||||
#include "ipool.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// 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 <typename TKey, typename TMapped, typename TKeyCompare = std::less<TKey> >
|
||||
class iflat_multimap : public flat_multimap_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::pair<const TKey, TMapped> value_type;
|
||||
|
||||
private:
|
||||
|
||||
typedef etl::ivector<value_type*> 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<std::bidirectional_iterator_tag, value_type>
|
||||
{
|
||||
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<std::bidirectional_iterator_tag, const value_type>
|
||||
{
|
||||
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<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
|
||||
|
||||
protected:
|
||||
|
||||
typedef typename parameter_type<TKey>::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 <typename TIterator>
|
||||
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<iterator, bool> insert(const value_type& value)
|
||||
{
|
||||
ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multimap_full));
|
||||
|
||||
std::pair<iterator, bool> 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 <class TIterator>
|
||||
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<iterator, iterator> 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<const_iterator, const_iterator> 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<iterator, iterator> 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<const_iterator, const_iterator> 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 <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return lookup.empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the flat_multiset.
|
||||
///\return <b>true</b> 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<iterator, bool> insert_at(iterator i_element, const value_type& value)
|
||||
{
|
||||
std::pair<iterator, bool> result(end(), false);
|
||||
|
||||
if (i_element == end())
|
||||
{
|
||||
// At the end.
|
||||
value_type* pvalue = storage.allocate<value_type>();
|
||||
::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<value_type>();
|
||||
::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 <b>true</b> if the arrays are equal, otherwise <b>false</b>
|
||||
///\ingroup flat_multimap
|
||||
//***************************************************************************
|
||||
template <typename TKey, typename TMapped, typename TKeyCompare>
|
||||
bool operator ==(const etl::iflat_multimap<TKey, TMapped, TKeyCompare>& lhs, const etl::iflat_multimap<TKey, TMapped, TKeyCompare>& 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 <b>true</b> if the arrays are not equal, otherwise <b>false</b>
|
||||
///\ingroup flat_multimap
|
||||
//***************************************************************************
|
||||
template <typename TKey, typename TMapped, typename TKeyCompare>
|
||||
bool operator !=(const etl::iflat_multimap<TKey, TMapped, TKeyCompare>& lhs, const etl::iflat_multimap<TKey, TMapped, TKeyCompare>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
}
|
||||
|
||||
#undef __ETL_IN_IFLAT_MULTIMAP_H__
|
||||
#endif
|
||||
@ -1,774 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove
|
||||
|
||||
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_IFLAT_MULTISET__
|
||||
#define __ETL_IFLAT_MULTISET__
|
||||
#define __ETL_IN_IFLAT_MULTISET_H__
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "private/flat_multiset_base.h"
|
||||
#include "type_traits.h"
|
||||
#include "parameter_type.h"
|
||||
#include "ivector.h"
|
||||
#include "error_handler.h"
|
||||
#include "ipool.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// 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 <typename T, typename TKeyCompare = std::less<T> >
|
||||
class iflat_multiset : public flat_multiset_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T key_type;
|
||||
typedef T value_type;
|
||||
|
||||
private:
|
||||
|
||||
typedef etl::ivector<value_type*> 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<std::bidirectional_iterator_tag, value_type>
|
||||
{
|
||||
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<std::bidirectional_iterator_tag, const value_type>
|
||||
{
|
||||
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<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
typedef typename parameter_type<T>::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 <typename TIterator>
|
||||
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<iterator, bool> insert(parameter_t value)
|
||||
{
|
||||
std::pair<iterator, bool> 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<value_type>();
|
||||
::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<value_type>();
|
||||
::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 <class TIterator>
|
||||
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<iterator, iterator> 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<const_iterator, const_iterator> 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<iterator, iterator> 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<const_iterator, const_iterator> 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 <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return lookup.empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the flat_multiset.
|
||||
///\return <b>true</b> 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 <b>true</b> if the arrays are equal, otherwise <b>false</b>
|
||||
///\ingroup flat_multiset
|
||||
//***************************************************************************
|
||||
template <typename T, typename TKeyCompare>
|
||||
bool operator ==(const etl::iflat_multiset<T, TKeyCompare>& lhs, const etl::iflat_multiset<T, TKeyCompare>& 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 <b>true</b> if the arrays are not equal, otherwise <b>false</b>
|
||||
///\ingroup flat_multiset
|
||||
//***************************************************************************
|
||||
template <typename T, typename TKeyCompare>
|
||||
bool operator !=(const etl::iflat_multiset<T, TKeyCompare>& lhs, const etl::iflat_multiset<T, TKeyCompare>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
}
|
||||
|
||||
#undef __ETL_IN_IFLAT_MULTISET_H__
|
||||
#endif
|
||||
781
src/iflat_set.h
781
src/iflat_set.h
@ -1,781 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove
|
||||
|
||||
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_IFLAT_SET__
|
||||
#define __ETL_IFLAT_SET__
|
||||
#define __ETL_IN_IFLAT_SET_H__
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "private/flat_set_base.h"
|
||||
#include "type_traits.h"
|
||||
#include "parameter_type.h"
|
||||
#include "ivector.h"
|
||||
#include "ipool.h"
|
||||
#include "error_handler.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for specifically sized flat_sets.
|
||||
/// Can be used as a reference type for all flat_sets containing a specific type.
|
||||
///\ingroup flat_set
|
||||
//***************************************************************************
|
||||
template <typename T, typename TKeyCompare = std::less<T> >
|
||||
class iflat_set : public flat_set_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T key_type;
|
||||
typedef T value_type;
|
||||
typedef TKeyCompare key_compare;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef size_t size_type;
|
||||
|
||||
private:
|
||||
|
||||
typedef etl::ivector<value_type*> lookup_t;
|
||||
typedef etl::ipool storage_t;
|
||||
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
class iterator : public std::iterator<std::bidirectional_iterator_tag, value_type>
|
||||
{
|
||||
public:
|
||||
|
||||
friend class iflat_set;
|
||||
|
||||
iterator()
|
||||
{
|
||||
}
|
||||
|
||||
iterator(typename lookup_t::iterator ilookup)
|
||||
: ilookup(ilookup)
|
||||
{
|
||||
}
|
||||
|
||||
iterator(const iterator& other)
|
||||
: ilookup(other.ilookup)
|
||||
{
|
||||
}
|
||||
|
||||
iterator& operator =(const iterator& other)
|
||||
{
|
||||
ilookup = other.ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator& operator ++()
|
||||
{
|
||||
++ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator ++(int)
|
||||
{
|
||||
iterator temp(*this);
|
||||
++ilookup;
|
||||
return temp;
|
||||
}
|
||||
|
||||
iterator& operator --()
|
||||
{
|
||||
--ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator --(int)
|
||||
{
|
||||
iterator temp(*this);
|
||||
--ilookup;
|
||||
return temp;
|
||||
}
|
||||
|
||||
reference operator *()
|
||||
{
|
||||
return *(*ilookup);
|
||||
}
|
||||
|
||||
const_reference operator *() const
|
||||
{
|
||||
return *(*ilookup);
|
||||
}
|
||||
|
||||
pointer operator &()
|
||||
{
|
||||
return etl::addressof(*(*ilookup));
|
||||
}
|
||||
|
||||
const_pointer operator &() const
|
||||
{
|
||||
return &(*(*ilookup));
|
||||
}
|
||||
|
||||
pointer operator ->()
|
||||
{
|
||||
return etl::addressof(*(*ilookup));
|
||||
}
|
||||
|
||||
const_pointer operator ->() const
|
||||
{
|
||||
return etl::addressof(*(*ilookup));
|
||||
}
|
||||
|
||||
friend bool operator == (const iterator& lhs, const iterator& rhs)
|
||||
{
|
||||
return lhs.ilookup == rhs.ilookup;
|
||||
}
|
||||
|
||||
friend bool operator != (const iterator& lhs, const iterator& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typename lookup_t::iterator ilookup;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
class const_iterator : public std::iterator<std::bidirectional_iterator_tag, const value_type>
|
||||
{
|
||||
public:
|
||||
|
||||
friend class iflat_set;
|
||||
|
||||
const_iterator()
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(typename lookup_t::const_iterator ilookup)
|
||||
: ilookup(ilookup)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(const iterator& other)
|
||||
: ilookup(other.ilookup)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator(const const_iterator& other)
|
||||
: ilookup(other.ilookup)
|
||||
{
|
||||
}
|
||||
|
||||
const_iterator& operator =(const iterator& other)
|
||||
{
|
||||
ilookup = other.ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator& operator =(const const_iterator& other)
|
||||
{
|
||||
ilookup = other.ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator& operator ++()
|
||||
{
|
||||
++ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator operator ++(int)
|
||||
{
|
||||
const_iterator temp(*this);
|
||||
++ilookup;
|
||||
return temp;
|
||||
}
|
||||
|
||||
const_iterator& operator --()
|
||||
{
|
||||
--ilookup;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator operator --(int)
|
||||
{
|
||||
const_iterator temp(*this);
|
||||
--ilookup;
|
||||
return temp;
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
typedef typename parameter_type<T>::type parameter_t;
|
||||
|
||||
public:
|
||||
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns an iterator to the beginning of the flat_set.
|
||||
///\return An iterator to the beginning of the flat_set.
|
||||
//*********************************************************************
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(lookup.begin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the beginning of the flat_set.
|
||||
///\return A const iterator to the beginning of the flat_set.
|
||||
//*********************************************************************
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(lookup.begin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns an iterator to the end of the flat_set.
|
||||
///\return An iterator to the end of the flat_set.
|
||||
//*********************************************************************
|
||||
iterator end()
|
||||
{
|
||||
return iterator(lookup.end());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the end of the flat_set.
|
||||
///\return A const iterator to the end of the flat_set.
|
||||
//*********************************************************************
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(lookup.end());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the beginning of the flat_set.
|
||||
///\return A const iterator to the beginning of the flat_set.
|
||||
//*********************************************************************
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return const_iterator(lookup.cbegin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the end of the flat_set.
|
||||
///\return A const iterator to the end of the flat_set.
|
||||
//*********************************************************************
|
||||
const_iterator cend() const
|
||||
{
|
||||
return const_iterator(lookup.cend());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns an reverse iterator to the reverse beginning of the flat_set.
|
||||
///\return Iterator to the reverse beginning of the flat_set.
|
||||
//*********************************************************************
|
||||
reverse_iterator rbegin()
|
||||
{
|
||||
return reverse_iterator(lookup.rbegin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the reverse beginning of the flat_set.
|
||||
///\return Const iterator to the reverse beginning of the flat_set.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator rbegin() const
|
||||
{
|
||||
return const_reverse_iterator(lookup.rbegin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a reverse iterator to the end + 1 of the flat_set.
|
||||
///\return Reverse iterator to the end + 1 of the flat_set.
|
||||
//*********************************************************************
|
||||
reverse_iterator rend()
|
||||
{
|
||||
return reverse_iterator(lookup.rend());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the end + 1 of the flat_set.
|
||||
///\return Const reverse iterator to the end + 1 of the flat_set.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator rend() const
|
||||
{
|
||||
return const_reverse_iterator(lookup.rend());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the reverse beginning of the flat_set.
|
||||
///\return Const reverse iterator to the reverse beginning of the flat_set.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator crbegin() const
|
||||
{
|
||||
return const_reverse_iterator(lookup.crbegin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the end + 1 of the flat_set.
|
||||
///\return Const reverse iterator to the end + 1 of the flat_set.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator crend() const
|
||||
{
|
||||
return const_reverse_iterator(lookup.crend());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Assigns values to the flat_set.
|
||||
/// If asserts or exceptions are enabled, emits flat_set_full if the flat_set does not have enough free space.
|
||||
/// If asserts or exceptions are enabled, emits flat_set_iterator if the iterators are reversed.
|
||||
///\param first The iterator to the first element.
|
||||
///\param last The iterator to the last element + 1.
|
||||
//*********************************************************************
|
||||
template <typename TIterator>
|
||||
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_set_full));
|
||||
#endif
|
||||
|
||||
clear();
|
||||
|
||||
while (first != last)
|
||||
{
|
||||
insert(*first++);
|
||||
}
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts a value to the flat_set.
|
||||
/// If asserts or exceptions are enabled, emits flat_set_full if the flat_set is already full.
|
||||
///\param value The value to insert.
|
||||
//*********************************************************************
|
||||
std::pair<iterator, bool> insert(parameter_t value)
|
||||
{
|
||||
std::pair<iterator, bool> result(end(), false);
|
||||
|
||||
ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_set_full));
|
||||
|
||||
iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare());
|
||||
|
||||
if (i_element == end())
|
||||
{
|
||||
// At the end. Doesn't exist.
|
||||
value_type* pvalue = storage.allocate<value_type>();
|
||||
::new (pvalue) value_type(value);
|
||||
lookup.push_back(pvalue);
|
||||
result.first = --end();
|
||||
result.second = true;
|
||||
++construct_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not at the end.
|
||||
// Does not exist already?
|
||||
if (*i_element != value)
|
||||
{
|
||||
value_type* pvalue = storage.allocate<value_type>();
|
||||
::new (pvalue) value_type(value);
|
||||
lookup.insert(i_element.ilookup, pvalue);
|
||||
result.first = i_element;
|
||||
result.second = true;
|
||||
++construct_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.first = i_element;
|
||||
result.second = false;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts a value to the flat_set.
|
||||
/// If asserts or exceptions are enabled, emits flat_set_full if the flat_set 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_set.
|
||||
/// If asserts or exceptions are enabled, emits flat_set_full if the flat_set 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 <class TIterator>
|
||||
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)
|
||||
{
|
||||
iterator i_element = find(key);
|
||||
|
||||
if (i_element == end())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i_element->~value_type();
|
||||
storage.release(etl::addressof(*i_element));
|
||||
lookup.erase(i_element.ilookup);
|
||||
--construct_count;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// 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_set.
|
||||
//*************************************************************************
|
||||
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
|
||||
{
|
||||
return (find(key) == end()) ? 0 : 1;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// 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<iterator, iterator> 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<const_iterator, const_iterator> equal_range(parameter_t key) const
|
||||
{
|
||||
return std::upper_bound(cbegin(), cend(), key, TKeyCompare());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
iflat_set& operator = (const iflat_set& rhs)
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
assign(rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the flat_set.
|
||||
///\return The current size of the flat_set.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return lookup.size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'empty' state of the flat_set.
|
||||
///\return <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return lookup.empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the flat_set.
|
||||
///\return <b>true</b> if full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return lookup.full();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the flat_set.
|
||||
///\return The capacity of the flat_set.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return lookup.capacity();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum possible size of the flat_set.
|
||||
///\return The maximum size of the flat_set.
|
||||
//*************************************************************************
|
||||
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_set(lookup_t& lookup_, storage_t& storage)
|
||||
: lookup(lookup_),
|
||||
storage(storage)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Disable copy construction.
|
||||
iflat_set(const iflat_set&);
|
||||
|
||||
lookup_t& lookup;
|
||||
storage_t& storage;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Equal operator.
|
||||
///\param lhs Reference to the first flat_set.
|
||||
///\param rhs Reference to the second flat_set.
|
||||
///\return <b>true</b> if the arrays are equal, otherwise <b>false</b>
|
||||
///\ingroup flat_set
|
||||
//***************************************************************************
|
||||
template <typename T, typename TKeyCompare>
|
||||
bool operator ==(const etl::iflat_set<T, TKeyCompare>& lhs, const etl::iflat_set<T, TKeyCompare>& rhs)
|
||||
{
|
||||
return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Not equal operator.
|
||||
///\param lhs Reference to the first flat_set.
|
||||
///\param rhs Reference to the second flat_set.
|
||||
///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b>
|
||||
///\ingroup flat_set
|
||||
//***************************************************************************
|
||||
template <typename T, typename TKeyCompare>
|
||||
bool operator !=(const etl::iflat_set<T, TKeyCompare>& lhs, const etl::iflat_set<T, TKeyCompare>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
}
|
||||
|
||||
#undef __ETL_IN_IFLAT_SET_H__
|
||||
#endif
|
||||
1066
src/iforward_list.h
1066
src/iforward_list.h
File diff suppressed because it is too large
Load Diff
1197
src/ilist.h
1197
src/ilist.h
File diff suppressed because it is too large
Load Diff
1695
src/imap.h
1695
src/imap.h
File diff suppressed because it is too large
Load Diff
1423
src/imultimap.h
1423
src/imultimap.h
File diff suppressed because it is too large
Load Diff
1404
src/imultiset.h
1404
src/imultiset.h
File diff suppressed because it is too large
Load Diff
305
src/ipool.h
305
src/ipool.h
@ -1,305 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
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_IPOOL__
|
||||
#define __ETL_IPOOL__
|
||||
#define __ETL_IN_IPOOL_H__
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include "platform.h"
|
||||
#include "nullptr.h"
|
||||
#include "alignment.h"
|
||||
#include "error_handler.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "11"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for pool exceptions.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the pool has no more free items.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_no_allocation : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
explicit pool_no_allocation(string_type file_name, numeric_type line_number)
|
||||
: pool_exception(ETL_ERROR_TEXT("pool:allocation", ETL_FILE"A"), file_name, line_number)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when an object is released which does not belong to the pool.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_object_not_in_pool : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_object_not_in_pool(string_type file_name, numeric_type line_number)
|
||||
: pool_exception(ETL_ERROR_TEXT("pool:notinpool", ETL_FILE"B"), file_name, line_number)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class ipool
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate an object from the pool.
|
||||
/// Uses the default constructor.
|
||||
/// If asserts or exceptions are enabled and there are no more free items an
|
||||
/// etl::pool_no_allocation if thrown, otherwise a nullptr is returned.
|
||||
//*************************************************************************
|
||||
template <typename T>
|
||||
T* allocate()
|
||||
{
|
||||
return reinterpret_cast<T*>(allocate_item());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Release an object in the pool.
|
||||
/// If asserts or exceptions are enabled and the object does not belong to this
|
||||
/// pool then an etl::pool_object_not_in_pool is thrown.
|
||||
/// \param p_object A pointer to the object to be released.
|
||||
//*************************************************************************
|
||||
void release(const void* p_object)
|
||||
{
|
||||
release_item((char*)p_object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Release all objects in the pool.
|
||||
//*************************************************************************
|
||||
void release_all()
|
||||
{
|
||||
items_allocated = 0;
|
||||
items_initialised = 0;
|
||||
p_next = p_buffer;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Check to see if the object belongs to the pool.
|
||||
/// \param p_object A pointer to the object to be checked.
|
||||
/// \return <b>true<\b> if it does, otherwise <b>false</b>
|
||||
//*************************************************************************
|
||||
//template <typename T>
|
||||
bool is_in_pool(const void* p_object) const
|
||||
{
|
||||
return is_item_in_pool((const char*)p_object);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum number of items in the pool.
|
||||
//*************************************************************************
|
||||
size_t max_items() const
|
||||
{
|
||||
return MAX_ITEMS;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of free items in the pool.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return MAX_ITEMS - items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of allocated items in the pool.
|
||||
//*************************************************************************
|
||||
size_t size() const
|
||||
{
|
||||
return items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no allocated items in the pool.
|
||||
/// \return <b>true</b> if there are none allocated.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return items_allocated == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no free items in the pool.
|
||||
/// \return <b>true</b> if there are none free.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return items_allocated == MAX_ITEMS;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
ipool(char* p_buffer_, uint32_t item_size, uint32_t max_items)
|
||||
: p_buffer(p_buffer_),
|
||||
p_next(p_buffer_),
|
||||
items_allocated(0),
|
||||
items_initialised(0),
|
||||
ITEM_SIZE(item_size),
|
||||
MAX_ITEMS(max_items)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//*************************************************************************
|
||||
/// Allocate an item from the pool.
|
||||
//*************************************************************************
|
||||
char* allocate_item()
|
||||
{
|
||||
char* p_value = nullptr;
|
||||
|
||||
// Any free space left?
|
||||
if (items_allocated < MAX_ITEMS)
|
||||
{
|
||||
// Initialise another one if necessary.
|
||||
if (items_initialised < MAX_ITEMS)
|
||||
{
|
||||
uintptr_t p = reinterpret_cast<uintptr_t>(p_buffer + (items_initialised * ITEM_SIZE));
|
||||
*reinterpret_cast<uintptr_t*>(p) = p + ITEM_SIZE;
|
||||
++items_initialised;
|
||||
}
|
||||
|
||||
// Get the address of new allocated item.
|
||||
p_value = p_next;
|
||||
|
||||
++items_allocated;
|
||||
if (items_allocated != MAX_ITEMS)
|
||||
{
|
||||
// Set up the pointer to the next free item
|
||||
p_next = *reinterpret_cast<char**>(p_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No more left!
|
||||
p_next = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ETL_ASSERT(false, ETL_ERROR(etl::pool_no_allocation));
|
||||
}
|
||||
|
||||
return p_value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Release an item back to the pool.
|
||||
//*************************************************************************
|
||||
void release_item(char* p_value)
|
||||
{
|
||||
// Does it belong to us?
|
||||
ETL_ASSERT(is_item_in_pool(p_value), ETL_ERROR(pool_object_not_in_pool));
|
||||
|
||||
if (p_next != nullptr)
|
||||
{
|
||||
// Point it to the current free item.
|
||||
*(uintptr_t*)p_value = reinterpret_cast<uintptr_t>(p_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the only free item.
|
||||
*((uintptr_t*)p_value) = 0;
|
||||
}
|
||||
|
||||
p_next = p_value;
|
||||
|
||||
--items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Check if the item belongs to this pool.
|
||||
//*************************************************************************
|
||||
bool is_item_in_pool(const char* p) const
|
||||
{
|
||||
// Within the range of the buffer?
|
||||
intptr_t distance = p - p_buffer;
|
||||
bool is_within_range = (distance >= 0) && (distance <= intptr_t((ITEM_SIZE * MAX_ITEMS) - ITEM_SIZE));
|
||||
|
||||
// Modulus and division can be slow on some architectures, so only do this in debug.
|
||||
#if defined(ETL_DEBUG)
|
||||
// Is the address on a valid object boundary?
|
||||
bool is_valid_address = ((distance % ITEM_SIZE) == 0);
|
||||
#else
|
||||
bool is_valid_address = true;
|
||||
#endif
|
||||
|
||||
return is_within_range && is_valid_address;
|
||||
}
|
||||
|
||||
// Disable copy construction and assignment.
|
||||
ipool(const ipool&);
|
||||
ipool& operator =(const ipool&);
|
||||
|
||||
char* p_buffer;
|
||||
char* p_next;
|
||||
|
||||
uint32_t items_allocated; ///< The number of items allocated.
|
||||
uint32_t items_initialised; ///< The number of items initialised.
|
||||
|
||||
const uint32_t ITEM_SIZE; ///< The size of allocated items.
|
||||
const uint32_t MAX_ITEMS; ///< The maximum number of objects that can be allocated.
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#undef __ETL_IN_IPOOL_H__
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,273 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove, rlindeman
|
||||
|
||||
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_IPRIORITY_QUEUE__
|
||||
#define __ETL_IPRIORITY_QUEUE__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "platform.h"
|
||||
#include "type_traits.h"
|
||||
#include "parameter_type.h"
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "12"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for priority_queue exceptions.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class priority_queue_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
priority_queue_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the queue is full.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class priority_queue_full : public priority_queue_exception
|
||||
{
|
||||
public:
|
||||
|
||||
priority_queue_full(string_type file_name, numeric_type line_number)
|
||||
: priority_queue_exception(ETL_ERROR_TEXT("priority_queue:full", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The priority queue iterator exception on reversed iterators
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class priority_queue_iterator : public priority_queue_exception
|
||||
{
|
||||
public:
|
||||
|
||||
priority_queue_iterator(string_type file_name, numeric_type line_number)
|
||||
: priority_queue_exception(ETL_ERROR_TEXT("priority_queue:iterator", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup queue
|
||||
///\brief This is the base for all priority queues that contain a particular type.
|
||||
///\details Normally a reference to this type will be taken from a derived queue.
|
||||
/// The TContainer specified must provide the front, push_back, pop_back, and
|
||||
/// assign methods to work correctly with priority_queue.
|
||||
///\code
|
||||
/// etl::priority_queue<int, 10> myPriorityQueue;
|
||||
/// etl::ipriority_queue<int>& iQueue = myPriorityQueue;
|
||||
///\endcode
|
||||
/// \warning This priority queue cannot be used for concurrent access from
|
||||
/// multiple threads.
|
||||
/// \tparam T The type of value that the queue holds.
|
||||
/// \tparam TContainer to hold the T queue values
|
||||
/// \tparam TCompare to use in comparing T values
|
||||
//***************************************************************************
|
||||
template <typename T, typename TContainer, typename TCompare>
|
||||
class ipriority_queue
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type; ///< The type stored in the queue.
|
||||
typedef TContainer container_type; ///< The container type used for priority queue.
|
||||
typedef TCompare compare_type; ///< The comparison type.
|
||||
typedef T& reference; ///< A reference to the type used in the queue.
|
||||
typedef const T& const_reference; ///< A const reference to the type used in the queue.
|
||||
typedef typename TContainer::size_type size_type; ///< The type used for determining the size of the queue.
|
||||
typedef typename std::iterator_traits<typename TContainer::iterator>::difference_type difference_type;
|
||||
|
||||
private:
|
||||
|
||||
typedef typename parameter_type<T>::type parameter_t;
|
||||
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets a reference to the highest priority value in the priority queue.<br>
|
||||
/// \return A reference to the highest priority value in the priority queue.
|
||||
//*************************************************************************
|
||||
reference top()
|
||||
{
|
||||
return container.front();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets a const reference to the highest priority value in the priority queue.<br>
|
||||
/// \return A const reference to the highest priority value in the priority queue.
|
||||
//*************************************************************************
|
||||
const_reference top() const
|
||||
{
|
||||
return container.front();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Adds a value to the queue.
|
||||
/// If asserts or exceptions are enabled, throws an etl::priority_queue_full
|
||||
/// is the priority queue is already full, otherwise does nothing if full.
|
||||
///\param value The value to push to the queue.
|
||||
//*************************************************************************
|
||||
void push(parameter_t value)
|
||||
{
|
||||
ETL_ASSERT(!full(), ETL_ERROR(priority_queue_full));
|
||||
|
||||
// Put element at end
|
||||
container.push_back(value);
|
||||
// Make elements in container into heap
|
||||
std::push_heap(container.begin(), container.end(), TCompare());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assigns values to the priority queue.
|
||||
/// If asserts or exceptions are enabled, emits priority_queue_full if
|
||||
/// priority queue does not have enough free space.
|
||||
/// If asserts or exceptions are enabled, emits priority_iterator if the
|
||||
/// iterators are reversed.
|
||||
///\param first The iterator to the first element.
|
||||
///\param last The iterator to the last element + 1.
|
||||
//*************************************************************************
|
||||
template <typename TIterator>
|
||||
void assign(TIterator first, TIterator last)
|
||||
{
|
||||
#if defined(ETL_DEBUG)
|
||||
difference_type count = std::distance(first, last);
|
||||
ETL_ASSERT(count >= 0, ETL_ERROR(priority_queue_iterator));
|
||||
ETL_ASSERT(static_cast<size_t>(count) <= max_size(), ETL_ERROR(priority_queue_full));
|
||||
#endif
|
||||
|
||||
clear();
|
||||
container.assign(first, last);
|
||||
std::make_heap(container.begin(), container.end(), TCompare());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Removes the oldest value from the back of the priority queue.
|
||||
/// Does nothing if the priority queue is already empty.
|
||||
//*************************************************************************
|
||||
void pop()
|
||||
{
|
||||
// Move largest element to end
|
||||
std::pop_heap(container.begin(), container.end(), TCompare());
|
||||
// Actually remove largest element at end
|
||||
container.pop_back();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the current number of items in the priority queue.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return container.size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum number of items that can be queued.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return container.max_size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the priority queue is empty.
|
||||
/// \return <b>true</b> if the queue is empty, otherwise <b>false</b>
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return container.empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the priority queue is full.
|
||||
/// \return <b>true</b> if the priority queue is full, otherwise <b>false</b>
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return container.size() == container.max_size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return container.max_size() - container.size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Clears the queue to the empty state.
|
||||
//*************************************************************************
|
||||
void clear()
|
||||
{
|
||||
container.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Make this a clone of the supplied priority queue
|
||||
//*************************************************************************
|
||||
void clone(const ipriority_queue& other)
|
||||
{
|
||||
assign(other.container.cbegin(), other.container.cend());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
ipriority_queue()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Disable copy construction.
|
||||
ipriority_queue(const ipriority_queue&);
|
||||
|
||||
/// The container specified at instantiation of the priority_queue
|
||||
TContainer container;
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
#endif
|
||||
229
src/iqueue.h
229
src/iqueue.h
@ -1,229 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
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_IQUEUE__
|
||||
#define __ETL_IQUEUE__
|
||||
#define __ETL_IN_IQUEUE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "private/queue_base.h"
|
||||
#include "type_traits.h"
|
||||
#include "parameter_type.h"
|
||||
#include "error_handler.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup queue
|
||||
///\brief This is the base for all queues that contain a particular type.
|
||||
///\details Normally a reference to this type will be taken from a derived queue.
|
||||
///\code
|
||||
/// etl::queue<int, 10> myQueue;
|
||||
/// etl::iqueue<int>& iQueue = myQueue;
|
||||
///\endcode
|
||||
/// \warning This queue cannot be used for concurrent access from multiple threads.
|
||||
/// \tparam T The type of value that the queue holds.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
class iqueue : public queue_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type; ///< The type stored in the queue.
|
||||
typedef T& reference; ///< A reference to the type used in the queue.
|
||||
typedef const T& const_reference; ///< A const reference to the type used in the queue.
|
||||
typedef T* pointer; ///< A pointer to the type used in the queue.
|
||||
typedef const T* const_pointer; ///< A const pointer to the type used in the queue.
|
||||
typedef queue_base::size_type size_type; ///< The type used for determining the size of the queue.
|
||||
|
||||
private:
|
||||
|
||||
typedef typename parameter_type<T>::type parameter_t;
|
||||
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets a reference to the value at the front of the queue.<br>
|
||||
/// \return A reference to the value at the front of the queue.
|
||||
//*************************************************************************
|
||||
reference front()
|
||||
{
|
||||
return p_buffer[out];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets a const reference to the value at the front of the queue.<br>
|
||||
/// \return A const reference to the value at the front of the queue.
|
||||
//*************************************************************************
|
||||
const_reference front() const
|
||||
{
|
||||
return p_buffer[out];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets a reference to the value at the back of the queue.<br>
|
||||
/// \return A reference to the value at the back of the queue.
|
||||
//*************************************************************************
|
||||
reference back()
|
||||
{
|
||||
return p_buffer[in == 0 ? MAX_SIZE - 1 : in - 1];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets a const reference to the value at the back of the queue.<br>
|
||||
/// \return A const reference to the value at the back of the queue.
|
||||
//*************************************************************************
|
||||
const_reference back() const
|
||||
{
|
||||
return p_buffer[in == 0 ? MAX_SIZE - 1 : in - 1];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Adds a value to the queue.
|
||||
/// If asserts or exceptions are enabled, throws an etl::queue_full if the queue if already full,
|
||||
/// otherwise does nothing if full.
|
||||
///\param value The value to push to the queue.
|
||||
//*************************************************************************
|
||||
void push(parameter_t value)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
|
||||
#endif
|
||||
::new (&p_buffer[in]) T(value);
|
||||
in = (in == (MAX_SIZE - 1)) ? 0 : in + 1;
|
||||
++current_size;
|
||||
++construct_count;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allows a possibly more efficient 'push' by moving to the next input value
|
||||
/// and returning a reference to it.
|
||||
/// This may eliminate a copy by allowing direct construction in-place.<br>
|
||||
/// If asserts or exceptions are enabled, throws an etl::queue_full is the queue is already full,
|
||||
/// otherwise does nothing if full.
|
||||
/// \return A reference to the position to 'push' to.
|
||||
//*************************************************************************
|
||||
reference push()
|
||||
{
|
||||
const size_type next = in;
|
||||
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(queue_full));
|
||||
#endif
|
||||
::new (&p_buffer[in]) T();
|
||||
in = (in == (MAX_SIZE - 1)) ? 0 : in + 1;
|
||||
++current_size;
|
||||
++construct_count;
|
||||
|
||||
return p_buffer[next];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Clears the queue to the empty state.
|
||||
//*************************************************************************
|
||||
void clear()
|
||||
{
|
||||
while (current_size > 0)
|
||||
{
|
||||
p_buffer[out].~T();
|
||||
out = (out == (MAX_SIZE - 1)) ? 0 : out + 1;
|
||||
--current_size;
|
||||
--construct_count;
|
||||
}
|
||||
|
||||
in = 0;
|
||||
out = 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Removes the oldest value from the back of the queue.
|
||||
/// Does nothing if the queue is already empty.
|
||||
//*************************************************************************
|
||||
void pop()
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!empty(), ETL_ERROR(queue_empty));
|
||||
#endif
|
||||
p_buffer[out].~T();
|
||||
out = (out == (MAX_SIZE - 1)) ? 0 : out + 1;
|
||||
--current_size;
|
||||
--construct_count;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
iqueue& operator = (const iqueue& rhs)
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
clone(rhs);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Make this a clone of the supplied queue
|
||||
//*************************************************************************
|
||||
void clone(const iqueue& other)
|
||||
{
|
||||
size_t index = other.out;
|
||||
|
||||
for (size_t i = 0; i < other.size(); ++i)
|
||||
{
|
||||
push(other.p_buffer[index]);
|
||||
index = (index == (MAX_SIZE - 1)) ? 0 : index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
iqueue(T* p_buffer, size_type max_size)
|
||||
: queue_base(max_size),
|
||||
p_buffer(p_buffer)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Disable copy construction.
|
||||
iqueue(const iqueue&);
|
||||
|
||||
T* p_buffer; ///< The internal buffer.
|
||||
};
|
||||
}
|
||||
|
||||
#undef __ETL_IN_IQUEUE_H__
|
||||
#endif
|
||||
1621
src/iset.h
1621
src/iset.h
File diff suppressed because it is too large
Load Diff
201
src/istack.h
201
src/istack.h
@ -1,201 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
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_ISTACK__
|
||||
#define __ETL_ISTACK__
|
||||
#define __ETL_IN_ISTACK_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "private/stack_base.h"
|
||||
#include "type_traits.h"
|
||||
#include "parameter_type.h"
|
||||
#include "error_handler.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup stack
|
||||
///\brief This is the base for all stacks that contain a particular type.
|
||||
///\details Normally a reference to this type will be taken from a derived stack.
|
||||
///\code
|
||||
/// etl::stack<int, 10> myQueue;
|
||||
/// etl::istack<int>& iQueue = myQueue;
|
||||
///\endcode
|
||||
/// \warning This stack cannot be used for concurrent access from multiple threads.
|
||||
/// \tparam T The type of value that the stack holds.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
class istack : public stack_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type; ///< The type stored in the stack.
|
||||
typedef T& reference; ///< A reference to the type used in the stack.
|
||||
typedef const T& const_reference; ///< A const reference to the type used in the stack.
|
||||
typedef T* pointer; ///< A pointer to the type used in the stack.
|
||||
typedef const T* const_pointer; ///< A const pointer to the type used in the stack.
|
||||
typedef stack_base::size_type size_type; ///< The type used for determining the size of the stack.
|
||||
|
||||
private:
|
||||
|
||||
typedef typename parameter_type<T>::type parameter_t;
|
||||
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets a reference to the value at the top of the stack.<br>
|
||||
/// \return A reference to the value at the top of the stack.
|
||||
//*************************************************************************
|
||||
reference top()
|
||||
{
|
||||
return p_buffer[top_index];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Adds a value to the stack.
|
||||
/// If asserts or exceptions are enabled, throws an etl::stack_full if the stack is already full.
|
||||
///\param value The value to push to the stack.
|
||||
//*************************************************************************
|
||||
void push(parameter_t value)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
|
||||
#endif
|
||||
top_index = current_size++;
|
||||
::new (&p_buffer[top_index]) T(value);
|
||||
++construct_count;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Allows a possibly more efficient 'push' by moving to the next input value
|
||||
/// and returning a reference to it.
|
||||
/// This may eliminate a copy by allowing direct construction in-place.<br>
|
||||
/// If asserts or exceptions are enabled, throws an etl::stack_full if the stack is already full.
|
||||
/// \return A reference to the position to 'push' to.
|
||||
//*************************************************************************
|
||||
reference push()
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!full(), ETL_ERROR(stack_full));
|
||||
#endif
|
||||
top_index = current_size++;
|
||||
::new (&p_buffer[top_index]) T();
|
||||
++construct_count;
|
||||
|
||||
return p_buffer[top_index];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets a const reference to the value at the top of the stack.<br>
|
||||
/// \return A const reference to the value at the top of the stack.
|
||||
//*************************************************************************
|
||||
const_reference top() const
|
||||
{
|
||||
return p_buffer[top_index];
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Clears the stack to the empty state.
|
||||
//*************************************************************************
|
||||
void clear()
|
||||
{
|
||||
while (current_size > 0)
|
||||
{
|
||||
p_buffer[top_index].~T();
|
||||
--top_index;
|
||||
--current_size;
|
||||
--construct_count;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Removes the oldest item from the top of the stack.
|
||||
/// Does nothing if the stack is already empty.
|
||||
//*************************************************************************
|
||||
void pop()
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(!empty(), ETL_ERROR(stack_empty));
|
||||
#endif
|
||||
p_buffer[top_index].~T();
|
||||
--top_index;
|
||||
--current_size;
|
||||
--construct_count;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
istack& operator = (const istack& rhs)
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
clone(rhs);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Make this a clone of the supplied stack
|
||||
//*************************************************************************
|
||||
void clone(const istack& other)
|
||||
{
|
||||
size_t index = 0;
|
||||
|
||||
for (size_t i = 0; i < other.size(); ++i)
|
||||
{
|
||||
push(other.p_buffer[index++]);
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
istack(T* p_buffer, size_type max_size)
|
||||
: stack_base(max_size),
|
||||
p_buffer(p_buffer)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Disable copy construction.
|
||||
istack(const istack&);
|
||||
|
||||
T* p_buffer; ///< The internal buffer.
|
||||
};
|
||||
}
|
||||
|
||||
#undef __ETL_IN_ISTACK_H__
|
||||
#endif
|
||||
1308
src/iunordered_map.h
1308
src/iunordered_map.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1189
src/iunordered_set.h
1189
src/iunordered_set.h
File diff suppressed because it is too large
Load Diff
953
src/ivector.h
953
src/ivector.h
@ -1,953 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
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_IVECTOR__
|
||||
#define __ETL_IVECTOR__
|
||||
#define __ETL_IN_IVECTOR_H__
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "platform.h"
|
||||
#include "algorithm.h"
|
||||
#include "private/vector_base.h"
|
||||
#include "type_traits.h"
|
||||
#include "parameter_type.h"
|
||||
#include "error_handler.h"
|
||||
#include "memory.h"
|
||||
|
||||
#ifdef ETL_COMPILER_GCC
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for specifically sized vectors.
|
||||
/// Can be used as a reference type for all vectors containing a specific type.
|
||||
///\ingroup vector
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
class ivector : public vector_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef size_t size_type;
|
||||
typedef typename std::iterator_traits<iterator>::difference_type difference_type;
|
||||
|
||||
protected:
|
||||
|
||||
typedef typename parameter_type<T>::type parameter_t;
|
||||
|
||||
public:
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns an iterator to the beginning of the vector.
|
||||
///\return An iterator to the beginning of the vector.
|
||||
//*********************************************************************
|
||||
iterator begin()
|
||||
{
|
||||
return p_buffer;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the beginning of the vector.
|
||||
///\return A const iterator to the beginning of the vector.
|
||||
//*********************************************************************
|
||||
const_iterator begin() const
|
||||
{
|
||||
return p_buffer;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns an iterator to the end of the vector.
|
||||
///\return An iterator to the end of the vector.
|
||||
//*********************************************************************
|
||||
iterator end()
|
||||
{
|
||||
return p_end;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the end of the vector.
|
||||
///\return A const iterator to the end of the vector.
|
||||
//*********************************************************************
|
||||
const_iterator end() const
|
||||
{
|
||||
return p_end;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the beginning of the vector.
|
||||
///\return A const iterator to the beginning of the vector.
|
||||
//*********************************************************************
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return p_buffer;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const_iterator to the end of the vector.
|
||||
///\return A const iterator to the end of the vector.
|
||||
//*********************************************************************
|
||||
const_iterator cend() const
|
||||
{
|
||||
return p_end;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns an reverse iterator to the reverse beginning of the vector.
|
||||
///\return Iterator to the reverse beginning of the vector.
|
||||
//*********************************************************************
|
||||
reverse_iterator rbegin()
|
||||
{
|
||||
return reverse_iterator(end());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the reverse beginning of the vector.
|
||||
///\return Const iterator to the reverse beginning of the vector.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator rbegin() const
|
||||
{
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a reverse iterator to the end + 1 of the vector.
|
||||
///\return Reverse iterator to the end + 1 of the vector.
|
||||
//*********************************************************************
|
||||
reverse_iterator rend()
|
||||
{
|
||||
return reverse_iterator(begin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the end + 1 of the vector.
|
||||
///\return Const reverse iterator to the end + 1 of the vector.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator rend() const
|
||||
{
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the reverse beginning of the vector.
|
||||
///\return Const reverse iterator to the reverse beginning of the vector.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator crbegin() const
|
||||
{
|
||||
return const_reverse_iterator(cend());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reverse iterator to the end + 1 of the vector.
|
||||
///\return Const reverse iterator to the end + 1 of the vector.
|
||||
//*********************************************************************
|
||||
const_reverse_iterator crend() const
|
||||
{
|
||||
return const_reverse_iterator(cbegin());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Resizes the vector.
|
||||
/// If asserts or exceptions are enabled and the new size is larger than the
|
||||
/// maximum then a vector_full is thrown.
|
||||
///\param new_size The new size.
|
||||
//*********************************************************************
|
||||
void resize(size_t new_size)
|
||||
{
|
||||
resize(new_size, T());
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Resizes the vector.
|
||||
/// If asserts or exceptions are enabled and the new size is larger than the
|
||||
/// maximum then a vector_full is thrown.
|
||||
///\param new_size The new size.
|
||||
///\param value The value to fill new elements with. Default = default constructed value.
|
||||
//*********************************************************************
|
||||
template <typename U = T>
|
||||
typename etl::enable_if<etl::has_trivial_constructor<U>::value, void>::type
|
||||
resize(size_t new_size, T value)
|
||||
{
|
||||
ETL_ASSERT(new_size <= MAX_SIZE, ETL_ERROR(vector_full));
|
||||
|
||||
const size_t current_size = size();
|
||||
size_t delta = (current_size < new_size) ? new_size - current_size : current_size - new_size;
|
||||
|
||||
if (current_size < new_size)
|
||||
{
|
||||
std::fill_n(p_end, delta, value);
|
||||
#if defined(ETL_DEBUG)
|
||||
construct_count += delta;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
p_end -= delta;
|
||||
#if defined(ETL_DEBUG)
|
||||
construct_count -= delta;
|
||||
#endif
|
||||
}
|
||||
|
||||
p_end = p_buffer + new_size;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Resizes the vector.
|
||||
/// If asserts or exceptions are enabled and the new size is larger than the
|
||||
/// maximum then a vector_full is thrown.
|
||||
///\param new_size The new size.
|
||||
///\param value The value to fill new elements with. Default = default constructed value.
|
||||
//*********************************************************************
|
||||
template <typename U = T>
|
||||
typename etl::enable_if<!etl::has_trivial_constructor<U>::value, void>::type
|
||||
resize(size_t new_size, T value)
|
||||
{
|
||||
ETL_ASSERT(new_size <= MAX_SIZE, ETL_ERROR(vector_full));
|
||||
|
||||
const size_t current_size = size();
|
||||
size_t delta = (current_size < new_size) ? new_size - current_size : current_size - new_size;
|
||||
|
||||
if (current_size < new_size)
|
||||
{
|
||||
etl::uninitialized_fill_n(p_end, delta, value);
|
||||
#if defined(ETL_DEBUG)
|
||||
construct_count += delta;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
etl::destroy_n(p_end - delta, delta);
|
||||
#if defined(ETL_DEBUG)
|
||||
construct_count -= delta;
|
||||
#endif
|
||||
}
|
||||
|
||||
p_end = p_buffer + new_size;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Does nothing.
|
||||
//*********************************************************************
|
||||
void reserve(size_t)
|
||||
{
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a reference to the value at index 'i'
|
||||
///\param i The index.
|
||||
///\return A reference to the value at index 'i'
|
||||
//*********************************************************************
|
||||
reference operator [](size_t i)
|
||||
{
|
||||
return p_buffer[i];
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reference to the value at index 'i'
|
||||
///\param i The index.
|
||||
///\return A const reference to the value at index 'i'
|
||||
//*********************************************************************
|
||||
const_reference operator [](size_t i) const
|
||||
{
|
||||
return p_buffer[i];
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a reference to the value at index 'i'
|
||||
/// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range.
|
||||
///\param i The index.
|
||||
///\return A reference to the value at index 'i'
|
||||
//*********************************************************************
|
||||
reference at(size_t i)
|
||||
{
|
||||
ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds));
|
||||
return p_buffer[i];
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reference to the value at index 'i'
|
||||
/// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range.
|
||||
///\param i The index.
|
||||
///\return A const reference to the value at index 'i'
|
||||
//*********************************************************************
|
||||
const_reference at(size_t i) const
|
||||
{
|
||||
ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds));
|
||||
return p_buffer[i];
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a reference to the first element.
|
||||
///\return A reference to the first element.
|
||||
//*********************************************************************
|
||||
reference front()
|
||||
{
|
||||
return *p_buffer;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reference to the first element.
|
||||
///\return A const reference to the first element.
|
||||
//*********************************************************************
|
||||
const_reference front() const
|
||||
{
|
||||
return *p_buffer;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a reference to the last element.
|
||||
///\return A reference to the last element.
|
||||
//*********************************************************************
|
||||
reference back()
|
||||
{
|
||||
return *(p_end - 1);
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const reference to the last element.
|
||||
///\return A const reference to the last element.
|
||||
//*********************************************************************
|
||||
const_reference back() const
|
||||
{
|
||||
return *(p_end - 1);
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a pointer to the beginning of the vector data.
|
||||
///\return A pointer to the beginning of the vector data.
|
||||
//*********************************************************************
|
||||
pointer data()
|
||||
{
|
||||
return p_buffer;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Returns a const pointer to the beginning of the vector data.
|
||||
///\return A const pointer to the beginning of the vector data.
|
||||
//*********************************************************************
|
||||
const_pointer data() const
|
||||
{
|
||||
return p_buffer;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Assigns values to the vector.
|
||||
/// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space.
|
||||
/// If asserts or exceptions are enabled, emits vector_iterator if the iterators are reversed.
|
||||
///\param first The iterator to the first element.
|
||||
///\param last The iterator to the last element + 1.
|
||||
//*********************************************************************
|
||||
template <typename TIterator>
|
||||
void assign(TIterator first, TIterator last)
|
||||
{
|
||||
#if defined(ETL_DEBUG)
|
||||
difference_type count = std::distance(first, last);
|
||||
ETL_ASSERT(static_cast<size_t>(count) <= MAX_SIZE, ETL_ERROR(vector_full));
|
||||
#endif
|
||||
|
||||
initialise();
|
||||
|
||||
#if defined(ETL_DEBUG)
|
||||
p_end = etl::uninitialized_copy(first, last, p_buffer, construct_count);
|
||||
#else
|
||||
p_end = etl::uninitialized_copy(first, last, p_buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Assigns values to the vector.
|
||||
/// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space.
|
||||
///\param n The number of elements to add.
|
||||
///\param value The value to insert for each element.
|
||||
//*********************************************************************
|
||||
void assign(size_t n, parameter_t value)
|
||||
{
|
||||
ETL_ASSERT(n <= MAX_SIZE, ETL_ERROR(vector_full));
|
||||
|
||||
initialise();
|
||||
|
||||
#if defined(ETL_DEBUG)
|
||||
p_end = etl::uninitialized_fill_n(p_buffer, n, value, construct_count);
|
||||
#else
|
||||
p_end = etl::uninitialized_fill_n(p_buffer, n, value);
|
||||
#endif
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Clears the vector.
|
||||
//*************************************************************************
|
||||
void clear()
|
||||
{
|
||||
initialise();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Increases the size of the vector by one, but does not initialise the new element.
|
||||
/// If asserts or exceptions are enabled, throws a vector_full if the vector is already full.
|
||||
//*************************************************************************
|
||||
void push_back()
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(size() != MAX_SIZE, ETL_ERROR(vector_full));
|
||||
#endif
|
||||
|
||||
create_back();
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts a value at the end of the vector.
|
||||
/// If asserts or exceptions are enabled, emits vector_full if the vector is already full.
|
||||
///\param value The value to add.
|
||||
//*********************************************************************
|
||||
void push_back(parameter_t value)
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(size() != MAX_SIZE, ETL_ERROR(vector_full));
|
||||
#endif
|
||||
create_back(value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Removes an element from the end of the vector.
|
||||
/// Does nothing if the vector is empty.
|
||||
//*************************************************************************
|
||||
void pop_back()
|
||||
{
|
||||
#if defined(ETL_CHECK_PUSH_POP)
|
||||
ETL_ASSERT(size() > 0, ETL_ERROR(vector_empty));
|
||||
#endif
|
||||
destroy_back();
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts a value to the vector.
|
||||
/// If asserts or exceptions are enabled, emits vector_full if the vector is already full.
|
||||
///\param position The position to insert before.
|
||||
///\param value The value to insert.
|
||||
//*********************************************************************
|
||||
iterator insert(iterator position, parameter_t value)
|
||||
{
|
||||
ETL_ASSERT(size() + 1 <= MAX_SIZE, ETL_ERROR(vector_full));
|
||||
|
||||
if (position == end())
|
||||
{
|
||||
create_back(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
create_back(back());
|
||||
std::copy_backward(position, p_end - 1, p_end);
|
||||
*position = value;
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts 'n' values to the vector.
|
||||
/// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space.
|
||||
///\param position The position to insert before.
|
||||
///\param n The number of elements to add.
|
||||
///\param value The value to insert.
|
||||
//*********************************************************************
|
||||
template <typename U = T>
|
||||
typename etl::enable_if<etl::has_trivial_constructor<U>::value, void>::type
|
||||
insert(iterator position, size_t n, parameter_t value)
|
||||
{
|
||||
ETL_ASSERT((size() + n) <= MAX_SIZE, ETL_ERROR(vector_full));
|
||||
|
||||
std::copy_backward(position, p_end, p_end + n);
|
||||
std::fill_n(position, n, value);
|
||||
|
||||
construct_count += n;
|
||||
p_end += n;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts 'n' values to the vector.
|
||||
/// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space.
|
||||
///\param position The position to insert before.
|
||||
///\param n The number of elements to add.
|
||||
///\param value The value to insert.
|
||||
//*********************************************************************
|
||||
template <typename U = T>
|
||||
typename etl::enable_if<!etl::has_trivial_constructor<U>::value, void>::type
|
||||
insert(iterator position, size_t n, parameter_t value)
|
||||
{
|
||||
ETL_ASSERT((size() + n) <= MAX_SIZE, ETL_ERROR(vector_full));
|
||||
|
||||
size_t insert_n = n;
|
||||
size_t insert_begin = std::distance(begin(), position);
|
||||
size_t insert_end = insert_begin + insert_n;
|
||||
|
||||
// Copy old data.
|
||||
size_t copy_old_n;
|
||||
size_t construct_old_n;
|
||||
iterator p_construct_old;
|
||||
|
||||
if (insert_end > size())
|
||||
{
|
||||
copy_old_n = 0;
|
||||
construct_old_n = size() - insert_begin;
|
||||
p_construct_old = p_buffer + insert_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_old_n = size() - insert_begin - insert_n;
|
||||
construct_old_n = insert_n;
|
||||
p_construct_old = p_end;
|
||||
}
|
||||
|
||||
size_t copy_new_n = construct_old_n;
|
||||
size_t construct_new_n = insert_n - copy_new_n;
|
||||
|
||||
#if defined(ETL_DEBUG)
|
||||
// Construct old.
|
||||
etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old, construct_count);
|
||||
|
||||
// Copy old.
|
||||
etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end);
|
||||
|
||||
// Construct new.
|
||||
etl::uninitialized_fill_n(p_end, construct_new_n, value, construct_count);
|
||||
|
||||
// Copy new.
|
||||
std::fill_n(p_buffer + insert_begin, copy_new_n, value);
|
||||
#else
|
||||
// Construct old.
|
||||
etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old);
|
||||
|
||||
// Copy old.
|
||||
etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end);
|
||||
|
||||
// Construct new.
|
||||
etl::uninitialized_fill_n(p_end, construct_new_n, value);
|
||||
|
||||
// Copy new.
|
||||
std::fill_n(p_buffer + insert_begin, copy_new_n, value);
|
||||
#endif
|
||||
|
||||
p_end += n;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts a range of values to the vector.
|
||||
/// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space.
|
||||
/// For fundamental and pointer types.
|
||||
///\param position The position to insert before.
|
||||
///\param first The first element to add.
|
||||
///\param last The last + 1 element to add.
|
||||
//*********************************************************************
|
||||
template <class TIterator, typename U = T>
|
||||
typename etl::enable_if<etl::has_trivial_constructor<U>::value, void>::type
|
||||
insert(iterator position, TIterator first, TIterator last)
|
||||
{
|
||||
size_t count = std::distance(first, last);
|
||||
|
||||
ETL_ASSERT((size() + count) <= MAX_SIZE, ETL_ERROR(vector_full));
|
||||
|
||||
construct_count += count;
|
||||
|
||||
if (position == end())
|
||||
{
|
||||
p_end = std::copy(first, last, p_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::copy_backward(position, p_end, p_end + count);
|
||||
std::copy(first, last, position);
|
||||
p_end += count;
|
||||
}
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Inserts a range of values to the vector.
|
||||
/// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space.
|
||||
/// For fundamental and pointer types.
|
||||
///\param position The position to insert before.
|
||||
///\param first The first element to add.
|
||||
///\param last The last + 1 element to add.
|
||||
//*********************************************************************
|
||||
template <class TIterator, typename U = T>
|
||||
typename etl::enable_if<!etl::has_trivial_constructor<U>::value, void>::type
|
||||
insert(iterator position, TIterator first, TIterator last)
|
||||
{
|
||||
size_t count = std::distance(first, last);
|
||||
|
||||
ETL_ASSERT((size() + count) <= MAX_SIZE, ETL_ERROR(vector_full));
|
||||
|
||||
size_t insert_n = count;
|
||||
size_t insert_begin = std::distance(begin(), position);
|
||||
size_t insert_end = insert_begin + insert_n;
|
||||
|
||||
// Copy old data.
|
||||
size_t copy_old_n;
|
||||
size_t construct_old_n;
|
||||
iterator p_construct_old;
|
||||
|
||||
if (insert_end > size())
|
||||
{
|
||||
copy_old_n = 0;
|
||||
construct_old_n = size() - insert_begin;
|
||||
p_construct_old = p_buffer + insert_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
copy_old_n = size() - insert_begin - insert_n;
|
||||
construct_old_n = insert_n;
|
||||
p_construct_old = p_end;
|
||||
}
|
||||
|
||||
size_t copy_new_n = construct_old_n;
|
||||
size_t construct_new_n = insert_n - copy_new_n;
|
||||
|
||||
#if defined(ETL_DEBUG)
|
||||
// Construct old.
|
||||
etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old, construct_count);
|
||||
|
||||
// Copy old.
|
||||
etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end);
|
||||
|
||||
// Construct new.
|
||||
etl::uninitialized_copy_n(first + copy_new_n, construct_new_n, p_end, construct_count);
|
||||
|
||||
// Copy new.
|
||||
etl::copy_n(first, copy_new_n, p_buffer + insert_begin);
|
||||
#else
|
||||
// Construct old.
|
||||
etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old);
|
||||
|
||||
// Copy old.
|
||||
etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end);
|
||||
|
||||
// Construct new.
|
||||
etl::uninitialized_copy_n(first + copy_new_n, construct_new_n, p_end);
|
||||
|
||||
// Copy new.
|
||||
etl::copy_n(first, copy_new_n, p_buffer + insert_begin);
|
||||
#endif
|
||||
|
||||
p_end += count;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Erases an element.
|
||||
///\param i_element Iterator to the element.
|
||||
///\return An iterator pointing to the element that followed the erased element.
|
||||
//*********************************************************************
|
||||
iterator erase(iterator i_element)
|
||||
{
|
||||
std::copy(i_element + 1, end(), i_element);
|
||||
destroy_back();
|
||||
|
||||
return i_element;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// 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.
|
||||
///\return An iterator pointing to the element that followed the erased element.
|
||||
//*********************************************************************
|
||||
template <typename U = T>
|
||||
typename etl::enable_if<etl::has_trivial_constructor<U>::value, iterator>::type
|
||||
erase(iterator first, iterator last)
|
||||
{
|
||||
if (first == begin() && last == end())
|
||||
{
|
||||
clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::copy(last, end(), first);
|
||||
size_t n_delete = std::distance(first, last);
|
||||
construct_count -= n_delete;
|
||||
p_end -= n_delete;
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// 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.
|
||||
///\return An iterator pointing to the element that followed the erased element.
|
||||
//*********************************************************************
|
||||
template <typename U = T>
|
||||
typename etl::enable_if<!etl::has_trivial_constructor<U>::value, iterator>::type
|
||||
erase(iterator first, iterator last)
|
||||
{
|
||||
if (first == begin() && last == end())
|
||||
{
|
||||
clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::copy(last, end(), first);
|
||||
size_t n_delete = std::distance(first, last);
|
||||
|
||||
// Destroy the elements left over at the end.
|
||||
#if defined(ETL_DEBUG)
|
||||
etl::destroy(p_end - n_delete, p_end, construct_count);
|
||||
#else
|
||||
etl::destroy(p_end - n_delete, p_end);
|
||||
#endif
|
||||
p_end -= n_delete;
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Assignment operator.
|
||||
//*************************************************************************
|
||||
ivector& operator = (const ivector& rhs)
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
assign(rhs.cbegin(), rhs.cend());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the vector.
|
||||
///\return The current size of the vector.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return size_t(p_end - p_buffer);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'empty' state of the vector.
|
||||
///\return <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return (p_end == p_buffer);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the vector.
|
||||
///\return <b>true</b> if full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return size() == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*********************************************************************
|
||||
/// Constructor.
|
||||
//*********************************************************************
|
||||
ivector(T* p_buffer_, size_t MAX_SIZE)
|
||||
: vector_base(MAX_SIZE),
|
||||
p_buffer(p_buffer_),
|
||||
p_end(p_buffer_)
|
||||
{
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Initialise the vector.
|
||||
//*********************************************************************
|
||||
void initialise()
|
||||
{
|
||||
#if defined(ETL_DEBUG)
|
||||
etl::destroy(p_buffer, p_end, construct_count);
|
||||
#else
|
||||
etl::destroy(p_buffer, p_end);
|
||||
#endif
|
||||
|
||||
p_end = p_buffer;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
pointer p_buffer; ///< Pointer to the start of the buffer.
|
||||
pointer p_end; ///< Pointer to one past the last element in the buffer.
|
||||
|
||||
//*********************************************************************
|
||||
/// Create a new element with a default value at the back.
|
||||
//*********************************************************************
|
||||
inline void create_back()
|
||||
{
|
||||
#if defined(ETL_DEBUG)
|
||||
etl::create_value_at(p_end, construct_count);
|
||||
#else
|
||||
etl::create_value_at(p_end);
|
||||
#endif
|
||||
++p_end;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Create a new element with a value at the back
|
||||
//*********************************************************************
|
||||
inline void create_back(parameter_t value)
|
||||
{
|
||||
#if defined(ETL_DEBUG)
|
||||
etl::create_copy_at(p_end, value, construct_count);
|
||||
#else
|
||||
etl::create_copy_at(p_end, value);
|
||||
#endif
|
||||
++p_end;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
/// Destroy an element at the back.
|
||||
//*********************************************************************
|
||||
inline void destroy_back()
|
||||
{
|
||||
--p_end;
|
||||
|
||||
#if defined(ETL_DEBUG)
|
||||
etl::destroy_at(p_end, construct_count);
|
||||
#else
|
||||
etl::destroy_at(p_end);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Disable copy construction.
|
||||
ivector(const ivector&);
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Equal operator.
|
||||
///\param lhs Reference to the first vector.
|
||||
///\param rhs Reference to the second vector.
|
||||
///\return <b>true</b> if the arrays are equal, otherwise <b>false</b>
|
||||
///\ingroup vector
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
bool operator ==(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs)
|
||||
{
|
||||
return (lhs.size() == rhs.size()) && std::equal(lhs.begin(), lhs.end(), rhs.begin());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Not equal operator.
|
||||
///\param lhs Reference to the first vector.
|
||||
///\param rhs Reference to the second vector.
|
||||
///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b>
|
||||
///\ingroup vector
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
bool operator !=(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Less than operator.
|
||||
///\param lhs Reference to the first vector.
|
||||
///\param rhs Reference to the second vector.
|
||||
///\return <b>true</b> if the first vector is lexicographically less than the second, otherwise <b>false</b>
|
||||
///\ingroup vector
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
bool operator <(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs)
|
||||
{
|
||||
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Greater than operator.
|
||||
///\param lhs Reference to the first vector.
|
||||
///\param rhs Reference to the second vector.
|
||||
///\return <b>true</b> if the first vector is lexicographically greater than the second, otherwise <b>false</b>
|
||||
///\ingroup vector
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
bool operator >(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs)
|
||||
{
|
||||
return (rhs < lhs);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Less than or equal operator.
|
||||
///\param lhs Reference to the first vector.
|
||||
///\param rhs Reference to the second vector.
|
||||
///\return <b>true</b> if the first vector is lexicographically less than or equal to the second, otherwise <b>false</b>
|
||||
///\ingroup vector
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
bool operator <=(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs)
|
||||
{
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Greater than or equal operator.
|
||||
///\param lhs Reference to the first vector.
|
||||
///\param rhs Reference to the second vector.
|
||||
///\return <b>true</b> if the first vector is lexicographically greater than or equal to the second, otherwise <b>false</b>
|
||||
///\ingroup vector
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
bool operator >=(const etl::ivector<T>& lhs, const etl::ivector<T>& rhs)
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
}
|
||||
|
||||
#include "private/ivectorpointer.h"
|
||||
|
||||
#undef __ETL_IN_IVECTOR_H__
|
||||
#endif
|
||||
@ -1,181 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
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_IN_IDEQUE_H__
|
||||
#error This header is a private element of etl::deque & etl::ideque
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_DEQUE_BASE__
|
||||
#define __ETL_DEQUE_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "1"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception base for deques
|
||||
///\ingroup deque
|
||||
//***************************************************************************
|
||||
class deque_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
deque_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Deque full exception.
|
||||
///\ingroup deque
|
||||
//***************************************************************************
|
||||
class deque_full : public deque_exception
|
||||
{
|
||||
public:
|
||||
|
||||
deque_full(string_type file_name, numeric_type line_number)
|
||||
: deque_exception(ETL_ERROR_TEXT("deque:full", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Deque empty exception.
|
||||
///\ingroup deque
|
||||
//***************************************************************************
|
||||
class deque_empty : public deque_exception
|
||||
{
|
||||
public:
|
||||
|
||||
deque_empty(string_type file_name, numeric_type line_number)
|
||||
: deque_exception(ETL_ERROR_TEXT("deque:empty", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Deque out of bounds exception.
|
||||
///\ingroup deque
|
||||
//***************************************************************************
|
||||
class deque_out_of_bounds : public deque_exception
|
||||
{
|
||||
public:
|
||||
|
||||
deque_out_of_bounds(string_type file_name, numeric_type line_number)
|
||||
: deque_exception(ETL_ERROR_TEXT("deque:bounds", ETL_FILE"C"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base class for all templated deque types.
|
||||
///\ingroup deque
|
||||
//***************************************************************************
|
||||
class deque_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the deque.
|
||||
///\return The current size of the deque.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'empty' state of the deque.
|
||||
///\return <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return (current_size == 0);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the deque.
|
||||
///\return <b>true</b> if full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return current_size == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum possible size of the deque.
|
||||
///\return The maximum size of the deque.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor.
|
||||
//*************************************************************************
|
||||
deque_base(size_t max_size, size_t buffer_size)
|
||||
: current_size(0),
|
||||
MAX_SIZE(max_size),
|
||||
BUFFER_SIZE(buffer_size)
|
||||
{
|
||||
}
|
||||
|
||||
size_type current_size; ///< The current number of elements in the deque.
|
||||
const size_type MAX_SIZE; ///< The maximum number of elements in the deque.
|
||||
const size_type BUFFER_SIZE; ///< The number of elements in the buffer.
|
||||
etl::debug_count construct_count; ///< Internal debugging.
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,110 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove
|
||||
|
||||
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_IN_IFLAT_MAP_H__
|
||||
#error This header is a private element of etl::flat_map & etl::iflat_map
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_FLAT_MAP_BASE__
|
||||
#define __ETL_FLAT_MAP_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../exception.h"
|
||||
#include "../ivector.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "2"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup flat_map
|
||||
/// Exception base for flat_maps
|
||||
//***************************************************************************
|
||||
class flat_map_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_map_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_map
|
||||
/// Vector full exception.
|
||||
//***************************************************************************
|
||||
class flat_map_full : public flat_map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_map_full(string_type file_name, numeric_type line_number)
|
||||
: flat_map_exception(ETL_ERROR_TEXT("flat_map: full", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_map
|
||||
/// Vector out of bounds exception.
|
||||
//***************************************************************************
|
||||
class flat_map_out_of_bounds : public flat_map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_map_out_of_bounds(string_type file_name, numeric_type line_number)
|
||||
: flat_map_exception(ETL_ERROR_TEXT("flat_map:bounds", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_map
|
||||
/// The base class for all templated flat_map types.
|
||||
//***************************************************************************
|
||||
class flat_map_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
protected:
|
||||
|
||||
etl::debug_count construct_count; ///< Internal debugging.
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,94 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove
|
||||
|
||||
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_IN_IFLAT_MULTIMAP_H__
|
||||
#error This header is a private element of etl::flat_multimap & etl::iflat_multimap
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_FLAT_MULTIMAP_BASE__
|
||||
#define __ETL_FLAT_MULTIMAP_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../exception.h"
|
||||
#include "../ivector.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "3"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multimap
|
||||
/// Exception base for flat_multimaps
|
||||
//***************************************************************************
|
||||
class flat_multimap_exception : public 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 flat_multimap_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multimap_full(string_type file_name, numeric_type line_number)
|
||||
: 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;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,105 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove
|
||||
|
||||
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_IN_IFLAT_MULTISET_H__
|
||||
#error This header is a private element of etl::flat_multiset & etl::iflat_multiset
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_FLAT_MULTISET_BASE__
|
||||
#define __ETL_FLAT_MULTISET_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../exception.h"
|
||||
#include "../ivector.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "4"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multiset
|
||||
/// Exception base for flat_multisets
|
||||
//***************************************************************************
|
||||
class flat_multiset_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multiset_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multiset
|
||||
/// Flat multiset full exception.
|
||||
//***************************************************************************
|
||||
class flat_multiset_full : public flat_multiset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multiset_full(string_type file_name, numeric_type line_number)
|
||||
: 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()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,109 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove
|
||||
|
||||
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_IN_IFLAT_SET_H__
|
||||
#error This header is a private element of etl::flat_set & etl::iflat_set
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_FLAT_SET_BASE__
|
||||
#define __ETL_FLAT_SET_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "5"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup flat_set
|
||||
/// Exception base for flat_sets
|
||||
//***************************************************************************
|
||||
class flat_set_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_set_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_set
|
||||
/// Vector full exception.
|
||||
//***************************************************************************
|
||||
class flat_set_full : public flat_set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_set_full(string_type file_name, numeric_type line_number)
|
||||
: flat_set_exception(ETL_ERROR_TEXT("flat_set:full", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_set
|
||||
/// Vector iterator exception.
|
||||
//***************************************************************************
|
||||
class flat_set_iterator : public flat_set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_set_iterator(string_type file_name, numeric_type line_number)
|
||||
: flat_set_exception(ETL_ERROR_TEXT("flat_set:iterator", ETL_FILE"C"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_set
|
||||
/// The base class for all templated flat_set types.
|
||||
//***************************************************************************
|
||||
class flat_set_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
protected:
|
||||
|
||||
etl::debug_count construct_count;
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,260 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
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_IN_IFORWARD_LIST_H__
|
||||
#error This header is a private element of etl::forward_list & etl::iforward_list
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_LIST_BASE__
|
||||
#define __ETL_LIST_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "6"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the forward_list.
|
||||
///\ingroup forward_list
|
||||
//***************************************************************************
|
||||
class forward_list_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
forward_list_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the forward_list.
|
||||
///\ingroup forward_list
|
||||
//***************************************************************************
|
||||
class forward_list_full : public forward_list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
forward_list_full(string_type file_name, numeric_type line_number)
|
||||
: forward_list_exception(ETL_ERROR_TEXT("forward_list:full", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Empty exception for the forward_list.
|
||||
///\ingroup forward_list
|
||||
//***************************************************************************
|
||||
class forward_list_empty : public forward_list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
forward_list_empty(string_type file_name, numeric_type line_number)
|
||||
: forward_list_exception(ETL_ERROR_TEXT("forward_list:empty", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the forward_list.
|
||||
///\ingroup forward_list
|
||||
//***************************************************************************
|
||||
class forward_list_iterator : public forward_list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
forward_list_iterator(string_type file_name, numeric_type line_number)
|
||||
: forward_list_exception(ETL_ERROR_TEXT("forward_list:iterator", ETL_FILE"C"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base class for all forward_lists.
|
||||
///\ingroup forward_list
|
||||
//***************************************************************************
|
||||
class forward_list_base
|
||||
{
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// The node element in the forward_list.
|
||||
//*************************************************************************
|
||||
struct node_t
|
||||
{
|
||||
node_t()
|
||||
: next(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
node_t* next;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef size_t size_type; ///< The type used for determining the size of forward_list.
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the forward_list.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return p_node_pool->size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the maximum possible size of the forward_list.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the forward_list is empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return p_node_pool->empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the forward_list is full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return p_node_pool->full();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return p_node_pool->available();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Reverses the forward_list.
|
||||
//*************************************************************************
|
||||
void reverse()
|
||||
{
|
||||
if (is_trivial_list())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
node_t* p_last = &start_node;
|
||||
node_t* p_current = p_last->next;
|
||||
node_t* p_next = p_current->next;
|
||||
|
||||
p_current->next = nullptr;
|
||||
|
||||
while (p_next != nullptr)
|
||||
{
|
||||
p_last = p_current;
|
||||
p_current = p_next;
|
||||
p_next = p_current->next;
|
||||
|
||||
p_current->next = p_last;
|
||||
}
|
||||
|
||||
join(&start_node, p_current);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
forward_list_base(etl::ipool& node_pool, size_type max_size)
|
||||
: p_node_pool(&node_pool),
|
||||
MAX_SIZE(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the head node.
|
||||
//*************************************************************************
|
||||
node_t& get_head()
|
||||
{
|
||||
return *start_node.next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the head node.
|
||||
//*************************************************************************
|
||||
const node_t& get_head() const
|
||||
{
|
||||
return *start_node.next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Insert a node.
|
||||
//*************************************************************************
|
||||
inline void insert_node_after(node_t& position, node_t& node)
|
||||
{
|
||||
// Connect to the forward_list.
|
||||
join(&node, position.next);
|
||||
join(&position, &node);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Is the forward_list a trivial length?
|
||||
//*************************************************************************
|
||||
bool is_trivial_list() const
|
||||
{
|
||||
return (size() < 2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Join two nodes.
|
||||
//*************************************************************************
|
||||
void join(node_t* left, node_t* right)
|
||||
{
|
||||
left->next = right;
|
||||
}
|
||||
|
||||
node_t start_node; ///< The node that acts as the forward_list start.
|
||||
etl::ipool* p_node_pool; ///< The pool of data nodes used in the list.
|
||||
const size_type MAX_SIZE; ///< The maximum size of the forward_list.
|
||||
etl::debug_count construct_count; ///< Internal debugging.
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,305 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
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_IN_ILIST_H__
|
||||
#error This header is a private element of etl::list & etl::ilist
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_LIST_BASE__
|
||||
#define __ETL_LIST_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
#include "pool.h"
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "7"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the list.
|
||||
///\ingroup list
|
||||
//***************************************************************************
|
||||
class list_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
list_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the list.
|
||||
///\ingroup list
|
||||
//***************************************************************************
|
||||
class list_full : public list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
list_full(string_type file_name, numeric_type line_number)
|
||||
: list_exception(ETL_ERROR_TEXT("list:full", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Empty exception for the list.
|
||||
///\ingroup list
|
||||
//***************************************************************************
|
||||
class list_empty : public list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
list_empty(string_type file_name, numeric_type line_number)
|
||||
: list_exception(ETL_ERROR_TEXT("list:empty", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the list.
|
||||
///\ingroup list
|
||||
//***************************************************************************
|
||||
class list_iterator : public list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
list_iterator(string_type file_name, numeric_type line_number)
|
||||
: list_exception(ETL_ERROR_TEXT("list:iterator", ETL_FILE"C"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Unsorted exception for the list.
|
||||
///\ingroup list
|
||||
//***************************************************************************
|
||||
class list_unsorted : public list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
list_unsorted(string_type file_name, numeric_type line_number)
|
||||
: list_exception(ETL_ERROR_TEXT("list:unsorted", ETL_FILE"D"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base class for all lists.
|
||||
///\ingroup list
|
||||
//***************************************************************************
|
||||
class list_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type; ///< The type used for determining the size of list.
|
||||
|
||||
//*************************************************************************
|
||||
/// The node element in the list.
|
||||
//*************************************************************************
|
||||
struct node_t
|
||||
{
|
||||
//***********************************************************************
|
||||
/// Constructor
|
||||
//***********************************************************************
|
||||
node_t()
|
||||
: previous(nullptr),
|
||||
next(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Reverses the previous & next pointers.
|
||||
//***********************************************************************
|
||||
inline void reverse()
|
||||
{
|
||||
std::swap(previous, next);
|
||||
}
|
||||
|
||||
node_t* previous;
|
||||
node_t* next;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Reverses the list.
|
||||
//*************************************************************************
|
||||
void reverse()
|
||||
{
|
||||
if (is_trivial_list())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
node_t* p_node = terminal_node.next;
|
||||
|
||||
while (p_node != &terminal_node)
|
||||
{
|
||||
node_t* p_temp = p_node->previous;
|
||||
p_node->previous = p_node->next;
|
||||
p_node->next = p_temp;
|
||||
p_node = p_node->previous;
|
||||
}
|
||||
|
||||
// Terminal node.
|
||||
node_t* p_temp = p_node->previous;
|
||||
p_node->previous = p_node->next;
|
||||
p_node->next = p_temp;
|
||||
p_node = p_node->previous;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the maximum possible size of the list.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the list.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return p_node_pool->size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the list is empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return p_node_pool->empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the list is full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return p_node_pool->size() == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Is the list a trivial length?
|
||||
//*************************************************************************
|
||||
bool is_trivial_list() const
|
||||
{
|
||||
return (size() < 2);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the head node.
|
||||
//*************************************************************************
|
||||
node_t& get_head()
|
||||
{
|
||||
return *terminal_node.next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the head node.
|
||||
//*************************************************************************
|
||||
const node_t& get_head() const
|
||||
{
|
||||
return *terminal_node.next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the tail node.
|
||||
//*************************************************************************
|
||||
node_t& get_tail()
|
||||
{
|
||||
return *terminal_node.previous;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the tail node.
|
||||
//*************************************************************************
|
||||
const node_t& get_tail() const
|
||||
{
|
||||
return *terminal_node.previous;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Insert a node before 'position'.
|
||||
//*************************************************************************
|
||||
void insert_node(node_t& position, node_t& node)
|
||||
{
|
||||
// Connect to the list.
|
||||
join(*position.previous, node);
|
||||
join(node, position);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Join two nodes.
|
||||
//*************************************************************************
|
||||
void join(node_t& left, node_t& right)
|
||||
{
|
||||
left.next = &right;
|
||||
right.previous = &left;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
list_base(etl::ipool& node_pool,
|
||||
size_type max_size)
|
||||
: p_node_pool(&node_pool),
|
||||
MAX_SIZE(max_size)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
etl::ipool* p_node_pool; ///< The pool of data nodes used in the list.
|
||||
node_t terminal_node; ///< The node that acts as the list start and end.
|
||||
const size_type MAX_SIZE; ///< The maximum size of the list.
|
||||
etl::debug_count construct_count; ///< Internal debugging.
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,434 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove, rlindeman
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#if !defined(__ETL_IN_IMAP_H__)
|
||||
#error This header is a private element of etl::map & etl::imap
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_MAP_BASE__
|
||||
#define __ETL_MAP_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "8"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class map_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
map_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class map_full : public map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
map_full(string_type file_name, numeric_type line_number)
|
||||
: map_exception("map:full", file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Map out of bounds exception.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class map_out_of_bounds : public map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
map_out_of_bounds(string_type file_name, numeric_type line_number)
|
||||
: map_exception("map:bounds", file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class map_iterator : public map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
map_iterator(string_type file_name, numeric_type line_number)
|
||||
: map_exception("map:iterator", file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base class for all maps.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class map_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type; ///< The type used for determining the size of map.
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the map.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the maximum possible size of the map.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the map is empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return current_size == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the map is full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return current_size == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the vector.
|
||||
///\return The capacity of the vector.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
enum
|
||||
{
|
||||
kLeft = 0,
|
||||
kRight = 1,
|
||||
kNeither = 2
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The node element in the map.
|
||||
//*************************************************************************
|
||||
struct Node
|
||||
{
|
||||
//***********************************************************************
|
||||
/// Constructor
|
||||
//***********************************************************************
|
||||
Node() :
|
||||
weight(uint_least8_t(kNeither)),
|
||||
dir(uint_least8_t(kNeither))
|
||||
{
|
||||
}
|
||||
|
||||
~Node()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Marks the node as a leaf.
|
||||
//***********************************************************************
|
||||
void mark_as_leaf()
|
||||
{
|
||||
weight = uint_least8_t(kNeither);
|
||||
dir = uint_least8_t(kNeither);
|
||||
children[0] = nullptr;
|
||||
children[1] = nullptr;
|
||||
}
|
||||
|
||||
Node* children[2];
|
||||
uint_least8_t weight;
|
||||
uint_least8_t dir;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
map_base(size_type max_size)
|
||||
: current_size(0)
|
||||
, MAX_SIZE(max_size)
|
||||
, root_node(nullptr)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Balance the critical node at the position provided as needed
|
||||
//*************************************************************************
|
||||
void balance_node(Node*& critical_node)
|
||||
{
|
||||
// Step 1: Update weights for all children of the critical node up to the
|
||||
// newly inserted node. This step is costly (in terms of traversing nodes
|
||||
// multiple times during insertion) but doesn't require as much recursion
|
||||
Node* weight_node = critical_node->children[critical_node->dir];
|
||||
while (weight_node)
|
||||
{
|
||||
// Keep going until we reach a terminal node (dir == kNeither)
|
||||
if (uint_least8_t(kNeither) != weight_node->dir)
|
||||
{
|
||||
// Does this insert balance the previous weight factor value?
|
||||
if (weight_node->weight == 1 - weight_node->dir)
|
||||
{
|
||||
weight_node->weight = uint_least8_t(kNeither);
|
||||
}
|
||||
else
|
||||
{
|
||||
weight_node->weight = weight_node->dir;
|
||||
}
|
||||
|
||||
// Update weight factor node to point to next node
|
||||
weight_node = weight_node->children[weight_node->dir];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stop loop, terminal node found
|
||||
break;
|
||||
}
|
||||
} // while(weight_node)
|
||||
|
||||
// Step 2: Update weight for critical_node or rotate tree to balance node
|
||||
if (uint_least8_t(kNeither) == critical_node->weight)
|
||||
{
|
||||
critical_node->weight = critical_node->dir;
|
||||
}
|
||||
// If direction is different than weight, then it will now be balanced
|
||||
else if (critical_node->dir != critical_node->weight)
|
||||
{
|
||||
critical_node->weight = uint_least8_t(kNeither);
|
||||
}
|
||||
// Rotate is required to balance the tree at the critical node
|
||||
else
|
||||
{
|
||||
// If critical node matches child node direction then perform a two
|
||||
// node rotate in the direction of the critical node
|
||||
if (critical_node->weight == critical_node->children[critical_node->dir]->dir)
|
||||
{
|
||||
rotate_2node(critical_node, critical_node->dir);
|
||||
}
|
||||
// Otherwise perform a three node rotation in the direction of the
|
||||
// critical node
|
||||
else
|
||||
{
|
||||
rotate_3node(critical_node, critical_node->dir,
|
||||
critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Rotate two nodes at the position provided the to balance the tree
|
||||
//*************************************************************************
|
||||
void rotate_2node(Node*& position, uint_least8_t dir)
|
||||
{
|
||||
// A C A B
|
||||
// B C -> A E OR B C -> D A
|
||||
// D E B D D E E C
|
||||
// C (new position) becomes the root
|
||||
// A (position) takes ownership of D as its children[kRight] child
|
||||
// C (new position) takes ownership of A as its left child
|
||||
// OR
|
||||
// B (new position) becomes the root
|
||||
// A (position) takes ownership of E as its left child
|
||||
// B (new position) takes ownership of A as its right child
|
||||
|
||||
// Capture new root
|
||||
Node* new_root = position->children[dir];
|
||||
// Replace position's previous child with new root's other child
|
||||
position->children[dir] = new_root->children[1 - dir];
|
||||
// New root now becomes parent of current position
|
||||
new_root->children[1 - dir] = position;
|
||||
// Clear weight factor from current position
|
||||
position->weight = uint_least8_t(kNeither);
|
||||
// Newly detached right now becomes current position
|
||||
position = new_root;
|
||||
// Clear weight factor from new root
|
||||
position->weight = uint_least8_t(kNeither);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Rotate three nodes at the position provided the to balance the tree
|
||||
//*************************************************************************
|
||||
void rotate_3node(Node*& position, uint_least8_t dir, uint_least8_t third)
|
||||
{
|
||||
// __A__ __E__ __A__ __D__
|
||||
// _B_ C -> B A OR B _C_ -> A C
|
||||
// D E D F G C D E B F G E
|
||||
// F G F G
|
||||
// E (new position) becomes the root
|
||||
// B (position) takes ownership of F as its left child
|
||||
// A takes ownership of G as its right child
|
||||
// OR
|
||||
// D (new position) becomes the root
|
||||
// A (position) takes ownership of F as its right child
|
||||
// C takes ownership of G as its left child
|
||||
|
||||
// Capture new root (either E or D depending on dir)
|
||||
Node* new_root = position->children[dir]->children[1 - dir];
|
||||
// Set weight factor for B or C based on F or G existing and being a different than dir
|
||||
position->children[dir]->weight = third != uint_least8_t(kNeither) && third != dir ? dir : uint_least8_t(kNeither);
|
||||
|
||||
// Detach new root from its tree (replace with new roots child)
|
||||
position->children[dir]->children[1 - dir] =
|
||||
new_root->children[dir];
|
||||
// Attach current left tree to new root
|
||||
new_root->children[dir] = position->children[dir];
|
||||
// Set weight factor for A based on F or G
|
||||
position->weight = third != uint_least8_t(kNeither) && third == dir ? 1 - dir : uint_least8_t(kNeither);
|
||||
|
||||
// Move new root's right tree to current roots left tree
|
||||
position->children[dir] = new_root->children[1 - dir];
|
||||
// Attach current root to new roots right tree
|
||||
new_root->children[1 - dir] = position;
|
||||
// Replace current position with new root
|
||||
position = new_root;
|
||||
// Clear weight factor for new current position
|
||||
position->weight = uint_least8_t(kNeither);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
Node* find_limit_node(Node* position, const int8_t dir) const
|
||||
{
|
||||
// Something at this position and in the direction specified? keep going
|
||||
Node* limit_node = position;
|
||||
while (limit_node && limit_node->children[dir])
|
||||
{
|
||||
limit_node = limit_node->children[dir];
|
||||
}
|
||||
|
||||
// Return the limit node position found
|
||||
return limit_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
const Node* find_limit_node(const Node* position, const int8_t dir) const
|
||||
{
|
||||
// Something at this position and in the direction specified? keep going
|
||||
const Node* limit_node = position;
|
||||
while (limit_node && limit_node->children[dir])
|
||||
{
|
||||
limit_node = limit_node->children[dir];
|
||||
}
|
||||
|
||||
// Return the limit node position found
|
||||
return limit_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Attach the provided node to the position provided
|
||||
//*************************************************************************
|
||||
void attach_node(Node*& position, Node& node)
|
||||
{
|
||||
// Mark new node as leaf on attach to tree at position provided
|
||||
node.mark_as_leaf();
|
||||
|
||||
// Add the node here
|
||||
position = &node;
|
||||
|
||||
// One more.
|
||||
++current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Detach the node at the position provided
|
||||
//*************************************************************************
|
||||
void detach_node(Node*& position, Node*& replacement)
|
||||
{
|
||||
// Make temporary copy of actual nodes involved because we might lose
|
||||
// their references in the process (e.g. position is the same as
|
||||
// replacement or replacement is a child of position)
|
||||
Node* detached = position;
|
||||
Node* swap = replacement;
|
||||
|
||||
// Update current position to point to swap (replacement) node first
|
||||
position = swap;
|
||||
|
||||
// Update replacement node to point to child in opposite direction
|
||||
// otherwise we might lose the other child of the swap node
|
||||
replacement = swap->children[1 - swap->dir];
|
||||
|
||||
// Point swap node to detached node's children and weight
|
||||
swap->children[kLeft] = detached->children[kLeft];
|
||||
swap->children[kRight] = detached->children[kRight];
|
||||
swap->weight = detached->weight;
|
||||
}
|
||||
|
||||
size_type current_size; ///< The number of the used nodes.
|
||||
const size_type MAX_SIZE; ///< The maximum size of the map.
|
||||
Node* root_node; ///< The node that acts as the map root.
|
||||
etl::debug_count construct_count;
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,588 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove, rlindeman
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#if !defined(__ETL_IN_IMULTIMAP_H__)
|
||||
#error This header is a private element of etl::multimap & etl::imultimap
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_MULTIMAP_BASE__
|
||||
#define __ETL_MULTIMAP_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "9"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class multimap_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
multimap_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class multimap_full : public multimap_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multimap_full(string_type file_name, numeric_type line_number)
|
||||
: multimap_exception("multimap:full", file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Map out of bounds exception.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class multimap_out_of_bounds : public multimap_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multimap_out_of_bounds(string_type file_name, numeric_type line_number)
|
||||
: multimap_exception("multimap:bounds", file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class multimap_iterator : public multimap_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multimap_iterator(string_type file_name, numeric_type line_number)
|
||||
: multimap_exception("multimap:iterator", file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base class for all maps.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class multimap_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type; ///< The type used for determining the size of map.
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the map.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the maximum possible size of the map.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the map is empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return current_size == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the map is full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return current_size == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the vector.
|
||||
///\return The capacity of the vector.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
static const uint_least8_t kLeft = 0;
|
||||
static const uint_least8_t kRight = 1;
|
||||
static const uint_least8_t kNeither = 2;
|
||||
|
||||
//*************************************************************************
|
||||
/// The node element in the multimap.
|
||||
//*************************************************************************
|
||||
struct Node
|
||||
{
|
||||
//***********************************************************************
|
||||
/// Constructor
|
||||
//***********************************************************************
|
||||
Node() :
|
||||
weight(kNeither),
|
||||
dir(kNeither)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Marks the node as a leaf.
|
||||
//***********************************************************************
|
||||
void mark_as_leaf()
|
||||
{
|
||||
weight = kNeither;
|
||||
dir = kNeither;
|
||||
parent = nullptr;
|
||||
children[0] = nullptr;
|
||||
children[1] = nullptr;
|
||||
}
|
||||
|
||||
Node* parent;
|
||||
Node* children[2];
|
||||
uint_least8_t weight;
|
||||
uint_least8_t dir;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
multimap_base(size_type max_size)
|
||||
: current_size(0)
|
||||
, MAX_SIZE(max_size)
|
||||
, root_node(nullptr)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Balance the critical node at the position provided as needed
|
||||
//*************************************************************************
|
||||
void balance_node(Node*& critical_node)
|
||||
{
|
||||
// Step 1: Update weights for all children of the critical node up to the
|
||||
// newly inserted node. This step is costly (in terms of traversing nodes
|
||||
// multiple times during insertion) but doesn't require as much recursion
|
||||
Node* weight_node = critical_node->children[critical_node->dir];
|
||||
while (weight_node)
|
||||
{
|
||||
// Keep going until we reach a terminal node (dir == kNeither)
|
||||
if (kNeither != weight_node->dir)
|
||||
{
|
||||
// Does this insert balance the previous weight factor value?
|
||||
if (weight_node->weight == 1 - weight_node->dir)
|
||||
{
|
||||
weight_node->weight = kNeither;
|
||||
}
|
||||
else
|
||||
{
|
||||
weight_node->weight = weight_node->dir;
|
||||
}
|
||||
|
||||
// Update weight factor node to point to next node
|
||||
weight_node = weight_node->children[weight_node->dir];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stop loop, terminal node found
|
||||
break;
|
||||
}
|
||||
} // while(weight_node)
|
||||
|
||||
// Step 2: Update weight for critical_node or rotate tree to balance node
|
||||
if (kNeither == critical_node->weight)
|
||||
{
|
||||
critical_node->weight = critical_node->dir;
|
||||
}
|
||||
// If direction is different than weight, then it will now be balanced
|
||||
else if (critical_node->dir != critical_node->weight)
|
||||
{
|
||||
critical_node->weight = kNeither;
|
||||
}
|
||||
// Rotate is required to balance the tree at the critical node
|
||||
else
|
||||
{
|
||||
// If critical node matches child node direction then perform a two
|
||||
// node rotate in the direction of the critical node
|
||||
if (critical_node->weight == critical_node->children[critical_node->dir]->dir)
|
||||
{
|
||||
rotate_2node(critical_node, critical_node->dir);
|
||||
}
|
||||
// Otherwise perform a three node rotation in the direction of the
|
||||
// critical node
|
||||
else
|
||||
{
|
||||
rotate_3node(critical_node, critical_node->dir,
|
||||
critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Rotate two nodes at the position provided the to balance the tree
|
||||
//*************************************************************************
|
||||
void rotate_2node(Node*& position, uint_least8_t dir)
|
||||
{
|
||||
// A C A B
|
||||
// B C -> A E OR B C -> D A
|
||||
// D E B D D E E C
|
||||
// C (new position) becomes the root
|
||||
// A (position) takes ownership of D as its children[kRight] child
|
||||
// C (new position) takes ownership of A as its left child
|
||||
// OR
|
||||
// B (new position) becomes the root
|
||||
// A (position) takes ownership of E as its left child
|
||||
// B (new position) takes ownership of A as its right child
|
||||
|
||||
// Capture new root (either B or C depending on dir) and its parent
|
||||
Node* new_root = position->children[dir];
|
||||
|
||||
// Replace position's previous child with new root's other child
|
||||
position->children[dir] = new_root->children[1 - dir];
|
||||
// Update new root's other child parent pointer
|
||||
if (position->children[dir])
|
||||
{
|
||||
position->children[dir]->parent = position;
|
||||
}
|
||||
|
||||
// New root's parent becomes current position's parent
|
||||
new_root->parent = position->parent;
|
||||
new_root->children[1 - dir] = position;
|
||||
new_root->dir = 1 - dir;
|
||||
|
||||
// Clear weight factor from current position
|
||||
position->weight = kNeither;
|
||||
// Position's parent becomes new_root
|
||||
position->parent = new_root;
|
||||
position = new_root;
|
||||
// Clear weight factor from new root
|
||||
position->weight = kNeither;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Rotate three nodes at the position provided the to balance the tree
|
||||
//*************************************************************************
|
||||
void rotate_3node(Node*& position, uint_least8_t dir, uint_least8_t third)
|
||||
{
|
||||
// __A__ __E__ __A__ __D__
|
||||
// _B_ C -> B A OR B _C_ -> A C
|
||||
// D E D F G C D E B F G E
|
||||
// F G F G
|
||||
// E (new position) becomes the root
|
||||
// B (position) takes ownership of F as its left child
|
||||
// A takes ownership of G as its right child
|
||||
// OR
|
||||
// D (new position) becomes the root
|
||||
// A (position) takes ownership of F as its right child
|
||||
// C takes ownership of G as its left child
|
||||
|
||||
// Capture new root (either E or D depending on dir)
|
||||
Node* new_root = position->children[dir]->children[1 - dir];
|
||||
// Set weight factor for B or C based on F or G existing and being a different than dir
|
||||
position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither;
|
||||
|
||||
// Detach new root from its tree (replace with new roots child)
|
||||
position->children[dir]->children[1 - dir] = new_root->children[dir];
|
||||
// Update new roots child parent pointer
|
||||
if (new_root->children[dir])
|
||||
{
|
||||
new_root->children[dir]->parent = position->children[dir];
|
||||
}
|
||||
|
||||
// Attach current left tree to new root and update its parent
|
||||
new_root->children[dir] = position->children[dir];
|
||||
position->children[dir]->parent = new_root;
|
||||
|
||||
// Set weight factor for A based on F or G
|
||||
position->weight = third != kNeither && third == dir ? 1 - dir : kNeither;
|
||||
|
||||
// Move new root's right tree to current roots left tree
|
||||
position->children[dir] = new_root->children[1 - dir];
|
||||
if (new_root->children[1 - dir])
|
||||
{
|
||||
new_root->children[1 - dir]->parent = position;
|
||||
}
|
||||
|
||||
// Attach current root to new roots right tree and assume its parent
|
||||
new_root->parent = position->parent;
|
||||
new_root->children[1 - dir] = position;
|
||||
new_root->dir = 1 - dir;
|
||||
|
||||
// Update current position's parent and replace with new root
|
||||
position->parent = new_root;
|
||||
position = new_root;
|
||||
// Clear weight factor for new current position
|
||||
position->weight = kNeither;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the next node in sequence from the node provided
|
||||
//*************************************************************************
|
||||
void next_node(Node*& position) const
|
||||
{
|
||||
if (position)
|
||||
{
|
||||
// Is there a tree on the right? then find the minimum of that tree
|
||||
if (position->children[kRight])
|
||||
{
|
||||
// Return minimum node found
|
||||
position = find_limit_node(position->children[kRight], kLeft);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
{
|
||||
// Start with current position as parent
|
||||
Node* parent = position;
|
||||
do {
|
||||
// Update current position as previous parent
|
||||
position = parent;
|
||||
// Find parent of current position
|
||||
parent = position->parent; // find_parent_node(root_node, position);
|
||||
// Repeat while previous position was on right side of parent tree
|
||||
} while (parent && parent->children[kRight] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the next node in sequence from the node provided
|
||||
//*************************************************************************
|
||||
void next_node(const Node*& position) const
|
||||
{
|
||||
if (position)
|
||||
{
|
||||
// Is there a tree on the right? then find the minimum of that tree
|
||||
if (position->children[kRight])
|
||||
{
|
||||
// Return minimum node found
|
||||
position = find_limit_node(position->children[kRight], kLeft);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
{
|
||||
// Start with current position as parent
|
||||
const Node* parent = position;
|
||||
do {
|
||||
// Update current position as previous parent
|
||||
position = parent;
|
||||
// Find parent of current position
|
||||
parent = position->parent;
|
||||
// Repeat while previous position was on right side of parent tree
|
||||
} while (parent && parent->children[kRight] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the previous node in sequence from the node provided
|
||||
//*************************************************************************
|
||||
void prev_node(Node*& position) const
|
||||
{
|
||||
// If starting at the terminal end, the previous node is the maximum node
|
||||
// from the root
|
||||
if (!position)
|
||||
{
|
||||
position = find_limit_node(root_node, kRight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is there a tree on the left? then find the maximum of that tree
|
||||
if (position->children[kLeft])
|
||||
{
|
||||
// Return maximum node found
|
||||
position = find_limit_node(position->children[kLeft], kRight);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
{
|
||||
// Start with current position as parent
|
||||
Node* parent = position;
|
||||
do {
|
||||
// Update current position as previous parent
|
||||
position = parent;
|
||||
// Find parent of current position
|
||||
parent = position->parent;
|
||||
// Repeat while previous position was on left side of parent tree
|
||||
} while (parent && parent->children[kLeft] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the previous node in sequence from the node provided
|
||||
//*************************************************************************
|
||||
void prev_node(const Node*& position) const
|
||||
{
|
||||
// If starting at the terminal end, the previous node is the maximum node
|
||||
// from the root
|
||||
if (!position)
|
||||
{
|
||||
position = find_limit_node(root_node, kRight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is there a tree on the left? then find the maximum of that tree
|
||||
if (position->children[kLeft])
|
||||
{
|
||||
// Return maximum node found
|
||||
position = find_limit_node(position->children[kLeft], kRight);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
{
|
||||
// Start with current position as parent
|
||||
const Node* parent = position;
|
||||
do {
|
||||
// Update current position as previous parent
|
||||
position = parent;
|
||||
// Find parent of current position
|
||||
parent = position->parent;
|
||||
// Repeat while previous position was on left side of parent tree
|
||||
} while (parent && parent->children[kLeft] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
Node* find_limit_node(Node* position, const int8_t dir) const
|
||||
{
|
||||
// Something at this position and in the direction specified? keep going
|
||||
Node* limit_node = position;
|
||||
while (limit_node && limit_node->children[dir])
|
||||
{
|
||||
limit_node = limit_node->children[dir];
|
||||
}
|
||||
|
||||
// Return the limit node position found
|
||||
return limit_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Attach the provided node to the position provided
|
||||
//*************************************************************************
|
||||
void attach_node(Node* parent, Node*& position, Node& node)
|
||||
{
|
||||
// Mark new node as leaf on attach to tree at position provided
|
||||
node.mark_as_leaf();
|
||||
|
||||
// Keep track of this node's parent
|
||||
node.parent = parent;
|
||||
|
||||
// Add the node here
|
||||
position = &node;
|
||||
|
||||
// One more.
|
||||
++current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Detach the node at the position provided
|
||||
//*************************************************************************
|
||||
void detach_node(Node*& position, Node*& replacement)
|
||||
{
|
||||
// Make temporary copy of actual nodes involved because we might lose
|
||||
// their references in the process (e.g. position is the same as
|
||||
// replacement or replacement is a child of position)
|
||||
Node* detached = position;
|
||||
Node* swap = replacement;
|
||||
|
||||
// Update current position to point to swap (replacement) node first
|
||||
position = swap;
|
||||
|
||||
// Update replacement node to point to child in opposite direction
|
||||
// otherwise we might lose the other child of the swap node
|
||||
replacement = swap->children[1 - swap->dir];
|
||||
|
||||
// Point swap node to detached node's parent, children and weight
|
||||
swap->parent = detached->parent;
|
||||
swap->children[kLeft] = detached->children[kLeft];
|
||||
swap->children[kRight] = detached->children[kRight];
|
||||
if (swap->children[kLeft])
|
||||
{
|
||||
swap->children[kLeft]->parent = swap;
|
||||
}
|
||||
if (swap->children[kRight])
|
||||
{
|
||||
swap->children[kRight]->parent = swap;
|
||||
}
|
||||
swap->weight = detached->weight;
|
||||
}
|
||||
|
||||
size_type current_size; ///< The number of the used nodes.
|
||||
const size_type MAX_SIZE; ///< The maximum size of the map.
|
||||
Node* root_node; ///< The node that acts as the multimap root.
|
||||
etl::debug_count construct_count;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,589 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove, rlindeman
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#if !defined(__ETL_IN_IMULTISET_H__)
|
||||
#error This header is a private element of etl::multiset & etl::imultiset
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_MULTISET_BASE__
|
||||
#define __ETL_MULTISET_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "10"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class multiset_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
multiset_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class multiset_full : public multiset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multiset_full(string_type file_name, numeric_type line_number)
|
||||
: multiset_exception(ETL_ERROR_TEXT("multiset:full", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Map out of bounds exception.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class multiset_out_of_bounds : public multiset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multiset_out_of_bounds(string_type file_name, numeric_type line_number)
|
||||
: multiset_exception(ETL_ERROR_TEXT("multiset:bounds", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class multiset_iterator : public multiset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multiset_iterator(string_type file_name, numeric_type line_number)
|
||||
: multiset_exception(ETL_ERROR_TEXT("multiset:iterator", ETL_FILE"C"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base class for all sets.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class multiset_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type; ///< The type used for determining the size of set.
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the set.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the maximum possible size of the set.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the set is empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return current_size == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the set is full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return current_size == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the vector.
|
||||
///\return The capacity of the vector.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
static const uint_least8_t kLeft = 0;
|
||||
static const uint_least8_t kRight = 1;
|
||||
static const uint_least8_t kNeither = 2;
|
||||
|
||||
//*************************************************************************
|
||||
/// The node element in the multiset.
|
||||
//*************************************************************************
|
||||
struct Node
|
||||
{
|
||||
//***********************************************************************
|
||||
/// Constructor
|
||||
//***********************************************************************
|
||||
Node() :
|
||||
weight(kNeither),
|
||||
dir(kNeither)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Marks the node as a leaf.
|
||||
//***********************************************************************
|
||||
void mark_as_leaf()
|
||||
{
|
||||
weight = kNeither;
|
||||
dir = kNeither;
|
||||
parent = nullptr;
|
||||
children[0] = nullptr;
|
||||
children[1] = nullptr;
|
||||
}
|
||||
|
||||
Node* parent;
|
||||
Node* children[2];
|
||||
uint_least8_t weight;
|
||||
uint_least8_t dir;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
multiset_base(size_type max_size)
|
||||
: current_size(0)
|
||||
, MAX_SIZE(max_size)
|
||||
, root_node(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Attach the provided node to the position provided
|
||||
//*************************************************************************
|
||||
void attach_node(Node* parent, Node*& position, Node& node)
|
||||
{
|
||||
// Mark new node as leaf on attach to tree at position provided
|
||||
node.mark_as_leaf();
|
||||
|
||||
// Keep track of this node's parent
|
||||
node.parent = parent;
|
||||
|
||||
// Add the node here
|
||||
position = &node;
|
||||
|
||||
// One more.
|
||||
++current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Detach the node at the position provided
|
||||
//*************************************************************************
|
||||
void detach_node(Node*& position, Node*& replacement)
|
||||
{
|
||||
// Make temporary copy of actual nodes involved because we might lose
|
||||
// their references in the process (e.g. position is the same as
|
||||
// replacement or replacement is a child of position)
|
||||
Node* detached = position;
|
||||
Node* swap = replacement;
|
||||
|
||||
// Update current position to point to swap (replacement) node first
|
||||
position = swap;
|
||||
|
||||
// Update replacement node to point to child in opposite direction
|
||||
// otherwise we might lose the other child of the swap node
|
||||
replacement = swap->children[1 - swap->dir];
|
||||
|
||||
// Point swap node to detached node's parent, children and weight
|
||||
swap->parent = detached->parent;
|
||||
swap->children[kLeft] = detached->children[kLeft];
|
||||
swap->children[kRight] = detached->children[kRight];
|
||||
if (swap->children[kLeft])
|
||||
{
|
||||
swap->children[kLeft]->parent = swap;
|
||||
}
|
||||
if (swap->children[kRight])
|
||||
{
|
||||
swap->children[kRight]->parent = swap;
|
||||
}
|
||||
swap->weight = detached->weight;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Balance the critical node at the position provided as needed
|
||||
//*************************************************************************
|
||||
void balance_node(Node*& critical_node)
|
||||
{
|
||||
// Step 1: Update weights for all children of the critical node up to the
|
||||
// newly inserted node. This step is costly (in terms of traversing nodes
|
||||
// multiple times during insertion) but doesn't require as much recursion
|
||||
Node* weight_node = critical_node->children[critical_node->dir];
|
||||
while (weight_node)
|
||||
{
|
||||
// Keep going until we reach a terminal node (dir == kNeither)
|
||||
if (kNeither != weight_node->dir)
|
||||
{
|
||||
// Does this insert balance the previous weight factor value?
|
||||
if (weight_node->weight == 1 - weight_node->dir)
|
||||
{
|
||||
weight_node->weight = kNeither;
|
||||
}
|
||||
else
|
||||
{
|
||||
weight_node->weight = weight_node->dir;
|
||||
}
|
||||
|
||||
// Update weight factor node to point to next node
|
||||
weight_node = weight_node->children[weight_node->dir];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stop loop, terminal node found
|
||||
break;
|
||||
}
|
||||
} // while(weight_node)
|
||||
|
||||
// Step 2: Update weight for critical_node or rotate tree to balance node
|
||||
if (kNeither == critical_node->weight)
|
||||
{
|
||||
critical_node->weight = critical_node->dir;
|
||||
}
|
||||
// If direction is different than weight, then it will now be balanced
|
||||
else if (critical_node->dir != critical_node->weight)
|
||||
{
|
||||
critical_node->weight = kNeither;
|
||||
}
|
||||
// Rotate is required to balance the tree at the critical node
|
||||
else
|
||||
{
|
||||
// If critical node matches child node direction then perform a two
|
||||
// node rotate in the direction of the critical node
|
||||
if (critical_node->weight == critical_node->children[critical_node->dir]->dir)
|
||||
{
|
||||
rotate_2node(critical_node, critical_node->dir);
|
||||
}
|
||||
// Otherwise perform a three node rotation in the direction of the
|
||||
// critical node
|
||||
else
|
||||
{
|
||||
rotate_3node(critical_node, critical_node->dir,
|
||||
critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
Node* find_limit_node(Node* position, const int8_t dir) const
|
||||
{
|
||||
// Something at this position and in the direction specified? keep going
|
||||
Node* limit_node = position;
|
||||
while (limit_node && limit_node->children[dir])
|
||||
{
|
||||
limit_node = limit_node->children[dir];
|
||||
}
|
||||
|
||||
// Return the limit node position found
|
||||
return limit_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the next node in sequence from the node provided
|
||||
//*************************************************************************
|
||||
void next_node(Node*& position) const
|
||||
{
|
||||
if (position)
|
||||
{
|
||||
// Is there a tree on the right? then find the minimum of that tree
|
||||
if (position->children[kRight])
|
||||
{
|
||||
// Return minimum node found
|
||||
position = find_limit_node(position->children[kRight], kLeft);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
{
|
||||
// Start with current position as parent
|
||||
Node* parent = position;
|
||||
do {
|
||||
// Update current position as previous parent
|
||||
position = parent;
|
||||
// Find parent of current position
|
||||
parent = position->parent; // find_parent_node(root_node, position);
|
||||
// Repeat while previous position was on right side of parent tree
|
||||
} while (parent && parent->children[kRight] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the next node in sequence from the node provided
|
||||
//*************************************************************************
|
||||
void next_node(const Node*& position) const
|
||||
{
|
||||
if (position)
|
||||
{
|
||||
// Is there a tree on the right? then find the minimum of that tree
|
||||
if (position->children[kRight])
|
||||
{
|
||||
// Return minimum node found
|
||||
position = find_limit_node(position->children[kRight], kLeft);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
{
|
||||
// Start with current position as parent
|
||||
const Node* parent = position;
|
||||
do {
|
||||
// Update current position as previous parent
|
||||
position = parent;
|
||||
// Find parent of current position
|
||||
parent = position->parent;
|
||||
// Repeat while previous position was on right side of parent tree
|
||||
} while (parent && parent->children[kRight] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the previous node in sequence from the node provided
|
||||
//*************************************************************************
|
||||
void prev_node(Node*& position) const
|
||||
{
|
||||
// If starting at the terminal end, the previous node is the maximum node
|
||||
// from the root
|
||||
if (!position)
|
||||
{
|
||||
position = find_limit_node(root_node, kRight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is there a tree on the left? then find the maximum of that tree
|
||||
if (position->children[kLeft])
|
||||
{
|
||||
// Return maximum node found
|
||||
position = find_limit_node(position->children[kLeft], kRight);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
{
|
||||
// Start with current position as parent
|
||||
Node* parent = position;
|
||||
do {
|
||||
// Update current position as previous parent
|
||||
position = parent;
|
||||
// Find parent of current position
|
||||
parent = position->parent;
|
||||
// Repeat while previous position was on left side of parent tree
|
||||
} while (parent && parent->children[kLeft] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the previous node in sequence from the node provided
|
||||
//*************************************************************************
|
||||
void prev_node(const Node*& position) const
|
||||
{
|
||||
// If starting at the terminal end, the previous node is the maximum node
|
||||
// from the root
|
||||
if (!position)
|
||||
{
|
||||
position = find_limit_node(root_node, kRight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Is there a tree on the left? then find the maximum of that tree
|
||||
if (position->children[kLeft])
|
||||
{
|
||||
// Return maximum node found
|
||||
position = find_limit_node(position->children[kLeft], kRight);
|
||||
}
|
||||
// Otherwise find the parent of this node
|
||||
else
|
||||
{
|
||||
// Start with current position as parent
|
||||
const Node* parent = position;
|
||||
do {
|
||||
// Update current position as previous parent
|
||||
position = parent;
|
||||
// Find parent of current position
|
||||
parent = position->parent;
|
||||
// Repeat while previous position was on left side of parent tree
|
||||
} while (parent && parent->children[kLeft] == position);
|
||||
|
||||
// Set parent node as the next position
|
||||
position = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Rotate two nodes at the position provided the to balance the tree
|
||||
//*************************************************************************
|
||||
void rotate_2node(Node*& position, uint_least8_t dir)
|
||||
{
|
||||
// A C A B
|
||||
// B C -> A E OR B C -> D A
|
||||
// D E B D D E E C
|
||||
// C (new position) becomes the root
|
||||
// A (position) takes ownership of D as its children[kRight] child
|
||||
// C (new position) takes ownership of A as its left child
|
||||
// OR
|
||||
// B (new position) becomes the root
|
||||
// A (position) takes ownership of E as its left child
|
||||
// B (new position) takes ownership of A as its right child
|
||||
|
||||
// Capture new root (either B or C depending on dir) and its parent
|
||||
Node* new_root = position->children[dir];
|
||||
|
||||
// Replace position's previous child with new root's other child
|
||||
position->children[dir] = new_root->children[1 - dir];
|
||||
// Update new root's other child parent pointer
|
||||
if (position->children[dir])
|
||||
{
|
||||
position->children[dir]->parent = position;
|
||||
}
|
||||
|
||||
// New root's parent becomes current position's parent
|
||||
new_root->parent = position->parent;
|
||||
new_root->children[1 - dir] = position;
|
||||
new_root->dir = 1 - dir;
|
||||
|
||||
// Clear weight factor from current position
|
||||
position->weight = kNeither;
|
||||
// Position's parent becomes new_root
|
||||
position->parent = new_root;
|
||||
position = new_root;
|
||||
// Clear weight factor from new root
|
||||
position->weight = kNeither;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Rotate three nodes at the position provided the to balance the tree
|
||||
//*************************************************************************
|
||||
void rotate_3node(Node*& position, uint_least8_t dir, uint_least8_t third)
|
||||
{
|
||||
// __A__ __E__ __A__ __D__
|
||||
// _B_ C -> B A OR B _C_ -> A C
|
||||
// D E D F G C D E B F G E
|
||||
// F G F G
|
||||
// E (new position) becomes the root
|
||||
// B (position) takes ownership of F as its left child
|
||||
// A takes ownership of G as its right child
|
||||
// OR
|
||||
// D (new position) becomes the root
|
||||
// A (position) takes ownership of F as its right child
|
||||
// C takes ownership of G as its left child
|
||||
|
||||
// Capture new root (either E or D depending on dir)
|
||||
Node* new_root = position->children[dir]->children[1 - dir];
|
||||
// Set weight factor for B or C based on F or G existing and being a different than dir
|
||||
position->children[dir]->weight = third != kNeither && third != dir ? dir : kNeither;
|
||||
|
||||
// Detach new root from its tree (replace with new roots child)
|
||||
position->children[dir]->children[1 - dir] = new_root->children[dir];
|
||||
// Update new roots child parent pointer
|
||||
if (new_root->children[dir])
|
||||
{
|
||||
new_root->children[dir]->parent = position->children[dir];
|
||||
}
|
||||
|
||||
// Attach current left tree to new root and update its parent
|
||||
new_root->children[dir] = position->children[dir];
|
||||
position->children[dir]->parent = new_root;
|
||||
|
||||
// Set weight factor for A based on F or G
|
||||
position->weight = third != kNeither && third == dir ? 1 - dir : kNeither;
|
||||
|
||||
// Move new root's right tree to current roots left tree
|
||||
position->children[dir] = new_root->children[1 - dir];
|
||||
if (new_root->children[1 - dir])
|
||||
{
|
||||
new_root->children[1 - dir]->parent = position;
|
||||
}
|
||||
|
||||
// Attach current root to new roots right tree and assume its parent
|
||||
new_root->parent = position->parent;
|
||||
new_root->children[1 - dir] = position;
|
||||
new_root->dir = 1 - dir;
|
||||
|
||||
// Update current position's parent and replace with new root
|
||||
position->parent = new_root;
|
||||
position = new_root;
|
||||
// Clear weight factor for new current position
|
||||
position->weight = kNeither;
|
||||
}
|
||||
|
||||
size_type current_size; ///< The number of the used nodes.
|
||||
const size_type MAX_SIZE; ///< The maximum size of the set.
|
||||
Node* root_node; ///< The node that acts as the multiset root.
|
||||
etl::debug_count construct_count;
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,167 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
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_IN_IQUEUE_H__
|
||||
#error This header is a private element of etl::queue & etl::iqueue
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_QUEUE_BASE__
|
||||
#define __ETL_QUEUE_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "13"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for queue exceptions.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class queue_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
queue_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the queue is full.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class queue_full : public queue_exception
|
||||
{
|
||||
public:
|
||||
|
||||
queue_full(string_type file_name, numeric_type line_number)
|
||||
: queue_exception(ETL_ERROR_TEXT("queue:full", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the queue is empty.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class queue_empty : public queue_exception
|
||||
{
|
||||
public:
|
||||
|
||||
queue_empty(string_type file_name, numeric_type line_number)
|
||||
: queue_exception(ETL_ERROR_TEXT("queue:empty", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base class for all queues.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class queue_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type; ///< The type used for determining the size of queue.
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the current number of items in the queue.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum number of items that can be queued.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the queue is empty.
|
||||
/// \return <b>true</b> if the queue is empty, otherwise <b>false</b>
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return current_size == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the queue is full.
|
||||
/// \return <b>true</b> if the queue is full, otherwise <b>false</b>
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return current_size == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
queue_base(size_type max_size)
|
||||
: in(0),
|
||||
out(0),
|
||||
current_size(0),
|
||||
MAX_SIZE(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
size_type in; ///< Where to input new data.
|
||||
size_type out; ///< Where to get the oldest data.
|
||||
size_type current_size; ///< The number of items in the queue.
|
||||
const size_type MAX_SIZE; ///< The maximum number of items in the queue.
|
||||
etl::debug_count construct_count; ///< For internal debugging purposes.
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,429 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2015 jwellbelove, rlindeman
|
||||
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
#if !defined(__ETL_IN_ISET_H__)
|
||||
#error This header is a private element of etl::set & etl::iset
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_SET_BASE__
|
||||
#define __ETL_SET_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#define ETL_FILE "14"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class set_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
set_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class set_full : public set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
set_full(string_type file_name, numeric_type line_number)
|
||||
: set_exception(ETL_ERROR_TEXT("set:full", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Map out of bounds exception.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class set_out_of_bounds : public set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
set_out_of_bounds(string_type file_name, numeric_type line_number)
|
||||
: set_exception(ETL_ERROR_TEXT("set:bounds", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class set_iterator : public set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
set_iterator(string_type file_name, numeric_type line_number)
|
||||
: set_exception(ETL_ERROR_TEXT("set:iterator problem", ETL_FILE"C"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base class for all sets.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class set_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type; ///< The type used for determining the size of set.
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the set.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the maximum possible size of the set.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the set is empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return current_size == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the set is full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return current_size == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the vector.
|
||||
///\return The capacity of the vector.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
enum
|
||||
{
|
||||
kLeft = 0,
|
||||
kRight = 1,
|
||||
kNeither = 2
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The node element in the set.
|
||||
//*************************************************************************
|
||||
struct Node
|
||||
{
|
||||
//***********************************************************************
|
||||
/// Constructor
|
||||
//***********************************************************************
|
||||
Node() :
|
||||
weight(kNeither),
|
||||
dir(kNeither)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Marks the node as a leaf.
|
||||
//***********************************************************************
|
||||
void mark_as_leaf()
|
||||
{
|
||||
weight = kNeither;
|
||||
dir = kNeither;
|
||||
children[0] = nullptr;
|
||||
children[1] = nullptr;
|
||||
}
|
||||
|
||||
Node* children[2];
|
||||
uint_least8_t weight;
|
||||
uint_least8_t dir;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
set_base(size_type max_size)
|
||||
: current_size(0)
|
||||
, MAX_SIZE(max_size)
|
||||
, root_node(nullptr)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Attach the provided node to the position provided
|
||||
//*************************************************************************
|
||||
void attach_node(Node*& position, Node& node)
|
||||
{
|
||||
// Mark new node as leaf on attach to tree at position provided
|
||||
node.mark_as_leaf();
|
||||
|
||||
// Add the node here
|
||||
position = &node;
|
||||
|
||||
// One more.
|
||||
++current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Detach the node at the position provided
|
||||
//*************************************************************************
|
||||
void detach_node(Node*& position, Node*& replacement)
|
||||
{
|
||||
// Make temporary copy of actual nodes involved because we might lose
|
||||
// their references in the process (e.g. position is the same as
|
||||
// replacement or replacement is a child of position)
|
||||
Node* detached = position;
|
||||
Node* swap = replacement;
|
||||
|
||||
// Update current position to point to swap (replacement) node first
|
||||
position = swap;
|
||||
|
||||
// Update replacement node to point to child in opposite direction
|
||||
// otherwise we might lose the other child of the swap node
|
||||
replacement = swap->children[1 - swap->dir];
|
||||
|
||||
// Point swap node to detached node's children and weight
|
||||
swap->children[kLeft] = detached->children[kLeft];
|
||||
swap->children[kRight] = detached->children[kRight];
|
||||
swap->weight = detached->weight;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Balance the critical node at the position provided as needed
|
||||
//*************************************************************************
|
||||
void balance_node(Node*& critical_node)
|
||||
{
|
||||
// Step 1: Update weights for all children of the critical node up to the
|
||||
// newly inserted node. This step is costly (in terms of traversing nodes
|
||||
// multiple times during insertion) but doesn't require as much recursion
|
||||
Node* weight_node = critical_node->children[critical_node->dir];
|
||||
while (weight_node)
|
||||
{
|
||||
// Keep going until we reach a terminal node (dir == kNeither)
|
||||
if (uint_least8_t(kNeither) != weight_node->dir)
|
||||
{
|
||||
// Does this insert balance the previous weight factor value?
|
||||
if (weight_node->weight == 1 - weight_node->dir)
|
||||
{
|
||||
weight_node->weight = uint_least8_t(kNeither);
|
||||
}
|
||||
else
|
||||
{
|
||||
weight_node->weight = weight_node->dir;
|
||||
}
|
||||
|
||||
// Update weight factor node to point to next node
|
||||
weight_node = weight_node->children[weight_node->dir];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stop loop, terminal node found
|
||||
break;
|
||||
}
|
||||
} // while(weight_node)
|
||||
|
||||
// Step 2: Update weight for critical_node or rotate tree to balance node
|
||||
if (uint_least8_t(kNeither) == critical_node->weight)
|
||||
{
|
||||
critical_node->weight = critical_node->dir;
|
||||
}
|
||||
// If direction is different than weight, then it will now be balanced
|
||||
else if (critical_node->dir != critical_node->weight)
|
||||
{
|
||||
critical_node->weight = uint_least8_t(kNeither);
|
||||
}
|
||||
// Rotate is required to balance the tree at the critical node
|
||||
else
|
||||
{
|
||||
// If critical node matches child node direction then perform a two
|
||||
// node rotate in the direction of the critical node
|
||||
if (critical_node->weight == critical_node->children[critical_node->dir]->dir)
|
||||
{
|
||||
rotate_2node(critical_node, critical_node->dir);
|
||||
}
|
||||
// Otherwise perform a three node rotation in the direction of the
|
||||
// critical node
|
||||
else
|
||||
{
|
||||
rotate_3node(critical_node, critical_node->dir,
|
||||
critical_node->children[critical_node->dir]->children[1 - critical_node->dir]->dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
Node* find_limit_node(Node* position, const int8_t dir) const
|
||||
{
|
||||
// Something at this position and in the direction specified? keep going
|
||||
Node* limit_node = position;
|
||||
while (limit_node && limit_node->children[dir])
|
||||
{
|
||||
limit_node = limit_node->children[dir];
|
||||
}
|
||||
|
||||
// Return the limit node position found
|
||||
return limit_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Find the node whose key would go before all the other keys from the
|
||||
/// position provided
|
||||
//*************************************************************************
|
||||
const Node* find_limit_node(const Node* position, const int8_t dir) const
|
||||
{
|
||||
// Something at this position and in the direction specified? keep going
|
||||
const Node* limit_node = position;
|
||||
while (limit_node && limit_node->children[dir])
|
||||
{
|
||||
limit_node = limit_node->children[dir];
|
||||
}
|
||||
|
||||
// Return the limit node position found
|
||||
return limit_node;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Rotate two nodes at the position provided the to balance the tree
|
||||
//*************************************************************************
|
||||
void rotate_2node(Node*& position, uint_least8_t dir)
|
||||
{
|
||||
// A C A B
|
||||
// B C -> A E OR B C -> D A
|
||||
// D E B D D E E C
|
||||
// C (new position) becomes the root
|
||||
// A (position) takes ownership of D as its children[kRight] child
|
||||
// C (new position) takes ownership of A as its left child
|
||||
// OR
|
||||
// B (new position) becomes the root
|
||||
// A (position) takes ownership of E as its left child
|
||||
// B (new position) takes ownership of A as its right child
|
||||
|
||||
// Capture new root
|
||||
Node* new_root = position->children[dir];
|
||||
// Replace position's previous child with new root's other child
|
||||
position->children[dir] = new_root->children[1 - dir];
|
||||
// New root now becomes parent of current position
|
||||
new_root->children[1 - dir] = position;
|
||||
// Clear weight factor from current position
|
||||
position->weight = uint_least8_t(kNeither);
|
||||
// Newly detached right now becomes current position
|
||||
position = new_root;
|
||||
// Clear weight factor from new root
|
||||
position->weight = uint_least8_t(kNeither);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Rotate three nodes at the position provided the to balance the tree
|
||||
//*************************************************************************
|
||||
void rotate_3node(Node*& position, uint_least8_t dir, uint_least8_t third)
|
||||
{
|
||||
// __A__ __E__ __A__ __D__
|
||||
// _B_ C -> B A OR B _C_ -> A C
|
||||
// D E D F G C D E B F G E
|
||||
// F G F G
|
||||
// E (new position) becomes the root
|
||||
// B (position) takes ownership of F as its left child
|
||||
// A takes ownership of G as its right child
|
||||
// OR
|
||||
// D (new position) becomes the root
|
||||
// A (position) takes ownership of F as its right child
|
||||
// C takes ownership of G as its left child
|
||||
|
||||
// Capture new root (either E or D depending on dir)
|
||||
Node* new_root = position->children[dir]->children[1 - dir];
|
||||
// Set weight factor for B or C based on F or G existing and being a different than dir
|
||||
position->children[dir]->weight = third != uint_least8_t(kNeither) && third != dir ? dir : uint_least8_t(kNeither);
|
||||
|
||||
// Detach new root from its tree (replace with new roots child)
|
||||
position->children[dir]->children[1 - dir] =
|
||||
new_root->children[dir];
|
||||
// Attach current left tree to new root
|
||||
new_root->children[dir] = position->children[dir];
|
||||
// Set weight factor for A based on F or G
|
||||
position->weight = third != uint_least8_t(kNeither) && third == dir ? 1 - dir : uint_least8_t(kNeither);
|
||||
|
||||
// Move new root's right tree to current roots left tree
|
||||
position->children[dir] = new_root->children[1 - dir];
|
||||
// Attach current root to new roots right tree
|
||||
new_root->children[1 - dir] = position;
|
||||
// Replace current position with new root
|
||||
position = new_root;
|
||||
// Clear weight factor for new current position
|
||||
position->weight = uint_least8_t(kNeither);
|
||||
}
|
||||
|
||||
|
||||
size_type current_size; ///< The number of the used nodes.
|
||||
const size_type MAX_SIZE; ///< The maximum size of the set.
|
||||
Node* root_node; ///< The node that acts as the set root.
|
||||
etl::debug_count construct_count;
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,165 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtatoptopg a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
top the Software withtop restriction, topcludtopg withtop 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 followtopg conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included top 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_IN_ISTACK_H__
|
||||
#error This header is a private element of etl::stack & etl::istack
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_STACK_BASE__
|
||||
#define __ETL_STACK_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
#include "../debug_count.h"
|
||||
|
||||
#define ETL_FILE "15"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup stack
|
||||
/// The base class for stack exceptions.
|
||||
//***************************************************************************
|
||||
class stack_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
stack_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup stack
|
||||
/// The exception thrown when the stack is full.
|
||||
//***************************************************************************
|
||||
class stack_full : public stack_exception
|
||||
{
|
||||
public:
|
||||
|
||||
stack_full(string_type file_name, numeric_type line_number)
|
||||
: stack_exception(ETL_ERROR_TEXT("stack:full", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup stack
|
||||
/// The exception thrown when the stack is empty.
|
||||
//***************************************************************************
|
||||
class stack_empty : public stack_exception
|
||||
{
|
||||
public:
|
||||
|
||||
stack_empty(string_type file_name, numeric_type line_number)
|
||||
: stack_exception(ETL_ERROR_TEXT("stack:empty", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup stack
|
||||
/// A fixed capacity stack written in the STL style.
|
||||
/// \warntopg This stack cannot be used for concurrent access from multiple threads.
|
||||
//***************************************************************************
|
||||
class stack_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type; ///< The type used for determining the size of stack.
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the stack is empty.
|
||||
/// \return <b>true</b> if the stack is empty, otherwise <b>false</b>
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return current_size == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the stack is full.
|
||||
/// \return <b>true</b> if the stack is full, otherwise <b>false</b>
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return current_size == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the current number of items top the stack.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum number of items that can be stacked.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
stack_base(size_type max_size)
|
||||
: top_index(0),
|
||||
current_size(0),
|
||||
MAX_SIZE(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
size_type top_index; ///< The index of the top of the stack.
|
||||
size_type current_size; ///< The number of items in the stack.
|
||||
const size_type MAX_SIZE; ///< The maximum number of items in the stack.
|
||||
etl::debug_count construct_count; ///< For internal debugging purposes.
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -1,220 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2016 jwellbelove
|
||||
|
||||
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_IN_ISTRING_H__
|
||||
#error This header is a private element of etl::string & etl::istring
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_STRING_BASE__
|
||||
#define __ETL_STRING_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../platform.h"
|
||||
#include "../integral_limits.h"
|
||||
#include "../exception.h"
|
||||
#include "../error_handler.h"
|
||||
|
||||
#define ETL_FILE "27"
|
||||
|
||||
#ifdef ETL_COMPILER_MICROSOFT
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup string
|
||||
/// Exception base for strings
|
||||
//***************************************************************************
|
||||
class string_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
string_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup string
|
||||
/// String empty exception.
|
||||
//***************************************************************************
|
||||
class string_empty : public string_exception
|
||||
{
|
||||
public:
|
||||
|
||||
string_empty(string_type file_name, numeric_type line_number)
|
||||
: string_exception(ETL_ERROR_TEXT("string:empty", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup string
|
||||
/// String out of bounds exception.
|
||||
//***************************************************************************
|
||||
class string_out_of_bounds : public string_exception
|
||||
{
|
||||
public:
|
||||
|
||||
string_out_of_bounds(string_type file_name, numeric_type line_number)
|
||||
: string_exception(ETL_ERROR_TEXT("string:bounds", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup string
|
||||
/// String iterator exception.
|
||||
//***************************************************************************
|
||||
class string_iterator : public string_exception
|
||||
{
|
||||
public:
|
||||
|
||||
string_iterator(string_type file_name, numeric_type line_number)
|
||||
: string_exception(ETL_ERROR_TEXT("string:iterator", ETL_FILE"D"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup string
|
||||
/// The base class for all templated string types.
|
||||
//***************************************************************************
|
||||
class string_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
enum
|
||||
{
|
||||
npos = etl::integral_limits<size_t>::max
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the string.
|
||||
///\return The current size of the string.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the string.
|
||||
///\return The current size of the string.
|
||||
//*************************************************************************
|
||||
size_type length() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'empty' state of the string.
|
||||
///\return <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return (current_size == 0);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the string.
|
||||
///\return <b>true</b> if full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return current_size == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the string.
|
||||
///\return The capacity of the string.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum possible size of the string.
|
||||
///\return The maximum size of the string.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns whether the string was truncated by the lat operation.
|
||||
///\return Whether the string was truncated by the lat operation.
|
||||
//*************************************************************************
|
||||
size_t truncated() const
|
||||
{
|
||||
return is_truncated;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor.
|
||||
//*************************************************************************
|
||||
string_base(size_t max_size)
|
||||
: is_truncated(false),
|
||||
current_size(0),
|
||||
MAX_SIZE(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
bool is_truncated; ///< Set to true if the operation truncated the string.
|
||||
size_type current_size; ///< The current number of elements in the string.
|
||||
const size_type MAX_SIZE; ///< The maximum number of elements in the string.
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef ETL_COMPILER_MICROSOFT
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user