mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Moved non-user headers to private sub-directory.
This commit is contained in:
parent
62f807ca72
commit
72fc0e451d
172
deque_base.h
172
deque_base.h
@ -1,172 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception base for deques
|
||||
///\ingroup deque
|
||||
//***************************************************************************
|
||||
class deque_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
deque_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Deque full exception.
|
||||
///\ingroup deque
|
||||
//***************************************************************************
|
||||
class deque_full : public deque_exception
|
||||
{
|
||||
public:
|
||||
|
||||
deque_full()
|
||||
: deque_exception("deque: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Deque empty exception.
|
||||
///\ingroup deque
|
||||
//***************************************************************************
|
||||
class deque_empty : public deque_exception
|
||||
{
|
||||
public:
|
||||
|
||||
deque_empty()
|
||||
: deque_exception("deque: empty")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Deque out of bounds exception.
|
||||
///\ingroup deque
|
||||
//***************************************************************************
|
||||
class deque_out_of_bounds : public deque_exception
|
||||
{
|
||||
public:
|
||||
|
||||
deque_out_of_bounds()
|
||||
: deque_exception("deque: out of bounds")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
182
flat_map_base.h
182
flat_map_base.h
@ -1,182 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
#ifndef ETL_THROW_EXCEPTIONS
|
||||
#include "error_handler.h"
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup flat_map
|
||||
/// Exception base for flat_maps
|
||||
//***************************************************************************
|
||||
class flat_map_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_map_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_map
|
||||
/// Vector full exception.
|
||||
//***************************************************************************
|
||||
class flat_map_full : public flat_map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_map_full()
|
||||
: flat_map_exception("flat_map: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_map
|
||||
/// Vector out of bounds exception.
|
||||
//***************************************************************************
|
||||
class flat_map_out_of_bounds : public flat_map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_map_out_of_bounds()
|
||||
: flat_map_exception("flat_map: out of bounds")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_map
|
||||
/// Vector iterator exception.
|
||||
//***************************************************************************
|
||||
class flat_map_iterator : public flat_map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_map_iterator()
|
||||
: flat_map_exception("flat_map: iterator error")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_map
|
||||
/// The base class for all templated flat_map types.
|
||||
//***************************************************************************
|
||||
class flat_map_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the flat_map.
|
||||
///\return The current size of the flat_map.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return vbase.size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'empty' state of the flat_map.
|
||||
///\return <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return vbase.empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the flat_map.
|
||||
///\return <b>true</b> if full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return vbase.full();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the flat_map.
|
||||
///\return The capacity of the flat_map.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return vbase.capacity();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum possible size of the flat_map.
|
||||
///\return The maximum size of the flat_map.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return vbase.max_size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return vbase.available();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor.
|
||||
//*************************************************************************
|
||||
flat_map_base(vector_base& vbase)
|
||||
: vbase(vbase)
|
||||
{
|
||||
}
|
||||
|
||||
vector_base& vbase;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,182 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
#ifndef ETL_THROW_EXCEPTIONS
|
||||
#include "error_handler.h"
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multimap
|
||||
/// Exception base for flat_multimaps
|
||||
//***************************************************************************
|
||||
class flat_multimap_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multimap_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multimap
|
||||
/// Vector full exception.
|
||||
//***************************************************************************
|
||||
class flat_multimap_full : public flat_multimap_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multimap_full()
|
||||
: flat_multimap_exception("flat_multimap: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multimap
|
||||
/// Vector out of bounds exception.
|
||||
//***************************************************************************
|
||||
class flat_multimap_out_of_bounds : public flat_multimap_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multimap_out_of_bounds()
|
||||
: flat_multimap_exception("flat_multimap: out of bounds")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multimap
|
||||
/// Vector iterator exception.
|
||||
//***************************************************************************
|
||||
class flat_multimap_iterator : public flat_multimap_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multimap_iterator()
|
||||
: flat_multimap_exception("flat_multimap: iterator error")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multimap
|
||||
/// The base class for all templated flat_multimap types.
|
||||
//***************************************************************************
|
||||
class flat_multimap_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the flat_multimap.
|
||||
///\return The current size of the flat_multimap.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return vbase.size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'empty' state of the flat_multimap.
|
||||
///\return <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return vbase.empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the flat_multimap.
|
||||
///\return <b>true</b> if full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return vbase.full();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the flat_multimap.
|
||||
///\return The capacity of the flat_multimap.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return vbase.capacity();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum possible size of the flat_multimap.
|
||||
///\return The maximum size of the flat_multimap.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return vbase.max_size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return vbase.available();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor.
|
||||
//*************************************************************************
|
||||
flat_multimap_base(vector_base& vbase)
|
||||
: vbase(vbase)
|
||||
{
|
||||
}
|
||||
|
||||
vector_base& vbase;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,179 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multiset
|
||||
/// Exception base for flat_multisets
|
||||
//***************************************************************************
|
||||
class flat_multiset_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multiset_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multiset
|
||||
/// Flat multiset full exception.
|
||||
//***************************************************************************
|
||||
class flat_multiset_full : public flat_multiset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multiset_full()
|
||||
: flat_multiset_exception("flat_multiset: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multiset
|
||||
/// Flat multiset out of bounds exception.
|
||||
//***************************************************************************
|
||||
class flat_multiset_out_of_bounds : public flat_multiset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multiset_out_of_bounds()
|
||||
: flat_multiset_exception("flat_multiset: out of bounds")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multiset
|
||||
/// Vector iterator exception.
|
||||
//***************************************************************************
|
||||
class flat_multiset_iterator : public flat_multiset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_multiset_iterator()
|
||||
: flat_multiset_exception("flat_multiset: iterator error")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_multiset
|
||||
/// The base class for all templated flat_multiset types.
|
||||
//***************************************************************************
|
||||
class flat_multiset_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the flat_multiset.
|
||||
///\return The current size of the flat_multiset.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return vbase.size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'empty' state of the flat_multiset.
|
||||
///\return <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return vbase.empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the flat_multiset.
|
||||
///\return <b>true</b> if full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return vbase.full();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the flat_multiset.
|
||||
///\return The capacity of the flat_multiset.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return vbase.capacity();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum possible size of the flat_multiset.
|
||||
///\return The maximum size of the flat_multiset.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return vbase.max_size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return vbase.available();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor.
|
||||
//*************************************************************************
|
||||
flat_multiset_base(vector_base& vbase)
|
||||
: vbase(vbase)
|
||||
{
|
||||
}
|
||||
|
||||
vector_base& vbase;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
182
flat_set_base.h
182
flat_set_base.h
@ -1,182 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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 "ivector.h"
|
||||
|
||||
#ifndef ETL_THROW_EXCEPTIONS
|
||||
#include "error_handler.h"
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup flat_set
|
||||
/// Exception base for flat_sets
|
||||
//***************************************************************************
|
||||
class flat_set_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_set_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_set
|
||||
/// Vector full exception.
|
||||
//***************************************************************************
|
||||
class flat_set_full : public flat_set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_set_full()
|
||||
: flat_set_exception("flat_set: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_set
|
||||
/// Vector out of bounds exception.
|
||||
//***************************************************************************
|
||||
class flat_set_out_of_bounds : public flat_set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_set_out_of_bounds()
|
||||
: flat_set_exception("flat_set: out of bounds")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_set
|
||||
/// Vector iterator exception.
|
||||
//***************************************************************************
|
||||
class flat_set_iterator : public flat_set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
flat_set_iterator()
|
||||
: flat_set_exception("flat_set: iterator error")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup flat_set
|
||||
/// The base class for all templated flat_set types.
|
||||
//***************************************************************************
|
||||
class flat_set_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the flat_set.
|
||||
///\return The current size of the flat_set.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return vbase.size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'empty' state of the flat_set.
|
||||
///\return <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return vbase.empty();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the flat_set.
|
||||
///\return <b>true</b> if full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return vbase.full();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the capacity of the flat_set.
|
||||
///\return The capacity of the flat_set.
|
||||
//*************************************************************************
|
||||
size_type capacity() const
|
||||
{
|
||||
return vbase.capacity();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the maximum possible size of the flat_set.
|
||||
///\return The maximum size of the flat_set.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return vbase.max_size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return vbase.available();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor.
|
||||
//*************************************************************************
|
||||
flat_set_base(vector_base& vbase)
|
||||
: vbase(vbase)
|
||||
{
|
||||
}
|
||||
|
||||
vector_base& vbase;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,243 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the forward_list.
|
||||
///\ingroup forward_list
|
||||
//***************************************************************************
|
||||
class forward_list_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
forward_list_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the forward_list.
|
||||
///\ingroup forward_list
|
||||
//***************************************************************************
|
||||
class forward_list_full : public forward_list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
forward_list_full()
|
||||
: forward_list_exception("forward list: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the forward_list.
|
||||
///\ingroup forward_list
|
||||
//***************************************************************************
|
||||
class forward_list_iterator : public forward_list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
forward_list_iterator()
|
||||
: forward_list_exception("forward_list: iterator problem")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base class for all forward_lists.
|
||||
///\ingroup forward_list
|
||||
//***************************************************************************
|
||||
class forward_list_base
|
||||
{
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// The node element in the forward_list.
|
||||
//*************************************************************************
|
||||
struct Node
|
||||
{
|
||||
Node()
|
||||
: next(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Node* 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 current_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 current_size == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the forward_list is full.
|
||||
//*************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return current_size == MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the remaining capacity.
|
||||
///\return The remaining capacity.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return max_size() - size();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Reverses the forward_list.
|
||||
//*************************************************************************
|
||||
void reverse()
|
||||
{
|
||||
if (is_trivial_list())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Node* p_last = &start_node;
|
||||
Node* p_current = p_last->next;
|
||||
Node* 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(size_type max_size)
|
||||
: next_free(0),
|
||||
current_size(0),
|
||||
MAX_SIZE(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the head node.
|
||||
//*************************************************************************
|
||||
Node& get_head()
|
||||
{
|
||||
return *start_node.next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the head node.
|
||||
//*************************************************************************
|
||||
const Node& get_head() const
|
||||
{
|
||||
return *start_node.next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Insert a node.
|
||||
//*************************************************************************
|
||||
void insert_node_after(Node& position, Node& node)
|
||||
{
|
||||
// Connect to the forward_list.
|
||||
node.next = position.next;
|
||||
|
||||
join(&position, &node);
|
||||
|
||||
// One more.
|
||||
++current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Is the forward_list a trivial length?
|
||||
//*************************************************************************
|
||||
bool is_trivial_list() const
|
||||
{
|
||||
return (size() < 2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Join two nodes.
|
||||
//*************************************************************************
|
||||
void join(Node* left, Node* right)
|
||||
{
|
||||
left->next = right;
|
||||
}
|
||||
|
||||
Node start_node; ///< The node that acts as the forward_list start.
|
||||
size_type next_free; ///< The index of the next free node.
|
||||
size_type current_size; ///< The number of items in the list.
|
||||
const size_type MAX_SIZE; ///< The maximum size of the forward_list.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
264
list_base.h
264
list_base.h
@ -1,264 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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 "exception.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the list.
|
||||
///\ingroup list
|
||||
//***************************************************************************
|
||||
class list_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
list_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the list.
|
||||
///\ingroup list
|
||||
//***************************************************************************
|
||||
class list_full : public list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
list_full()
|
||||
: list_exception("list: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the list.
|
||||
///\ingroup list
|
||||
//***************************************************************************
|
||||
class list_iterator : public list_exception
|
||||
{
|
||||
public:
|
||||
|
||||
list_iterator()
|
||||
: list_exception("list: iterator problem")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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
|
||||
{
|
||||
//***********************************************************************
|
||||
/// Constructor
|
||||
//***********************************************************************
|
||||
Node()
|
||||
: previous(nullptr),
|
||||
next(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
/// Reverses the previous & next pointers.
|
||||
//***********************************************************************
|
||||
void reverse()
|
||||
{
|
||||
std::swap(previous, next);
|
||||
}
|
||||
|
||||
Node* previous;
|
||||
Node* next;
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// Reverses the list.
|
||||
//*************************************************************************
|
||||
void reverse()
|
||||
{
|
||||
if (is_trivial_list())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Node* p_node = terminal_node.next;
|
||||
|
||||
while (p_node != &terminal_node)
|
||||
{
|
||||
p_node->reverse();
|
||||
p_node = p_node->previous; // Now we've reversed it, we must go to the previous node.
|
||||
}
|
||||
|
||||
// Terminal node.
|
||||
p_node->reverse();
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the size of the list.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the maximum possible size of the list.
|
||||
//*************************************************************************
|
||||
size_type max_size() const
|
||||
{
|
||||
return MAX_SIZE;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the list is empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return current_size == 0;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if the list is full.
|
||||
//*************************************************************************
|
||||
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:
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the head node.
|
||||
//*************************************************************************
|
||||
Node& get_head()
|
||||
{
|
||||
return *terminal_node.next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the head node.
|
||||
//*************************************************************************
|
||||
const Node& get_head() const
|
||||
{
|
||||
return *terminal_node.next;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the tail node.
|
||||
//*************************************************************************
|
||||
Node& get_tail()
|
||||
{
|
||||
return *terminal_node.previous;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Get the tail node.
|
||||
//*************************************************************************
|
||||
const Node& get_tail() const
|
||||
{
|
||||
return *terminal_node.previous;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Insert a node before 'position'.
|
||||
//*************************************************************************
|
||||
void insert_node(Node& position, Node& node)
|
||||
{
|
||||
// Connect to the list.
|
||||
join(*position.previous, node);
|
||||
join(node, position);
|
||||
|
||||
// One more.
|
||||
++current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Is the list a trivial length?
|
||||
//*************************************************************************
|
||||
bool is_trivial_list() const
|
||||
{
|
||||
return (size() < 2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Join two nodes.
|
||||
//*************************************************************************
|
||||
void join(Node& left, Node& right)
|
||||
{
|
||||
left.next = &right;
|
||||
right.previous = &left;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// The constructor that is called from derived classes.
|
||||
//*************************************************************************
|
||||
list_base(size_type max_size)
|
||||
: current_size(0),
|
||||
MAX_SIZE(max_size)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Node terminal_node; ///< The node that acts as the list start and end.
|
||||
size_type current_size; ///< The number of the used nodes.
|
||||
const size_type MAX_SIZE; ///< The maximum size of the list.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
417
map_base.h
417
map_base.h
@ -1,417 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class map_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
map_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class map_full : public map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
map_full()
|
||||
: map_exception("map: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Map out of bounds exception.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class map_out_of_bounds : public map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
map_out_of_bounds()
|
||||
: map_exception("map: out of bounds")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class map_iterator : public map_exception
|
||||
{
|
||||
public:
|
||||
|
||||
map_iterator()
|
||||
: map_exception("map: iterator problem")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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:
|
||||
|
||||
static const uint8_t kLeft = 0;
|
||||
static const uint8_t kRight = 1;
|
||||
static const uint8_t kNeither = 2;
|
||||
|
||||
//*************************************************************************
|
||||
/// The node element in the map.
|
||||
//*************************************************************************
|
||||
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];
|
||||
uint8_t weight;
|
||||
uint8_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 (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, uint8_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 = kNeither;
|
||||
// Newly detached right now becomes current position
|
||||
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, uint8_t dir, uint8_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];
|
||||
// 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 != 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];
|
||||
// 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 = 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.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
581
multimap_base.h
581
multimap_base.h
@ -1,581 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class multimap_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
multimap_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class multimap_full : public multimap_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multimap_full()
|
||||
: multimap_exception("multimap: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Map out of bounds exception.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class multimap_out_of_bounds : public multimap_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multimap_out_of_bounds()
|
||||
: multimap_exception("multimap: out of bounds")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the map.
|
||||
///\ingroup map
|
||||
//***************************************************************************
|
||||
class multimap_iterator : public multimap_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multimap_iterator()
|
||||
: multimap_exception("multimap: iterator problem")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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 uint8_t kLeft = 0;
|
||||
static const uint8_t kRight = 1;
|
||||
static const uint8_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];
|
||||
uint8_t weight;
|
||||
uint8_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, uint8_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, uint8_t dir, uint8_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.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
580
multiset_base.h
580
multiset_base.h
@ -1,580 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class multiset_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
multiset_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class multiset_full : public multiset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multiset_full()
|
||||
: multiset_exception("multiset: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Map out of bounds exception.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class multiset_out_of_bounds : public multiset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multiset_out_of_bounds()
|
||||
: multiset_exception("multiset: out of bounds")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class multiset_iterator : public multiset_exception
|
||||
{
|
||||
public:
|
||||
|
||||
multiset_iterator()
|
||||
: multiset_exception("multiset: iterator problem")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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 uint8_t kLeft = 0;
|
||||
static const uint8_t kRight = 1;
|
||||
static const uint8_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];
|
||||
uint8_t weight;
|
||||
uint8_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, uint8_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, uint8_t dir, uint8_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.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
129
pool_base.h
129
pool_base.h
@ -1,129 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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_IPOOL_H__
|
||||
#error This header is a private element of etl::pool & etl::ipool
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_POOL_BASE__
|
||||
#define __ETL_POOL_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "exception.h"
|
||||
|
||||
#ifndef ETL_THROW_EXCEPTIONS
|
||||
#include "error_handler.h"
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for pool exceptions.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_exception(const char* what)
|
||||
: exception(what)
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the pool has no more free items.
|
||||
///\ingroup pool
|
||||
//***************************************************************************
|
||||
class pool_no_allocation : public pool_exception
|
||||
{
|
||||
public:
|
||||
|
||||
pool_no_allocation()
|
||||
: pool_exception("pool: no allocation")
|
||||
{}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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()
|
||||
: pool_exception("pool: not in pool")
|
||||
{}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
/// The base class for all templated pool types.
|
||||
///\ingroup pool
|
||||
//*************************************************************************
|
||||
class pool_base
|
||||
{
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Returns the number of free items in the pool.
|
||||
//*************************************************************************
|
||||
size_t available() const
|
||||
{
|
||||
return MAX_SIZE - items_allocated;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks to see if there are no free items in the pool.
|
||||
/// \return <b>true</b> if there are none free (or 'empty')
|
||||
//*************************************************************************
|
||||
bool none_free() const
|
||||
{
|
||||
return items_allocated == MAX_SIZE;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
//*************************************************************************
|
||||
pool_base(size_t max_size)
|
||||
: next_free(0),
|
||||
items_allocated(0),
|
||||
MAX_SIZE(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
size_t next_free; ///< The next free slot in the block.
|
||||
size_t items_allocated; ///< The number of items allocated.
|
||||
const size_t MAX_SIZE; ///< The maximum number of objects that can be allocated.
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,154 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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_IN_IPRIORITY_QUEUE_H__
|
||||
#error This header is a private element of etl::priority_queue & etl::ipriority_queue
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_PRIORITY_QUEUE_BASE__
|
||||
#define __ETL_PRIORITY_QUEUE_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "exception.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for priority_queue exceptions.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class priority_queue_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
priority_queue_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the queue is full.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class priority_queue_full : public priority_queue_exception
|
||||
{
|
||||
public:
|
||||
|
||||
priority_queue_full()
|
||||
: priority_queue_exception("priority_queue: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The priority queue iterator exception on reversed iterators
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class priority_queue_iterator : public priority_queue_exception
|
||||
{
|
||||
public:
|
||||
|
||||
priority_queue_iterator()
|
||||
: priority_queue_exception("priority_queue: iterator error")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The base class for all priority queues.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class priority_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 priority 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 priority 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 priority queue is full.
|
||||
/// \return <b>true</b> if the priority 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.
|
||||
//*************************************************************************
|
||||
priority_queue_base(size_type max_size)
|
||||
: current_size(0),
|
||||
MAX_SIZE(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
size_type current_size; ///< The number of items in the priority queue.
|
||||
const size_type MAX_SIZE; ///< The maximum number of items in the priority queue.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
144
queue_base.h
144
queue_base.h
@ -1,144 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// The base class for queue exceptions.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class queue_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
queue_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The exception thrown when the queue is full.
|
||||
///\ingroup queue
|
||||
//***************************************************************************
|
||||
class queue_full : public queue_exception
|
||||
{
|
||||
public:
|
||||
|
||||
queue_full()
|
||||
: queue_exception("queue: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
418
set_base.h
418
set_base.h
@ -1,418 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class set_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
set_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Full exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class set_full : public set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
set_full()
|
||||
: set_exception("set: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Map out of bounds exception.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class set_out_of_bounds : public set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
set_out_of_bounds()
|
||||
: set_exception("set: out of bounds")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Iterator exception for the set.
|
||||
///\ingroup set
|
||||
//***************************************************************************
|
||||
class set_iterator : public set_exception
|
||||
{
|
||||
public:
|
||||
|
||||
set_iterator()
|
||||
: set_exception("set: iterator problem")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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:
|
||||
|
||||
static const uint8_t kLeft = 0;
|
||||
static const uint8_t kRight = 1;
|
||||
static const uint8_t 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];
|
||||
uint8_t weight;
|
||||
uint8_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 (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 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, uint8_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 = kNeither;
|
||||
// Newly detached right now becomes current position
|
||||
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, uint8_t dir, uint8_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];
|
||||
// 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 != 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];
|
||||
// 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 = 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.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
143
stack_base.h
143
stack_base.h
@ -1,143 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup stack
|
||||
/// The base class for stack exceptions.
|
||||
//***************************************************************************
|
||||
class stack_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
stack_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup stack
|
||||
/// The exception thrown when the stack is full.
|
||||
//***************************************************************************
|
||||
class stack_full : public stack_exception
|
||||
{
|
||||
public:
|
||||
|
||||
stack_full()
|
||||
: stack_exception("stack: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\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.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
183
vector_base.h
183
vector_base.h
@ -1,183 +0,0 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
|
||||
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_IVECTOR_H__
|
||||
#error This header is a private element of etl::vector & etl::ivector
|
||||
#endif
|
||||
|
||||
#ifndef __ETL_VECTOR_BASE__
|
||||
#define __ETL_VECTOR_BASE__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "exception.h"
|
||||
|
||||
#ifndef ETL_THROW_EXCEPTIONS
|
||||
#include "error_handler.h"
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
///\ingroup vector
|
||||
/// Exception base for vectors
|
||||
//***************************************************************************
|
||||
class vector_exception : public exception
|
||||
{
|
||||
public:
|
||||
|
||||
vector_exception(const char* what)
|
||||
: exception(what)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup vector
|
||||
/// Vector full exception.
|
||||
//***************************************************************************
|
||||
class vector_full : public vector_exception
|
||||
{
|
||||
public:
|
||||
|
||||
vector_full()
|
||||
: vector_exception("vector: full")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup vector
|
||||
/// Vector out of bounds exception.
|
||||
//***************************************************************************
|
||||
class vector_out_of_bounds : public vector_exception
|
||||
{
|
||||
public:
|
||||
|
||||
vector_out_of_bounds()
|
||||
: vector_exception("vector: out of bounds")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup vector
|
||||
/// Vector iterator exception.
|
||||
//***************************************************************************
|
||||
class vector_iterator : public vector_exception
|
||||
{
|
||||
public:
|
||||
|
||||
vector_iterator()
|
||||
: vector_exception("vector: iterator error")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
///\ingroup vector
|
||||
/// The base class for all templated vector types.
|
||||
//***************************************************************************
|
||||
class vector_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef size_t size_type;
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current size of the vector.
|
||||
///\return The current size of the vector.
|
||||
//*************************************************************************
|
||||
size_type size() const
|
||||
{
|
||||
return current_size;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'empty' state of the vector.
|
||||
///\return <b>true</b> if empty.
|
||||
//*************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return (current_size == 0);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Checks the 'full' state of the vector.
|
||||
///\return <b>true</b> if 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 maximum possible size of the vector.
|
||||
///\return The maximum size of the vector.
|
||||
//*************************************************************************
|
||||
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.
|
||||
//*************************************************************************
|
||||
vector_base(size_t max_size)
|
||||
: current_size(0),
|
||||
MAX_SIZE(max_size)
|
||||
{
|
||||
}
|
||||
|
||||
size_type current_size; ///<The current number of elements in the vector.
|
||||
const size_type MAX_SIZE; ///<The maximum number of elements in the vector.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user