diff --git a/.gitignore b/.gitignore
index cdb074f8..c024df33 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,7 +11,6 @@ build_bench
bench.bat
build.bat
.p4config
-EASTL.psf
## CMake generated files
CMakeCache.txt
diff --git a/doc/EASTL FAQ.html b/doc/EASTL FAQ.html
index e1871697..6ef19dcf 100644
--- a/doc/EASTL FAQ.html
+++ b/doc/EASTL FAQ.html
@@ -470,7 +470,7 @@
Smart pointers
Type traits
-Of these, the last two (smart pointers and type traits) do not have analogs in standard C++. With respect to the other items, EASTL provides extensions and optimizations over the equivalents in standard C++ STL.
+EASTL provides extensions and optimizations over the equivalents in standard C++ STL.
EASTL is a professional-level implementation which outperforms commercial implementations (where functionality overlaps) and is significantly easier to read and debug.
Info.2
What uses are EASTL suitable for?
@@ -525,6 +525,10 @@
utility
functional
iterator
+ string_view
+ variant
+ any
+ optional
EASTL additions/amendments to std STL
@@ -573,6 +577,7 @@
- fixed_hash_multiset
- fixed_hash_map
- fixed_hash_multimap
+ - fixed_function
- vector_set
- vector_multiset
- vector_map
@@ -615,40 +620,20 @@
Status |
Notes |
-
- GCC 2.9x |
- Supported |
- However, GCC 2.9x has some issues that you may run into that cause you to use EASTL facilities differently than a fully compliant compiler would allow. |
-
GCC 3.x+ |
- Supported |
- This compiler is used by the Mac OSX, and Linux platforms. |
-
-
- MSVC 6.0 |
- Not supported |
- This compiler is too weak in the area of template and namespace support. |
-
-
- MSVC 7.0+ |
- Supported |
- This compiler is used by the PC and Win CE platforms |
-
-
- Borland 5.5+ |
- Not supported |
- Borland can successfully compile many parts of EASTL, but not all parts. |
+ Not Supported |
+ Not officially supported due to migration to Clang. |
- EDG |
+ MSVC 12.0+ |
Supported |
- This is the compiler front end to some other compilers, such as Intel, and Comeau C++. |
+ This compiler is used by the Windows based platforms |
- IBM XL 5.0+ |
+ Clang 4.0+ |
Supported |
- This compiler is sometimes used by PowerPC platforms such as Mac OSX and possibly future console platforms. |
+ This compiler is used by the Linux based platforms |
@@ -718,10 +703,12 @@
- The C++ standard, which is fairly readable. You can buy an electronic version for about $18 and in the meantime you can make do with draft revisions of it off the Internet by searching for "c++ draft standard".
- STL performance tips, by Pete Isensee
- STL algorithms vs. hand-written loops, by Scott Meyers.
+ - cppreference.com
+ - isocpp.org
-
Info.9
What is the legal status of EASTL?
-EASTL is usable for all uses within Electronic Arts, both for internal usage and for shipping products for all platforms. All source code was written by a single EA engineer. Any externally derived code would be explicitly stated as such and approved by the legal department if such code ever gets introduced. As of EASTL v1.0, the red_black_tree.cpp file contains two functions derived from the original HP STL and have received EA legal approval for usage in any product.
+EASTL is usable for all uses within Electronic Arts, both for internal usage and for shipping products for all platforms. Any externally derived code would be explicitly stated as such and approved by the legal department if such code ever gets introduced. As of EASTL v1.0, the red_black_tree.cpp file contains two functions derived from the original HP STL and have received EA legal approval for usage in any product.
Info.10
Does EASTL deal with compiler exception handling settings?
EASTL has automatic knowledge of the compiler's enabling/disabling of exceptions. If your compiler is set to disable exceptions, EASTL automatically detects so and executes without them. Also, you can force-enable or force-disable that setting to override the automatic behavior by #defining EASTL_EXCEPTIONS_ENABLED to 0 or 1. See EASTL's config.h for more information.
diff --git a/doc/EASTL Modules.html b/doc/EASTL Modules.html
index 828b0677..1f60cea2 100644
--- a/doc/EASTL Modules.html
+++ b/doc/EASTL Modules.html
@@ -275,7 +275,7 @@ Module Behaviour
- |
1 |
1 |
-1 |
+n |
n+ |
@@ -290,7 +290,7 @@ Module Behaviour
- |
1 |
1 |
-1 |
+n |
n log(n) |
diff --git a/doc/EASTL.natvis b/doc/EASTL.natvis
index 763349e3..30f1cc2b 100644
--- a/doc/EASTL.natvis
+++ b/doc/EASTL.natvis
@@ -49,30 +49,32 @@
{mPair.mFirst.heap.mpBegin,s}
- - mPair.mFirst.heap.mpEnd - mPair.mFirst.heap.mpBegin
- - mPair.mFirst.heap.mpCapacity - mPair.mFirst.heap.mpBegin
- - mPair.mFirst.heap.mpBegin,sb
+ - mPair.mFirst.heap.mnSize
+ - (mPair.mFirst.heap.mnCapacity
+ & ~kHeapMask)
+ - mPair.mFirst.heap.mpBegin,sb
- - mPair.mFirst.sso.mnSize
- - SSOLayout::SSO_SIZE_IN_BYTES-0
- - mPair.mFirst.sso.mpBegin,sb
+ - mPair.mFirst.sso.mnSize
+ - SSOLayout::SSO_CAPACITY
+ - mPair.mFirst.sso.mData,sb
- - mPair.mFirst.sso.mpBegin != mPair.mFirst.sso.mBuffer
+ - !!(mPair.mFirst.sso.mnSize & kSSOMask)
{mPair.mFirst.heap.mpBegin,su}
- - mPair.mFirst.heap.mpEnd - mPair.mFirst.heap.mpBegin
- - mPair.mFirst.heap.mpCapacity - mPair.mFirst.heap.mpBegin
- - mPair.mFirst.heap.mpBegin,sub
+ - mPair.mFirst.heap.mnSize
+ - (mPair.mFirst.heap.mnCapacity
+ & ~kHeapMask)
+ - mPair.mFirst.heap.mpBegin,sb
- - mPair.mFirst.sso.mnSize
- - SSOLayout::SSO_SIZE_IN_BYTES-0
- - mPair.mFirst.sso.mpBegin,sub
+ - mPair.mFirst.sso.mnSize
+ - SSOLayout::SSO_CAPACITY
+ - mPair.mFirst.sso.mData,sb
- - mPair.mFirst.sso.mpBegin != mPair.mFirst.sso.mBuffer
+ - !!(mPair.mFirst.sso.mnSize & kSSOMask)
diff --git a/include/EASTL/any.h b/include/EASTL/any.h
index 5075113f..35e82373 100644
--- a/include/EASTL/any.h
+++ b/include/EASTL/any.h
@@ -379,9 +379,10 @@ namespace eastl
any(ValueType&& value,
typename eastl::enable_if::type, any>::value>::type* = 0)
{
- static_assert(is_copy_constructible>::value, "ValueType must be copy-constructible");
- storage_handler>::construct(m_storage, eastl::forward(value));
- m_handler = &storage_handler::handler_func;
+ typedef decay_t DecayedValueType;
+ static_assert(is_copy_constructible::value, "ValueType must be copy-constructible");
+ storage_handler::construct(m_storage, eastl::forward(value));
+ m_handler = &storage_handler::handler_func;
}
template
diff --git a/include/EASTL/deque.h b/include/EASTL/deque.h
index 82d27ec8..69a3af4a 100644
--- a/include/EASTL/deque.h
+++ b/include/EASTL/deque.h
@@ -79,24 +79,15 @@
#include
#include
-#ifdef _MSC_VER
- #pragma warning(push, 0)
- #include
- #include
- #pragma warning(pop)
-#else
- #include
- #include
-#endif
+EA_DISABLE_ALL_VC_WARNINGS()
+#include
+#include
+EA_RESTORE_ALL_VC_WARNINGS()
#if EASTL_EXCEPTIONS_ENABLED
- #ifdef _MSC_VER
- #pragma warning(push, 0)
- #endif
+ EA_DISABLE_ALL_VC_WARNINGS()
#include // std::out_of_range, std::length_error.
- #ifdef _MSC_VER
- #pragma warning(pop)
- #endif
+ EA_RESTORE_ALL_VC_WARNINGS()
#endif
#ifdef _MSC_VER
@@ -273,15 +264,8 @@ namespace eastl
typedef DequeIterator iterator;
typedef DequeIterator const_iterator;
- #if defined(_MSC_VER) && (_MSC_VER >= 1400) && (_MSC_VER <= 1600) && !EASTL_STD_CPP_ONLY // _MSC_VER of 1400 means VS2005, 1600 means VS2010. VS2012 generates errors with usage of enum:size_type.
- enum : size_type { // Use Microsoft enum language extension, allowing for smaller debug symbols than using a static const. Users have been affected by this.
- npos = (size_type)-1,
- kMaxSize = (size_type)-2
- };
- #else
- static const size_type npos = (size_type)-1; /// 'npos' means non-valid position or simply non-position.
- static const size_type kMaxSize = (size_type)-2; /// -1 is reserved for 'npos'. It also happens to be slightly beneficial that kMaxSize is a value less than -1, as it helps us deal with potential integer wraparound issues.
- #endif
+ static const size_type npos = (size_type)-1; /// 'npos' means non-valid position or simply non-position.
+ static const size_type kMaxSize = (size_type)-2; /// -1 is reserved for 'npos'. It also happens to be slightly beneficial that kMaxSize is a value less than -1, as it helps us deal with potential integer wraparound issues.
enum
{
@@ -352,7 +336,6 @@ namespace eastl
class deque : public DequeBase
{
public:
-
typedef DequeBase base_type;
typedef deque this_type;
typedef T value_type;
@@ -390,10 +373,8 @@ namespace eastl
explicit deque(size_type n, const allocator_type& allocator = EASTL_DEQUE_DEFAULT_ALLOCATOR);
deque(size_type n, const value_type& value, const allocator_type& allocator = EASTL_DEQUE_DEFAULT_ALLOCATOR);
deque(const this_type& x);
- #if EASTL_MOVE_SEMANTICS_ENABLED
- deque(this_type&& x);
- deque(this_type&& x, const allocator_type& allocator);
- #endif
+ deque(this_type&& x);
+ deque(this_type&& x, const allocator_type& allocator);
deque(std::initializer_list ilist, const allocator_type& allocator = EASTL_DEQUE_DEFAULT_ALLOCATOR);
template
@@ -403,18 +384,16 @@ namespace eastl
this_type& operator=(const this_type& x);
this_type& operator=(std::initializer_list ilist);
- #if EASTL_MOVE_SEMANTICS_ENABLED
- this_type& operator=(this_type&& x);
- #endif
+ this_type& operator=(this_type&& x);
void swap(this_type& x);
void assign(size_type n, const value_type& value);
+ void assign(std::initializer_list ilist);
- template // It turns out that the C++ std::deque specifies a two argument
+ template // It turns out that the C++ std::deque specifies a two argument
void assign(InputIterator first, InputIterator last); // version of assign that takes (int size, int value). These are not
// iterators, so we need to do a template compiler trick to do the right thing.
- void assign(std::initializer_list ilist);
iterator begin() EA_NOEXCEPT;
const_iterator begin() const EA_NOEXCEPT;
@@ -455,54 +434,34 @@ namespace eastl
void push_front(const value_type& value);
reference push_front();
- #if EASTL_MOVE_SEMANTICS_ENABLED
- void push_front(value_type&& value);
- #endif
+ void push_front(value_type&& value);
void push_back(const value_type& value);
reference push_back();
- #if EASTL_MOVE_SEMANTICS_ENABLED
- void push_back(value_type&& value);
- #endif
+ void push_back(value_type&& value);
void pop_front();
void pop_back();
- #if EASTL_MOVE_SEMANTICS_ENABLED && EASTL_VARIADIC_TEMPLATES_ENABLED
- template
- iterator emplace(const_iterator position, Args&&... args);
-
- template
- void emplace_front(Args&&... args);
+ template
+ iterator emplace(const_iterator position, Args&&... args);
- template
- void emplace_back(Args&&... args);
- #else
- #if EASTL_MOVE_SEMANTICS_ENABLED
- iterator emplace(const_iterator position, value_type&& value);
- void emplace_front(value_type&& value);
- void emplace_back(value_type&& value);
- #endif
+ template
+ void emplace_front(Args&&... args);
- iterator emplace(const_iterator position, const value_type& value);
- void emplace_front(const value_type& value);
- void emplace_back(const value_type& value);
- #endif
+ template
+ void emplace_back(Args&&... args);
iterator insert(const_iterator position, const value_type& value);
- #if EASTL_MOVE_SEMANTICS_ENABLED
- iterator insert(const_iterator position, value_type&& value);
- #endif
- void insert(const_iterator position, size_type n, const value_type& value);
+ iterator insert(const_iterator position, value_type&& value);
+ void insert(const_iterator position, size_type n, const value_type& value);
+ iterator insert(const_iterator position, std::initializer_list ilist);
template
void insert(const_iterator position, InputIterator first, InputIterator last);
- iterator insert(const_iterator position, std::initializer_list ilist);
-
- iterator erase(const_iterator position);
- iterator erase(const_iterator first, const_iterator last);
-
+ iterator erase(const_iterator position);
+ iterator erase(const_iterator first, const_iterator last);
reverse_iterator erase(reverse_iterator position);
reverse_iterator erase(reverse_iterator first, reverse_iterator last);
@@ -864,16 +823,15 @@ namespace eastl
//if(n)
//{
const size_type nNewPtrArraySize = (size_type)((n / kDequeSubarraySize) + 1); // Always have at least one, even if n is zero.
- const size_type kMinPtrArraySize_ = kMinPtrArraySize; // GCC 4.0 blows up unless we define this constant.
+ const size_type kMinPtrArraySize_ = kMinPtrArraySize;
- mnPtrArraySize = eastl::max_alt(kMinPtrArraySize_, (nNewPtrArraySize + 2)); // GCC 4.0 blows up on this.
+ mnPtrArraySize = eastl::max_alt(kMinPtrArraySize_, (nNewPtrArraySize + 2));
mpPtrArray = DoAllocatePtrArray(mnPtrArraySize);
value_type** const pPtrArrayBegin = (mpPtrArray + ((mnPtrArraySize - nNewPtrArraySize) / 2)); // Try to place it in the middle.
value_type** const pPtrArrayEnd = pPtrArrayBegin + nNewPtrArraySize;
value_type** pPtrArrayCurrent = pPtrArrayBegin;
- // I am sorry for the mess of #ifs and indentations below.
#if EASTL_EXCEPTIONS_ENABLED
try
{
@@ -1267,22 +1225,20 @@ namespace eastl
}
- #if EASTL_MOVE_SEMANTICS_ENABLED
- template
- inline deque::deque(this_type&& x)
- : base_type((size_type)0, x.mAllocator)
- {
- swap(x);
- }
+ template
+ inline deque::deque(this_type&& x)
+ : base_type((size_type)0, x.mAllocator)
+ {
+ swap(x);
+ }
- template
- inline deque::deque(this_type&& x, const allocator_type& allocator)
- : base_type((size_type)0, allocator)
- {
- swap(x); // member swap handles the case that x has a different allocator than our allocator by doing a copy.
- }
- #endif
+ template
+ inline deque::deque(this_type&& x, const allocator_type& allocator)
+ : base_type((size_type)0, allocator)
+ {
+ swap(x); // member swap handles the case that x has a different allocator than our allocator by doing a copy.
+ }
template
@@ -1346,19 +1302,17 @@ namespace eastl
}
- #if EASTL_MOVE_SEMANTICS_ENABLED
- template
- inline typename deque::this_type&
- deque::operator=(this_type&& x)
+ template
+ inline typename deque::this_type&
+ deque::operator=(this_type&& x)
+ {
+ if(this != &x)
{
- if(this != &x)
- {
- set_capacity(0); // To consider: Are we really required to clear here? x is going away soon and will clear itself in its dtor.
- swap(x); // member swap handles the case that x has a different allocator than our allocator by doing a copy.
- }
- return *this;
+ set_capacity(0); // To consider: Are we really required to clear here? x is going away soon and will clear itself in its dtor.
+ swap(x); // member swap handles the case that x has a different allocator than our allocator by doing a copy.
}
- #endif
+ return *this;
+ }
template
@@ -1528,6 +1482,8 @@ namespace eastl
template
inline void deque::shrink_to_fit()
{
+ this_type x(eastl::make_move_iterator(begin()), eastl::make_move_iterator(end()));
+ swap(x);
}
@@ -1696,13 +1652,11 @@ namespace eastl
}
- #if EASTL_MOVE_SEMANTICS_ENABLED
- template
- void deque::push_front(value_type&& value)
- {
- emplace_front(eastl::move(value));
- }
- #endif
+ template
+ void deque::push_front(value_type&& value)
+ {
+ emplace_front(eastl::move(value));
+ }
template
@@ -1721,13 +1675,11 @@ namespace eastl
}
- #if EASTL_MOVE_SEMANTICS_ENABLED
- template
- void deque::push_back(value_type&& value)
- {
- emplace_back(eastl::move(value));
- }
- #endif
+ template
+ void deque::push_back(value_type&& value)
+ {
+ emplace_back(eastl::move(value));
+ }
template
@@ -1799,400 +1751,130 @@ namespace eastl
}
- #if EASTL_MOVE_SEMANTICS_ENABLED && EASTL_VARIADIC_TEMPLATES_ENABLED
- template
- template
- typename deque::iterator
- deque::emplace(const_iterator position, Args&&... args)
+ template
+ template
+ typename deque::iterator
+ deque::emplace(const_iterator position, Args&&... args)
+ {
+ if(EASTL_UNLIKELY(position.mpCurrent == mItEnd.mpCurrent)) // If we are doing the same thing as push_back...
{
- if(EASTL_UNLIKELY(position.mpCurrent == mItEnd.mpCurrent)) // If we are doing the same thing as push_back...
- {
- emplace_back(eastl::forward(args)...);
- return iterator(mItEnd, typename iterator::Decrement()); // Unfortunately, we need to make an iterator here, as the above push_back is an operation that can invalidate existing iterators.
- }
- else if(EASTL_UNLIKELY(position.mpCurrent == mItBegin.mpCurrent)) // If we are doing the same thing as push_front...
- {
- emplace_front(eastl::forward(args)...);
- return mItBegin;
- }
-
- iterator itPosition(position, typename iterator::FromConst());
- #if EASTL_USE_FORWARD_WORKAROUND
- auto valueSaved = value_type(eastl::forward(args)...); //Workaround for compiler bug in VS2013
- #else
- value_type valueSaved(eastl::forward(args)...); // We need to save this because value may come from within our container. It would be somewhat tedious to make a workaround that could avoid this.
- #endif
- const difference_type i(itPosition - mItBegin);
-
- #if EASTL_ASSERT_ENABLED
- EASTL_ASSERT(!empty()); // The push_front and push_back calls below assume that we are non-empty. It turns out this is never called unless so.
-
- if(EASTL_UNLIKELY(!(validate_iterator(itPosition) & isf_valid)))
- EASTL_FAIL_MSG("deque::emplace -- invalid iterator");
- #endif
-
- if(i < (difference_type)(size() / 2)) // Should we insert at the front or at the back? We divide the range in half.
- {
- emplace_front(*mItBegin); // This operation potentially invalidates all existing iterators and so we need to assign them anew relative to mItBegin below.
-
- itPosition = mItBegin + i;
+ emplace_back(eastl::forward(args)...);
+ return iterator(mItEnd, typename iterator::Decrement()); // Unfortunately, we need to make an iterator here, as the above push_back is an operation that can invalidate existing iterators.
+ }
+ else if(EASTL_UNLIKELY(position.mpCurrent == mItBegin.mpCurrent)) // If we are doing the same thing as push_front...
+ {
+ emplace_front(eastl::forward(args)...);
+ return mItBegin;
+ }
- const iterator newPosition (itPosition, typename iterator::Increment());
- iterator oldBegin (mItBegin, typename iterator::Increment());
- const iterator oldBeginPlus1(oldBegin, typename iterator::Increment());
+ iterator itPosition(position, typename iterator::FromConst());
+ value_type valueSaved(eastl::forward(args)...); // We need to save this because value may come from within our container. It would be somewhat tedious to make a workaround that could avoid this.
+ const difference_type i(itPosition - mItBegin);
- oldBegin.copy(oldBeginPlus1, newPosition, eastl::has_trivial_relocate());
- }
- else
- {
- emplace_back(*iterator(mItEnd, typename iterator::Decrement()));
+ #if EASTL_ASSERT_ENABLED
+ EASTL_ASSERT(!empty()); // The push_front and push_back calls below assume that we are non-empty. It turns out this is never called unless so.
- itPosition = mItBegin + i;
+ if(EASTL_UNLIKELY(!(validate_iterator(itPosition) & isf_valid)))
+ EASTL_FAIL_MSG("deque::emplace -- invalid iterator");
+ #endif
- iterator oldBack (mItEnd, typename iterator::Decrement());
- const iterator oldBackMinus1(oldBack, typename iterator::Decrement());
+ if(i < (difference_type)(size() / 2)) // Should we insert at the front or at the back? We divide the range in half.
+ {
+ emplace_front(*mItBegin); // This operation potentially invalidates all existing iterators and so we need to assign them anew relative to mItBegin below.
- oldBack.copy_backward(itPosition, oldBackMinus1, eastl::has_trivial_relocate());
- }
+ itPosition = mItBegin + i;
- *itPosition = eastl::move(valueSaved);
+ const iterator newPosition (itPosition, typename iterator::Increment());
+ iterator oldBegin (mItBegin, typename iterator::Increment());
+ const iterator oldBeginPlus1(oldBegin, typename iterator::Increment());
- return itPosition;
+ oldBegin.copy(oldBeginPlus1, newPosition, eastl::has_trivial_relocate());
}
-
- template
- template
- void deque::emplace_front(Args&&... args)
+ else
{
- if(mItBegin.mpCurrent != mItBegin.mpBegin) // If we have room in the first subarray... we hope that usually this 'new' pathway gets executed, as it is slightly faster.
- ::new((void*)--mItBegin.mpCurrent) value_type(eastl::forward(args)...); // Construct in place. If args is a single arg of type value_type&& then it this will be a move construction.
- else
- {
- // To consider: Detect if value isn't coming from within this container and handle that efficiently.
- #if EASTL_USE_FORWARD_WORKAROUND
- auto valueSaved = value_type(eastl::forward(args)...); //Workaround for compiler bug in VS2013
- #else
- value_type valueSaved(eastl::forward(args)...); // We need to make a temporary, because args may be a value_type that comes from within our container and the operations below may change the container. But we can use move instead of copy.
- #endif
+ emplace_back(*iterator(mItEnd, typename iterator::Decrement()));
- if(mItBegin.mpCurrentArrayPtr == mpPtrArray) // If there are no more pointers in front of the current (first) one...
- DoReallocPtrArray(1, kSideFront);
+ itPosition = mItBegin + i;
- mItBegin.mpCurrentArrayPtr[-1] = DoAllocateSubarray();
+ iterator oldBack (mItEnd, typename iterator::Decrement());
+ const iterator oldBackMinus1(oldBack, typename iterator::Decrement());
- #if EASTL_EXCEPTIONS_ENABLED
- try
- {
- #endif
- mItBegin.SetSubarray(mItBegin.mpCurrentArrayPtr - 1);
- mItBegin.mpCurrent = mItBegin.mpEnd - 1;
- ::new((void*)mItBegin.mpCurrent) value_type(eastl::move(valueSaved));
- #if EASTL_EXCEPTIONS_ENABLED
- }
- catch(...)
- {
- ++mItBegin; // The exception could only occur in the new operation above, after we have incremented mItBegin. So we need to undo it.
- DoFreeSubarray(mItBegin.mpCurrentArrayPtr[-1]);
- throw;
- }
- #endif
- }
+ oldBack.copy_backward(itPosition, oldBackMinus1, eastl::has_trivial_relocate());
}
- template
- template
- void deque::emplace_back(Args&&... args)
- {
- if((mItEnd.mpCurrent + 1) != mItEnd.mpEnd) // If we have room in the last subarray... we hope that usually this 'new' pathway gets executed, as it is slightly faster.
- ::new((void*)mItEnd.mpCurrent++) value_type(eastl::forward(args)...); // Construct in place. If args is a single arg of type value_type&& then it this will be a move construction.
- else
- {
- // To consider: Detect if value isn't coming from within this container and handle that efficiently.
- #if EASTL_USE_FORWARD_WORKAROUND
- auto valueSaved = value_type(eastl::forward(args)...); //Workaround for compiler bug in VS2013
- #else
- value_type valueSaved(eastl::forward(args)...); // We need to make a temporary, because args may be a value_type that comes from within our container and the operations below may change the container. But we can use move instead of copy.
- #endif
- if(((mItEnd.mpCurrentArrayPtr - mpPtrArray) + 1) >= (difference_type)mnPtrArraySize) // If there are no more pointers after the current (last) one.
- DoReallocPtrArray(1, kSideBack);
-
- mItEnd.mpCurrentArrayPtr[1] = DoAllocateSubarray();
+ *itPosition = eastl::move(valueSaved);
- #if EASTL_EXCEPTIONS_ENABLED
- try
- {
- #endif
- ::new((void*)mItEnd.mpCurrent) value_type(eastl::move(valueSaved)); // We can move valueSaved into position.
- mItEnd.SetSubarray(mItEnd.mpCurrentArrayPtr + 1);
- mItEnd.mpCurrent = mItEnd.mpBegin;
- #if EASTL_EXCEPTIONS_ENABLED
- }
- catch(...)
- {
- // No need to execute '--mItEnd', as the exception could only occur in the new operation above before we set mItEnd.
- DoFreeSubarray(mItEnd.mpCurrentArrayPtr[1]);
- throw;
- }
- #endif
- }
- }
- #else
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // Note: The following two sets of three functions are nearly copies of the above three functions.
- // We (nearly) duplicate code here instead of trying to fold the all nine of these functions into
- // three more generic functions because: 1) you can't really make just three functions but rather
- // would need to break them apart somewhat, and 2) these duplications are eventually going away
- // because they aren't needed with C++11 compilers, though that may not be until the year 2020.
- ////////////////////////////////////////////////////////////////////////////////////////////////////
-
- #if EASTL_MOVE_SEMANTICS_ENABLED
- template
- typename deque::iterator
- deque::emplace(const_iterator position, value_type&& value)
- {
- if(EASTL_UNLIKELY(position.mpCurrent == mItEnd.mpCurrent)) // If we are doing the same thing as push_back...
- {
- emplace_back(eastl::move(value));
- return iterator(mItEnd, typename iterator::Decrement()); // Unfortunately, we need to make an iterator here, as the above push_back is an operation that can invalidate existing iterators.
- }
- else if(EASTL_UNLIKELY(position.mpCurrent == mItBegin.mpCurrent)) // If we are doing the same thing as push_front...
- {
- emplace_front(eastl::move(value));
- return mItBegin;
- }
+ return itPosition;
+ }
- iterator itPosition(position, typename iterator::FromConst());
- value_type valueSaved(eastl::move(value)); // We need to save this because value may come from within our container. It would be somewhat tedious to make a workaround that could avoid this.
- const difference_type i(itPosition - mItBegin);
+ template
+ template
+ void deque::emplace_front(Args&&... args)
+ {
+ if(mItBegin.mpCurrent != mItBegin.mpBegin) // If we have room in the first subarray... we hope that usually this 'new' pathway gets executed, as it is slightly faster.
+ ::new((void*)--mItBegin.mpCurrent) value_type(eastl::forward(args)...); // Construct in place. If args is a single arg of type value_type&& then it this will be a move construction.
+ else
+ {
+ // To consider: Detect if value isn't coming from within this container and handle that efficiently.
+ value_type valueSaved(eastl::forward(args)...); // We need to make a temporary, because args may be a value_type that comes from within our container and the operations below may change the container. But we can use move instead of copy.
- #if EASTL_ASSERT_ENABLED
- EASTL_ASSERT(!empty()); // The push_front and push_back calls below assume that we are non-empty. It turns out this is never called unless so.
+ if(mItBegin.mpCurrentArrayPtr == mpPtrArray) // If there are no more pointers in front of the current (first) one...
+ DoReallocPtrArray(1, kSideFront);
- if(EASTL_UNLIKELY(!(validate_iterator(itPosition) & isf_valid)))
- EASTL_FAIL_MSG("deque::emplace -- invalid iterator");
- #endif
+ mItBegin.mpCurrentArrayPtr[-1] = DoAllocateSubarray();
- if(i < (difference_type)(size() / 2)) // Should we insert at the front or at the back? We divide the range in half.
+ #if EASTL_EXCEPTIONS_ENABLED
+ try
{
- emplace_front(*mItBegin); // This operation potentially invalidates all existing iterators and so we need to assign them anew relative to mItBegin below.
-
- itPosition = mItBegin + i;
-
- const iterator newPosition (itPosition, typename iterator::Increment());
- iterator oldBegin (mItBegin, typename iterator::Increment());
- const iterator oldBeginPlus1(oldBegin, typename iterator::Increment());
-
- oldBegin.copy(oldBeginPlus1, newPosition, eastl::has_trivial_relocate());
+ #endif
+ mItBegin.SetSubarray(mItBegin.mpCurrentArrayPtr - 1);
+ mItBegin.mpCurrent = mItBegin.mpEnd - 1;
+ ::new((void*)mItBegin.mpCurrent) value_type(eastl::move(valueSaved));
+ #if EASTL_EXCEPTIONS_ENABLED
}
- else
+ catch(...)
{
- emplace_back(*iterator(mItEnd, typename iterator::Decrement()));
-
- itPosition = mItBegin + i;
-
- iterator oldBack (mItEnd, typename iterator::Decrement());
- const iterator oldBackMinus1(oldBack, typename iterator::Decrement());
-
- oldBack.copy_backward(itPosition, oldBackMinus1, eastl::has_trivial_relocate());
+ ++mItBegin; // The exception could only occur in the new operation above, after we have incremented mItBegin. So we need to undo it.
+ DoFreeSubarray(mItBegin.mpCurrentArrayPtr[-1]);
+ throw;
}
+ #endif
+ }
+ }
- *itPosition = eastl::move(valueSaved);
+ template
+ template
+ void deque::emplace_back(Args&&... args)
+ {
+ if((mItEnd.mpCurrent + 1) != mItEnd.mpEnd) // If we have room in the last subarray... we hope that usually this 'new' pathway gets executed, as it is slightly faster.
+ ::new((void*)mItEnd.mpCurrent++) value_type(eastl::forward(args)...); // Construct in place. If args is a single arg of type value_type&& then it this will be a move construction.
+ else
+ {
+ // To consider: Detect if value isn't coming from within this container and handle that efficiently.
+ value_type valueSaved(eastl::forward(args)...); // We need to make a temporary, because args may be a value_type that comes from within our container and the operations below may change the container. But we can use move instead of copy.
+ if(((mItEnd.mpCurrentArrayPtr - mpPtrArray) + 1) >= (difference_type)mnPtrArraySize) // If there are no more pointers after the current (last) one.
+ DoReallocPtrArray(1, kSideBack);
- return itPosition;
- }
+ mItEnd.mpCurrentArrayPtr[1] = DoAllocateSubarray();
- template
- void deque::emplace_front(value_type&& value)
- {
- if(mItBegin.mpCurrent != mItBegin.mpBegin) // If we have room in the first subarray... we hope that usually this 'new' pathway gets executed, as it is slightly faster.
- ::new((void*)--mItBegin.mpCurrent) value_type(eastl::move(value)); // Move value into position.
- else
+ #if EASTL_EXCEPTIONS_ENABLED
+ try
{
- // To consider: Detect if value isn't coming from within this container and handle that efficiently.
- value_type valueSaved(eastl::move(value)); // We need to make a temporary, because value may come from within our container and the operations below may change the container. But we can use move instead of copy.
-
- if(mItBegin.mpCurrentArrayPtr == mpPtrArray) // If there are no more pointers in front of the current (first) one...
- DoReallocPtrArray(1, kSideFront);
-
- mItBegin.mpCurrentArrayPtr[-1] = DoAllocateSubarray();
-
- #if EASTL_EXCEPTIONS_ENABLED
- try
- {
- #endif
- mItBegin.SetSubarray(mItBegin.mpCurrentArrayPtr - 1);
- mItBegin.mpCurrent = mItBegin.mpEnd - 1;
- ::new((void*)mItBegin.mpCurrent) value_type(eastl::move(valueSaved));
- #if EASTL_EXCEPTIONS_ENABLED
- }
- catch(...)
- {
- ++mItBegin; // The exception could only occur in the new operation above, after we have incremented mItBegin. So we need to undo it.
- DoFreeSubarray(mItBegin.mpCurrentArrayPtr[-1]);
- throw;
- }
- #endif
+ #endif
+ ::new((void*)mItEnd.mpCurrent) value_type(eastl::move(valueSaved)); // We can move valueSaved into position.
+ mItEnd.SetSubarray(mItEnd.mpCurrentArrayPtr + 1);
+ mItEnd.mpCurrent = mItEnd.mpBegin;
+ #if EASTL_EXCEPTIONS_ENABLED
}
- }
-
- template
- void deque::emplace_back(value_type&& value)
- {
- if((mItEnd.mpCurrent + 1) != mItEnd.mpEnd) // If we have room in the last subarray... we hope that usually this 'new' pathway gets executed, as it is slightly faster.
- ::new((void*)mItEnd.mpCurrent++) value_type(eastl::move(value)); // Move value into position.
- else
+ catch(...)
{
- // To consider: Detect if value isn't coming from within this container and handle that efficiently.
- value_type valueSaved(eastl::move(value)); // We need to make a temporary, because value may come from within our container and the operations below may change the container. But we can use move instead of copy.
-
- if(((mItEnd.mpCurrentArrayPtr - mpPtrArray) + 1) >= (difference_type)mnPtrArraySize) // If there are no more pointers after the current (last) one.
- DoReallocPtrArray(1, kSideBack);
-
- mItEnd.mpCurrentArrayPtr[1] = DoAllocateSubarray();
-
- #if EASTL_EXCEPTIONS_ENABLED
- try
- {
- #endif
- ::new((void*)mItEnd.mpCurrent) value_type(eastl::move(valueSaved)); // We can move valueSaved into position.
- mItEnd.SetSubarray(mItEnd.mpCurrentArrayPtr + 1);
- mItEnd.mpCurrent = mItEnd.mpBegin;
- #if EASTL_EXCEPTIONS_ENABLED
- }
- catch(...)
- {
- // No need to execute '--mItEnd', as the exception could only occur in the new operation above before we set mItEnd.
- DoFreeSubarray(mItEnd.mpCurrentArrayPtr[1]);
- throw;
- }
- #endif
+ // No need to execute '--mItEnd', as the exception could only occur in the new operation above before we set mItEnd.
+ DoFreeSubarray(mItEnd.mpCurrentArrayPtr[1]);
+ throw;
}
- }
- #endif
-
- template
- typename deque::iterator
- deque::emplace(const_iterator position, const value_type& value)
- {
- if(EASTL_UNLIKELY(position.mpCurrent == mItEnd.mpCurrent)) // If we are doing the same thing as push_back...
- {
- emplace_back(value);
- return iterator(mItEnd, typename iterator::Decrement()); // Unfortunately, we need to make an iterator here, as the above push_back is an operation that can invalidate existing iterators.
- }
- else if(EASTL_UNLIKELY(position.mpCurrent == mItBegin.mpCurrent)) // If we are doing the same thing as push_front...
- {
- emplace_front(value);
- return mItBegin;
- }
-
- iterator itPosition(position, typename iterator::FromConst());
- value_type valueSaved(value); // We need to save this because value may come from within our container. It would be somewhat tedious to make a workaround that could avoid this.
- const difference_type i(itPosition - mItBegin);
-
- #if EASTL_ASSERT_ENABLED
- EASTL_ASSERT(!empty()); // The push_front and push_back calls below assume that we are non-empty. It turns out this is never called unless so.
-
- if(EASTL_UNLIKELY(!(validate_iterator(itPosition) & isf_valid)))
- EASTL_FAIL_MSG("deque::emplace -- invalid iterator");
#endif
-
- if(i < (difference_type)(size() / 2)) // Should we insert at the front or at the back? We divide the range in half.
- {
- emplace_front(*mItBegin); // This operation potentially invalidates all existing iterators and so we need to assign them anew relative to mItBegin below.
-
- itPosition = mItBegin + i;
-
- const iterator newPosition (itPosition, typename iterator::Increment());
- iterator oldBegin (mItBegin, typename iterator::Increment());
- const iterator oldBeginPlus1(oldBegin, typename iterator::Increment());
-
- oldBegin.copy(oldBeginPlus1, newPosition, eastl::has_trivial_relocate());
- }
- else
- {
- emplace_back(*iterator(mItEnd, typename iterator::Decrement()));
-
- itPosition = mItBegin + i;
-
- iterator oldBack (mItEnd, typename iterator::Decrement());
- const iterator oldBackMinus1(oldBack, typename iterator::Decrement());
-
- oldBack.copy_backward(itPosition, oldBackMinus1, eastl::has_trivial_relocate());
- }
-
- *itPosition = eastl::move(valueSaved);
-
- return itPosition;
- }
-
- template
- void deque::emplace_front(const value_type& value)
- {
- if(mItBegin.mpCurrent != mItBegin.mpBegin) // If we have room in the first subarray...
- ::new((void*)--mItBegin.mpCurrent) value_type(value); // We hope that usually this 'new' pathway gets executed, as it is slightly faster.
- else // Note that in this 'else' case we create a temporary, which is less desirable.
- {
- // To consider: Detect if value isn't coming from within this container and handle that efficiently.
- value_type valueSaved(value); // We need to make a temporary, because value may come from within our container and the operations below may change the container.
-
- if(mItBegin.mpCurrentArrayPtr == mpPtrArray) // If there are no more pointers in front of the current (first) one...
- DoReallocPtrArray(1, kSideFront);
-
- mItBegin.mpCurrentArrayPtr[-1] = DoAllocateSubarray();
-
- #if EASTL_EXCEPTIONS_ENABLED
- try
- {
- #endif
- mItBegin.SetSubarray(mItBegin.mpCurrentArrayPtr - 1);
- mItBegin.mpCurrent = mItBegin.mpEnd - 1;
- ::new((void*)mItBegin.mpCurrent) value_type(eastl::move(valueSaved)); // We can move valueSaved into position.
- #if EASTL_EXCEPTIONS_ENABLED
- }
- catch(...)
- {
- ++mItBegin; // The exception could only occur in the new operation above, after we have incremented mItBegin. So we need to undo it.
- DoFreeSubarray(mItBegin.mpCurrentArrayPtr[-1]);
- throw;
- }
- #endif
- }
}
-
- template
- void deque::emplace_back(const value_type& value)
- {
- if((mItEnd.mpCurrent + 1) != mItEnd.mpEnd) // If we have room in the last subarray...
- ::new((void*)mItEnd.mpCurrent++) value_type(value);
- else
- {
- // To consider: Detect if value isn't coming from within this container and handle that efficiently.
- value_type valueSaved(value); // We need to make a temporary, because value may come from within our container and the operations below may change the container.
-
- if(((mItEnd.mpCurrentArrayPtr - mpPtrArray) + 1) >= (difference_type)mnPtrArraySize) // If there are no more pointers after the current (last) one.
- DoReallocPtrArray(1, kSideBack);
-
- mItEnd.mpCurrentArrayPtr[1] = DoAllocateSubarray();
-
- #if EASTL_EXCEPTIONS_ENABLED
- try
- {
- #endif
- ::new((void*)mItEnd.mpCurrent) value_type(eastl::move(valueSaved)); // We can move valueSaved into position.
- mItEnd.SetSubarray(mItEnd.mpCurrentArrayPtr + 1);
- mItEnd.mpCurrent = mItEnd.mpBegin;
- #if EASTL_EXCEPTIONS_ENABLED
- }
- catch(...)
- {
- // No need to execute '--mItEnd', as the exception could only occur in the new operation above before we set mItEnd.
- DoFreeSubarray(mItEnd.mpCurrentArrayPtr[1]);
- throw;
- }
- #endif
- }
- }
- #endif
+ }
template
@@ -2203,14 +1885,12 @@ namespace eastl
}
- #if EASTL_MOVE_SEMANTICS_ENABLED
- template
- typename deque::iterator
- deque::insert(const_iterator position, value_type&& value)
- {
- return emplace(position, eastl::move(value));
- }
- #endif
+ template
+ typename deque::iterator
+ deque::insert(const_iterator position, value_type&& value)
+ {
+ return emplace(position, eastl::move(value));
+ }
template
diff --git a/include/EASTL/fixed_hash_map.h b/include/EASTL/fixed_hash_map.h
index 677d83e5..af6663dd 100644
--- a/include/EASTL/fixed_hash_map.h
+++ b/include/EASTL/fixed_hash_map.h
@@ -96,6 +96,7 @@ namespace eastl
enum { kMaxSize = nodeCount };
using base_type::mAllocator;
+ using base_type::clear;
protected:
node_type** mBucketBuffer[bucketCount + 1]; // '+1' because the hash table needs a null terminating bucket.
@@ -117,17 +118,13 @@ namespace eastl
const Predicate& predicate = Predicate());
fixed_hash_map(const this_type& x);
- #if EASTL_MOVE_SEMANTICS_ENABLED
- fixed_hash_map(this_type&& x);
- fixed_hash_map(this_type&& x, const overflow_allocator_type& overflowAllocator);
- #endif
+ fixed_hash_map(this_type&& x);
+ fixed_hash_map(this_type&& x, const overflow_allocator_type& overflowAllocator);
fixed_hash_map(std::initializer_list ilist, const overflow_allocator_type& overflowAllocator = EASTL_FIXED_HASH_MAP_DEFAULT_ALLOCATOR);
this_type& operator=(const this_type& x);
this_type& operator=(std::initializer_list ilist);
- #if EASTL_MOVE_SEMANTICS_ENABLED
- this_type& operator=(this_type&& x);
- #endif
+ this_type& operator=(this_type&& x);
void swap(this_type& x);
@@ -138,6 +135,8 @@ namespace eastl
const overflow_allocator_type& get_overflow_allocator() const EA_NOEXCEPT;
overflow_allocator_type& get_overflow_allocator() EA_NOEXCEPT;
void set_overflow_allocator(const overflow_allocator_type& allocator);
+
+ void clear(bool clearBuckets);
}; // fixed_hash_map
@@ -188,6 +187,7 @@ namespace eastl
enum { kMaxSize = nodeCount };
using base_type::mAllocator;
+ using base_type::clear;
protected:
node_type** mBucketBuffer[bucketCount + 1]; // '+1' because the hash table needs a null terminating bucket.
@@ -209,17 +209,13 @@ namespace eastl
const Predicate& predicate = Predicate());
fixed_hash_multimap(const this_type& x);
- #if EASTL_MOVE_SEMANTICS_ENABLED
- fixed_hash_multimap(this_type&& x);
- fixed_hash_multimap(this_type&& x, const overflow_allocator_type& overflowAllocator);
- #endif
+ fixed_hash_multimap(this_type&& x);
+ fixed_hash_multimap(this_type&& x, const overflow_allocator_type& overflowAllocator);
fixed_hash_multimap(std::initializer_list ilist, const overflow_allocator_type& overflowAllocator = EASTL_FIXED_HASH_MULTIMAP_DEFAULT_ALLOCATOR);
this_type& operator=(const this_type& x);
this_type& operator=(std::initializer_list ilist);
- #if EASTL_MOVE_SEMANTICS_ENABLED
- this_type& operator=(this_type&& x);
- #endif
+ this_type& operator=(this_type&& x);
void swap(this_type& x);
@@ -230,6 +226,8 @@ namespace eastl
const overflow_allocator_type& get_overflow_allocator() const EA_NOEXCEPT;
overflow_allocator_type& get_overflow_allocator() EA_NOEXCEPT;
void set_overflow_allocator(const overflow_allocator_type& allocator);
+
+ void clear(bool clearBuckets);
}; // fixed_hash_multimap
@@ -346,52 +344,50 @@ namespace eastl
}
- #if EASTL_MOVE_SEMANTICS_ENABLED
- template
- inline fixed_hash_map::
- fixed_hash_map(this_type&& x)
- : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
- x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer))
- {
- // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
- mAllocator.copy_overflow_allocator(x.mAllocator);
+ template
+ inline fixed_hash_map::
+ fixed_hash_map(this_type&& x)
+ : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
+ x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer))
+ {
+ // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
+ mAllocator.copy_overflow_allocator(x.mAllocator);
- #if EASTL_NAME_ENABLED
- mAllocator.set_name(x.mAllocator.get_name());
- #endif
+ #if EASTL_NAME_ENABLED
+ mAllocator.set_name(x.mAllocator.get_name());
+ #endif
- EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
+ EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
- if(!bEnableOverflow)
- base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
+ if(!bEnableOverflow)
+ base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
- mAllocator.reset(mNodeBuffer);
- base_type::insert(x.begin(), x.end());
- }
+ mAllocator.reset(mNodeBuffer);
+ base_type::insert(x.begin(), x.end());
+ }
- template
- inline fixed_hash_map::
- fixed_hash_map(this_type&& x, const overflow_allocator_type& overflowAllocator)
- : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
- x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
- {
- // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
- mAllocator.copy_overflow_allocator(x.mAllocator);
+ template
+ inline fixed_hash_map::
+ fixed_hash_map(this_type&& x, const overflow_allocator_type& overflowAllocator)
+ : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
+ x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
+ {
+ // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
+ mAllocator.copy_overflow_allocator(x.mAllocator);
- #if EASTL_NAME_ENABLED
- mAllocator.set_name(x.mAllocator.get_name());
- #endif
+ #if EASTL_NAME_ENABLED
+ mAllocator.set_name(x.mAllocator.get_name());
+ #endif
- EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
+ EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
- if(!bEnableOverflow)
- base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
+ if(!bEnableOverflow)
+ base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
- mAllocator.reset(mNodeBuffer);
- base_type::insert(x.begin(), x.end());
- }
- #endif
+ mAllocator.reset(mNodeBuffer);
+ base_type::insert(x.begin(), x.end());
+ }
template
@@ -423,15 +419,13 @@ namespace eastl
}
- #if EASTL_MOVE_SEMANTICS_ENABLED
- template
- inline typename fixed_hash_map::this_type&
- fixed_hash_map::operator=(this_type&& x)
- {
- base_type::operator=(x);
- return *this;
- }
- #endif
+ template
+ inline typename fixed_hash_map::this_type&
+ fixed_hash_map::operator=(this_type&& x)
+ {
+ base_type::operator=(x);
+ return *this;
+ }
template
@@ -457,7 +451,9 @@ namespace eastl
inline void fixed_hash_map::
reset_lose_memory()
{
- base_type::reset_lose_memory();
+ base_type::mnBucketCount = (size_type)base_type::mRehashPolicy.GetPrevBucketCount((uint32_t)bucketCount);
+ base_type::mnElementCount = 0;
+ base_type::mRehashPolicy.mnNextResize = 0;
base_type::get_allocator().reset(mNodeBuffer);
}
@@ -494,6 +490,21 @@ namespace eastl
}
+ template
+ inline void fixed_hash_map::
+ clear(bool clearBuckets)
+ {
+ base_type::DoFreeNodes(base_type::mpBucketArray, base_type::mnBucketCount);
+ if(clearBuckets)
+ {
+ base_type::DoFreeBuckets(base_type::mpBucketArray, base_type::mnBucketCount);
+ reset_lose_memory();
+ }
+ base_type::mpBucketArray = (node_type**)mBucketBuffer;
+ base_type::mnElementCount = 0;
+ }
+
+
///////////////////////////////////////////////////////////////////////
// global operators
///////////////////////////////////////////////////////////////////////
@@ -618,52 +629,50 @@ namespace eastl
}
- #if EASTL_MOVE_SEMANTICS_ENABLED
- template
- inline fixed_hash_multimap::
- fixed_hash_multimap(this_type&& x)
- : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
- x.equal_function(),fixed_allocator_type(NULL, mBucketBuffer))
- {
- // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
- mAllocator.copy_overflow_allocator(x.mAllocator);
+ template
+ inline fixed_hash_multimap::
+ fixed_hash_multimap(this_type&& x)
+ : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
+ x.equal_function(),fixed_allocator_type(NULL, mBucketBuffer))
+ {
+ // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
+ mAllocator.copy_overflow_allocator(x.mAllocator);
- #if EASTL_NAME_ENABLED
- mAllocator.set_name(x.mAllocator.get_name());
- #endif
+ #if EASTL_NAME_ENABLED
+ mAllocator.set_name(x.mAllocator.get_name());
+ #endif
- EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
+ EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
- if(!bEnableOverflow)
- base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
+ if(!bEnableOverflow)
+ base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
- mAllocator.reset(mNodeBuffer);
- base_type::insert(x.begin(), x.end());
- }
+ mAllocator.reset(mNodeBuffer);
+ base_type::insert(x.begin(), x.end());
+ }
- template
- inline fixed_hash_multimap::
- fixed_hash_multimap(this_type&& x, const overflow_allocator_type& overflowAllocator)
- : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
- x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
- {
- // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
- mAllocator.copy_overflow_allocator(x.mAllocator);
+ template
+ inline fixed_hash_multimap::
+ fixed_hash_multimap(this_type&& x, const overflow_allocator_type& overflowAllocator)
+ : base_type(prime_rehash_policy::GetPrevBucketCountOnly(bucketCount), x.hash_function(),
+ x.equal_function(), fixed_allocator_type(NULL, mBucketBuffer, overflowAllocator))
+ {
+ // This implementation is the same as above. If we could rely on using C++11 delegating constructor support then we could just call that here.
+ mAllocator.copy_overflow_allocator(x.mAllocator);
- #if EASTL_NAME_ENABLED
- mAllocator.set_name(x.mAllocator.get_name());
- #endif
+ #if EASTL_NAME_ENABLED
+ mAllocator.set_name(x.mAllocator.get_name());
+ #endif
- EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
+ EASTL_CT_ASSERT((nodeCount >= 1) && (bucketCount >= 2));
- if(!bEnableOverflow)
- base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
+ if(!bEnableOverflow)
+ base_type::set_max_load_factor(10000.f); // Set it so that we will never resize.
- mAllocator.reset(mNodeBuffer);
- base_type::insert(x.begin(), x.end());
- }
- #endif
+ mAllocator.reset(mNodeBuffer);
+ base_type::insert(x.begin(), x.end());
+ }
template
@@ -695,15 +704,13 @@ namespace eastl
}
- #if EASTL_MOVE_SEMANTICS_ENABLED
- template
- inline typename fixed_hash_multimap::this_type&
- fixed_hash_multimap::operator=(this_type&& x)
- {
- base_type::operator=(x);
- return *this;
- }
- #endif
+ template
+ inline typename fixed_hash_multimap::this_type&
+ fixed_hash_multimap::operator=(this_type&& x)
+ {
+ base_type::operator=(x);
+ return *this;
+ }
template
@@ -729,7 +736,9 @@ namespace eastl
inline void fixed_hash_multimap::
reset_lose_memory()
{
- base_type::reset_lose_memory();
+ base_type::mnBucketCount = (size_type)base_type::mRehashPolicy.GetPrevBucketCount((uint32_t)bucketCount);
+ base_type::mnElementCount = 0;
+ base_type::mRehashPolicy.mnNextResize = 0;
base_type::get_allocator().reset(mNodeBuffer);
}
@@ -765,6 +774,21 @@ namespace eastl
}
+ template
+ inline void fixed_hash_multimap::
+ clear(bool clearBuckets)
+ {
+ base_type::DoFreeNodes(base_type::mpBucketArray, base_type::mnBucketCount);
+ if(clearBuckets)
+ {
+ base_type::DoFreeBuckets(base_type::mpBucketArray, base_type::mnBucketCount);
+ reset_lose_memory();
+ }
+ base_type::mpBucketArray = (node_type**)mBucketBuffer;
+ base_type::mnElementCount = 0;
+ }
+
+
///////////////////////////////////////////////////////////////////////
// global operators
///////////////////////////////////////////////////////////////////////
diff --git a/include/EASTL/fixed_string.h b/include/EASTL/fixed_string.h
index f4b8665f..3e06a8d2 100644
--- a/include/EASTL/fixed_string.h
+++ b/include/EASTL/fixed_string.h
@@ -3,7 +3,7 @@
/////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-// This file implements a string which uses a fixed size memory pool.
+// This file implements a string which uses a fixed size memory pool.
// The bEnableOverflow template parameter allows the container to resort to
// heap allocations if the memory pool is exhausted.
///////////////////////////////////////////////////////////////////////////////
@@ -27,7 +27,7 @@ namespace eastl
///
/// Defines a default container name in the absence of a user-provided name.
/// In the case of fixed-size containers, the allocator name always refers
- /// to overflow allocations.
+ /// to overflow allocations.
///
#ifndef EASTL_FIXED_STRING_DEFAULT_NAME
#define EASTL_FIXED_STRING_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " fixed_string" // Unless the user overrides something, this is "EASTL fixed_string".
@@ -37,15 +37,15 @@ namespace eastl
/// fixed_string
///
- /// A fixed_string with bEnableOverflow == true is identical to a regular
+ /// A fixed_string with bEnableOverflow == true is identical to a regular
/// string in terms of its behavior. All the expectations of regular string
/// apply to it and no additional expectations come from it. When bEnableOverflow
- /// is false, fixed_string behaves like regular string with the exception that
+ /// is false, fixed_string behaves like regular string with the exception that
/// its capacity can never increase. All operations you do on such a fixed_string
- /// which require a capacity increase will result in undefined behavior or an
+ /// which require a capacity increase will result in undefined behavior or an
/// C++ allocation exception, depending on the configuration of EASTL.
///
- /// Note: The nodeCount value is the amount of characters to allocate, which needs to
+ /// Note: The nodeCount value is the amount of characters to allocate, which needs to
/// take into account a terminating zero. Thus if you want to store strings with a strlen
/// of 30, the nodeCount value must be at least 31.
///
@@ -55,12 +55,12 @@ namespace eastl
/// bEnableOverflow Whether or not we should use the overflow heap if our object pool is exhausted.
/// OverflowAllocator Overflow allocator, which is only used if bEnableOverflow == true. Defaults to the global heap.
///
- /// Notes:
+ /// Notes:
/// The nodeCount value must be at least 2, one for a character and one for a terminating 0.
///
- /// As of this writing, the string class necessarily reallocates when an insert of
+ /// As of this writing, the string class necessarily reallocates when an insert of
/// self is done into self. As a result, the fixed_string class doesn't support
- /// inserting self into self unless the bEnableOverflow template parameter is true.
+ /// inserting self into self unless the bEnableOverflow template parameter is true.
///
/// Example usage:
/// fixed_string fixedString("hello world"); // Can hold up to a strlen of 128.
@@ -74,7 +74,7 @@ namespace eastl
class fixed_string : public basic_string >
{
public:
- typedef fixed_vector_allocator fixed_allocator_type;
typedef typename fixed_allocator_type::overflow_allocator_type overflow_allocator_type;
typedef basic_string base_type;
@@ -92,6 +92,7 @@ namespace eastl
using base_type::append;
using base_type::resize;
using base_type::clear;
+ using base_type::capacity;
using base_type::size;
using base_type::sprintf_va_list;
using base_type::DoAllocate;
@@ -114,7 +115,7 @@ namespace eastl
fixed_string(const value_type* p);
fixed_string(size_type n, const value_type& value);
fixed_string(const this_type& x);
- fixed_string(const this_type& x, const overflow_allocator_type& overflowAllocator);
+ fixed_string(const this_type& x, const overflow_allocator_type& overflowAllocator);
fixed_string(const base_type& x);
fixed_string(const value_type* pBegin, const value_type* pEnd);
fixed_string(CtorDoNotInitialize, size_type n);
@@ -141,7 +142,7 @@ namespace eastl
void set_capacity(size_type n);
void reset_lose_memory(); // This is a unilateral reset to an initially empty state. No destructors are called, no deallocation occurs.
size_type max_size() const;
- bool full() const; // Returns true if the fixed space has been fully allocated. Note that if overflow is enabled, the container size can be greater than nodeCount but full() could return true because the fixed space may have a recently freed slot.
+ bool full() const; // Returns true if the fixed space has been fully allocated. Note that if overflow is enabled, the container size can be greater than nodeCount but full() could return true because the fixed space may have a recently freed slot.
bool has_overflowed() const; // Returns true if the allocations spilled over into the overflow allocator. Meaningful only if overflow is enabled.
bool can_overflow() const; // Returns the value of the bEnableOverflow template parameter.
@@ -173,9 +174,11 @@ namespace eastl
get_allocator().set_name(EASTL_FIXED_STRING_DEFAULT_NAME);
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
}
@@ -187,9 +190,11 @@ namespace eastl
get_allocator().set_name(EASTL_FIXED_STRING_DEFAULT_NAME);
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
}
@@ -203,9 +208,11 @@ namespace eastl
get_allocator().set_name(x.get_allocator().get_name());
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
append(x);
}
@@ -221,9 +228,11 @@ namespace eastl
get_allocator().set_name(x.get_allocator().get_name());
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
append(x);
}
@@ -237,9 +246,11 @@ namespace eastl
get_allocator().set_name(x.get_allocator().get_name());
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
append(x);
}
@@ -253,9 +264,11 @@ namespace eastl
get_allocator().set_name(x.get_allocator().get_name());
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
append(x, position, n);
}
@@ -269,9 +282,11 @@ namespace eastl
get_allocator().set_name(EASTL_FIXED_STRING_DEFAULT_NAME);
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
append(p, n);
}
@@ -281,14 +296,16 @@ namespace eastl
inline fixed_string::fixed_string(const value_type* p)
: base_type(fixed_allocator_type(mBuffer.buffer))
{
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
-
#if EASTL_NAME_ENABLED
get_allocator().set_name(EASTL_FIXED_STRING_DEFAULT_NAME);
#endif
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
+
append(p); // There better be enough space to hold the assigned string.
}
@@ -301,9 +318,11 @@ namespace eastl
get_allocator().set_name(EASTL_FIXED_STRING_DEFAULT_NAME);
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
append(n, value); // There better be enough space to hold the assigned string.
}
@@ -317,9 +336,11 @@ namespace eastl
get_allocator().set_name(EASTL_FIXED_STRING_DEFAULT_NAME);
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
append(pBegin, pEnd);
}
@@ -333,18 +354,19 @@ namespace eastl
get_allocator().set_name(EASTL_FIXED_STRING_DEFAULT_NAME);
#endif
- internalLayout().heap.mpBegin = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
- if((internalLayout().heap.mpBegin + n) < internalLayout().heap.mpCapacity)
+ if(n < nodeCount)
{
- internalLayout().heap.mpEnd = internalLayout().heap.mpBegin + n;
- *internalLayout().heap.mpEnd = 0;
+ internalLayout().SetHeapSize(n);
+ *internalLayout().HeapEndPtr() = 0;
}
else
{
- internalLayout().heap.mpEnd = mArray;
- *internalLayout().heap.mpEnd = 0;
+ internalLayout().SetHeapSize(0);
+ *internalLayout().HeapEndPtr() = 0;
+
resize(n);
}
}
@@ -358,9 +380,10 @@ namespace eastl
get_allocator().set_name(EASTL_FIXED_STRING_DEFAULT_NAME);
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+ *internalLayout().HeapBeginPtr() = 0;
va_list arguments;
va_start(arguments, pFormat);
@@ -377,9 +400,11 @@ namespace eastl
get_allocator().set_name(EASTL_FIXED_STRING_DEFAULT_NAME);
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
append(ilist.begin(), ilist.end());
}
@@ -395,9 +420,11 @@ namespace eastl
get_allocator().set_name(x.get_allocator().get_name());
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
append(x); // Let x destruct its own items.
}
@@ -411,9 +438,11 @@ namespace eastl
get_allocator().set_name(x.get_allocator().get_name());
#endif
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
- *internalLayout().heap.mpBegin = 0;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
+ internalLayout().SetHeapSize(0);
+
+ *internalLayout().HeapBeginPtr() = 0;
append(x); // Let x destruct its own items.
}
@@ -437,7 +466,7 @@ namespace eastl
return *this;
}
-
+
template
inline typename fixed_string::
this_type& fixed_string::operator=(const base_type& x)
@@ -460,7 +489,7 @@ namespace eastl
inline typename fixed_string::
this_type& fixed_string::operator=(const value_type* p)
{
- if(internalLayout().heap.mpBegin != p)
+ if(internalLayout().HeapBeginPtr() != p)
{
clear();
append(p);
@@ -522,8 +551,8 @@ namespace eastl
template
inline void fixed_string::set_capacity(size_type n)
{
- const size_type nPrevSize = (size_type)(internalLayout().heap.mpEnd - internalLayout().heap.mpBegin);
- const size_type nPrevCapacity = (size_type)((internalLayout().heap.mpCapacity - internalLayout().heap.mpBegin) - 1); // -1 because the terminating 0 isn't included in the calculated capacity value.
+ const size_type nPrevSize = internalLayout().GetSize();
+ const size_type nPrevCapacity = capacity();
if(n == npos) // If the user means to set the capacity so that it equals the size (i.e. free excess capacity)...
n = nPrevSize;
@@ -532,17 +561,17 @@ namespace eastl
{
const size_type allocSize = (n + 1); // +1 because the terminating 0 isn't included in the supplied capacity value. So now n refers the amount of memory we need.
- if(can_overflow() && (((uintptr_t)internalLayout().heap.mpBegin != (uintptr_t)mBuffer.buffer) || (allocSize > kMaxSize))) // If we are or would be using dynamically allocated memory instead of our fixed-size member buffer...
+ if(can_overflow() && (((uintptr_t)internalLayout().HeapBeginPtr() != (uintptr_t)mBuffer.buffer) || (allocSize > kMaxSize))) // If we are or would be using dynamically allocated memory instead of our fixed-size member buffer...
{
T* const pNewData = (allocSize <= kMaxSize) ? (T*)&mBuffer.buffer[0] : DoAllocate(allocSize);
- T* const pCopyEnd = (n < nPrevSize) ? (internalLayout().heap.mpBegin + n) : internalLayout().heap.mpEnd;
- CharStringUninitializedCopy(internalLayout().heap.mpBegin, pCopyEnd, pNewData); // Copy [internalLayout().heap.mpBegin, pCopyEnd) to pNewData.
- if((uintptr_t)internalLayout().heap.mpBegin != (uintptr_t)mBuffer.buffer)
- DoFree(internalLayout().heap.mpBegin, (size_type)(internalLayout().heap.mpCapacity - internalLayout().heap.mpBegin));
-
- internalLayout().heap.mpEnd = pNewData + (pCopyEnd - internalLayout().heap.mpBegin);
- internalLayout().heap.mpBegin = pNewData;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + allocSize;
+ T* const pCopyEnd = (n < nPrevSize) ? (internalLayout().HeapBeginPtr() + n) : internalLayout().HeapEndPtr();
+ CharStringUninitializedCopy(internalLayout().HeapBeginPtr(), pCopyEnd, pNewData); // Copy [internalLayout().heap.mpBegin, pCopyEnd) to pNewData.
+ if((uintptr_t)internalLayout().HeapBeginPtr() != (uintptr_t)mBuffer.buffer)
+ DoFree(internalLayout().HeapBeginPtr(), internalLayout().GetHeapCapacity() + 1);
+
+ internalLayout().SetHeapSize((size_type)(pCopyEnd - internalLayout().HeapBeginPtr()));
+ internalLayout().SetHeapBeginPtr(pNewData);
+ internalLayout().SetHeapCapacity(allocSize - 1);
} // Else the new capacity would be within our fixed buffer.
else if(n < nPrevSize) // If the newly requested capacity is less than our size, we do what vector::set_capacity does and resize, even though we actually aren't reducing the capacity.
resize(n);
@@ -553,8 +582,9 @@ namespace eastl
template
inline void fixed_string::reset_lose_memory()
{
- internalLayout().heap.mpBegin = internalLayout().heap.mpEnd = mArray;
- internalLayout().heap.mpCapacity = internalLayout().heap.mpBegin + nodeCount;
+ internalLayout().SetHeapBeginPtr(mArray);
+ internalLayout().SetHeapSize(0);
+ internalLayout().SetHeapCapacity(nodeCount - 1);
}
@@ -569,9 +599,9 @@ namespace eastl
template
inline bool fixed_string::full() const
{
- // If size >= capacity, then we are definitely full.
+ // If size >= capacity, then we are definitely full.
// Also, if our size is smaller but we've switched away from mBuffer due to a previous overflow, then we are considered full.
- return ((size_t)(internalLayout().heap.mpEnd - internalLayout().heap.mpBegin) >= kMaxSize) || ((void*)internalLayout().heap.mpBegin != (void*)mBuffer.buffer);
+ return ((size_t)(internalLayout().HeapEndPtr() - internalLayout().HeapBeginPtr()) >= kMaxSize) || ((void*)internalLayout().HeapBeginPtr() != (void*)mBuffer.buffer);
}
@@ -582,7 +612,7 @@ namespace eastl
// down to a small size where the fixed buffer could take over ownership of the data again.
// The only simple fix for this is to take on another member variable which tracks whether this overflow
// has occurred at some point in the past.
- return ((void*)internalLayout().heap.mpBegin != (void*)mBuffer.buffer);
+ return ((void*)internalLayout().HeapBeginPtr() != (void*)mBuffer.buffer);
}
@@ -598,11 +628,12 @@ namespace eastl
this_type fixed_string::substr(size_type position, size_type n) const
{
#if EASTL_STRING_OPT_RANGE_ERRORS
- if(position > (size_type)(internalLayout().heap.mpEnd - internalLayout().heap.mpBegin))
+ if(position > internalLayout().GetSize())
base_type::ThrowRangeException();
#endif
- return fixed_string(internalLayout().heap.mpBegin + position, internalLayout().heap.mpBegin + position + eastl::min_alt(n, (size_type)(internalLayout().heap.mpEnd - internalLayout().heap.mpBegin) - position));
+ return fixed_string(internalLayout().HeapBeginPtr() + position,
+ internalLayout().HeapBeginPtr() + position + eastl::min_alt(n, internalLayout().GetSize() - position));
}
@@ -612,7 +643,7 @@ namespace eastl
{
const size_type nLength = size();
if(n < nLength)
- return fixed_string(internalLayout().heap.mpBegin, internalLayout().heap.mpBegin + n);
+ return fixed_string(internalLayout().HeapBeginPtr(), internalLayout().HeapBeginPtr() + n);
return *this;
}
@@ -623,7 +654,7 @@ namespace eastl
{
const size_type nLength = size();
if(n < nLength)
- return fixed_string(internalLayout().heap.mpEnd - n, internalLayout().heap.mpEnd);
+ return fixed_string(internalLayout().HeapEndPtr() - n, internalLayout().HeapEndPtr());
return *this;
}
@@ -645,7 +676,7 @@ namespace eastl
template
- inline void
+ inline void
fixed_string::set_overflow_allocator(const overflow_allocator_type& allocator)
{
get_allocator().set_overflow_allocator(allocator);
@@ -659,10 +690,10 @@ namespace eastl
// Operator +
template
- fixed_string operator+(const fixed_string& a,
+ fixed_string operator+(const fixed_string& a,
const fixed_string& b)
{
- // We have a problem here because need to return an fixed_string by value. This will typically result in it
+ // We have a problem here because need to return an fixed_string by value. This will typically result in it
// using stack space equal to its size. That size may be too large to be workable.
typedef fixed_string this_type;
@@ -674,7 +705,7 @@ namespace eastl
template
- fixed_string operator+(const typename fixed_string::value_type* p,
+ fixed_string operator+(const typename fixed_string::value_type* p,
const fixed_string& b)
{
typedef fixed_string this_type;
@@ -688,7 +719,7 @@ namespace eastl
template
- fixed_string operator+(typename fixed_string::value_type c,
+ fixed_string operator+(typename fixed_string::value_type c,
const fixed_string& b)
{
typedef fixed_string this_type;
@@ -701,7 +732,7 @@ namespace eastl
template
- fixed_string operator+(const fixed_string& a,
+ fixed_string operator+(const fixed_string& a,
const typename fixed_string::value_type* p)
{
typedef fixed_string this_type;
@@ -715,7 +746,7 @@ namespace eastl
template
- fixed_string operator+(const fixed_string& a,
+ fixed_string operator+(const fixed_string& a,
typename fixed_string::value_type c)
{
typedef fixed_string this_type;
@@ -729,7 +760,7 @@ namespace eastl
#if EASTL_MOVE_SEMANTICS_ENABLED
template
- fixed_string operator+(fixed_string&& a,
+ fixed_string operator+(fixed_string&& a,
fixed_string&& b)
{
a.append(b); // Using an rvalue by name results in it becoming an lvalue.
@@ -737,7 +768,7 @@ namespace eastl
}
template
- fixed_string operator+(fixed_string&& a,
+ fixed_string operator+(fixed_string&& a,
const fixed_string& b)
{
a.append(b);
@@ -745,7 +776,7 @@ namespace eastl
}
template
- fixed_string operator+(const typename fixed_string::value_type* p,
+ fixed_string operator+(const typename fixed_string::value_type* p,
fixed_string&& b)
{
b.insert(0, p);
@@ -753,7 +784,7 @@ namespace eastl
}
template
- fixed_string