diff options
author | Andrei Karas <akaras@inbox.ru> | 2017-10-10 22:14:45 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2017-10-10 22:15:57 +0300 |
commit | aa3f63fd497558a02feb3ddbc44f31eac091f39b (patch) | |
tree | 0e28b9b1f0501dd8be9e1a38db4ec1777fa3fbfa /src/debug | |
parent | 7c10a6b61e9d06a4ae9cc9f942dfacb6fcfd9d3d (diff) | |
download | plus-aa3f63fd497558a02feb3ddbc44f31eac091f39b.tar.gz plus-aa3f63fd497558a02feb3ddbc44f31eac091f39b.tar.bz2 plus-aa3f63fd497558a02feb3ddbc44f31eac091f39b.tar.xz plus-aa3f63fd497558a02feb3ddbc44f31eac091f39b.zip |
Remove most unused files.
Diffstat (limited to 'src/debug')
-rw-r--r-- | src/debug/mse/LICENSE_1_0.txt | 23 | ||||
-rw-r--r-- | src/debug/mse/msemsevector.h | 2432 | ||||
-rw-r--r-- | src/debug/mse/msemstdvector.h | 413 | ||||
-rw-r--r-- | src/debug/mse/mseprimitives.h | 872 | ||||
-rw-r--r-- | src/debug/mse/source.txt | 1 | ||||
-rw-r--r-- | src/debug/nvwa/_nvwa.h | 112 | ||||
-rw-r--r-- | src/debug/nvwa/c++11.h | 340 | ||||
-rw-r--r-- | src/debug/nvwa/debug_new.cpp | 1197 | ||||
-rw-r--r-- | src/debug/nvwa/debug_new.h | 207 | ||||
-rw-r--r-- | src/debug/nvwa/fast_mutex.h | 427 | ||||
-rw-r--r-- | src/debug/nvwa/source.txt | 1 | ||||
-rw-r--r-- | src/debug/nvwa/static_assert.h | 62 | ||||
-rw-r--r-- | src/debug/readme.txt | 2 |
13 files changed, 0 insertions, 6089 deletions
diff --git a/src/debug/mse/LICENSE_1_0.txt b/src/debug/mse/LICENSE_1_0.txt deleted file mode 100644 index 664c26753..000000000 --- a/src/debug/mse/LICENSE_1_0.txt +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -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, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/src/debug/mse/msemsevector.h b/src/debug/mse/msemsevector.h deleted file mode 100644 index e0046ca5c..000000000 --- a/src/debug/mse/msemsevector.h +++ /dev/null @@ -1,2432 +0,0 @@ - -// Copyright (c) 2015 Noah Lopez -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef MSEMSEVECTOR_H -#define MSEMSEVECTOR_H - -/*compiler specific defines*/ -#ifdef _MSC_VER -#if (1700 > _MSC_VER) -#define MSVC2010_COMPATIBLE 1 -#endif /*(1700 > _MSC_VER)*/ -#if (1900 > _MSC_VER) -#define MSVC2013_COMPATIBLE 1 -#endif /*(1900 > _MSC_VER)*/ -#else /*_MSC_VER*/ -#if (defined(__GNUC__) || defined(__GNUG__)) -#define GPP_COMPATIBLE 1 -#if ((5 > __GNUC__) && (!defined(__clang__))) -#define GPP4P8_COMPATIBLE 1 -#endif /*((5 > __GNUC__) && (!defined(__clang__)))*/ -#endif -#endif /*_MSC_VER*/ - -//define MSE_MSEVECTOR_USE_MSE_PRIMITIVES 1 -#ifdef MSE_MSEVECTOR_USE_MSE_PRIMITIVES -#include "debug/mse/mseprimitives.h" -#endif // MSE_MSEVECTOR_USE_MSE_PRIMITIVES - -#include <vector> -#include <assert.h> -#include <memory> -#include <unordered_map> -#include <functional> -#include <climits> // ULONG_MAX -#include <stdexcept> - -#ifdef MSE_CUSTOM_THROW_DEFINITION -#include <iostream> -#define MSE_THROW(x) MSE_CUSTOM_THROW_DEFINITION(x) -#else // MSE_CUSTOM_THROW_DEFINITION -#define MSE_THROW(x) throw(x) -#endif // MSE_CUSTOM_THROW_DEFINITION - -namespace mse { - -#ifdef MSE_MSEVECTOR_USE_MSE_PRIMITIVES - typedef mse::CSize_t msev_size_t; - typedef mse::CInt msev_int; - typedef bool msev_bool; // no added safety benefit to using mse::CBool in this case - #define msev_as_a_size_t as_a_size_t -#else // MSE_MSEVECTOR_USE_MSE_PRIMITIVES -#if SIZE_MAX <= ULONG_MAX -#define MSE_MSEVECTOR_BASE_INTEGER_TYPE long int -#else // SIZE_MAX <= ULONG_MAX -#define MSE_MSEVECTOR_BASE_INTEGER_TYPE long long int -#endif // SIZE_MAX <= ULONG_MAX - - typedef size_t msev_size_t; - typedef MSE_MSEVECTOR_BASE_INTEGER_TYPE msev_int; - typedef bool msev_bool; - typedef size_t msev_as_a_size_t; -#endif // MSE_MSEVECTOR_USE_MSE_PRIMITIVES - - - class msevector_range_error : public std::range_error { public: - using std::range_error::range_error; - }; - class msevector_null_dereference_error : public std::logic_error { public: - using std::logic_error::logic_error; - }; - - /* msev_pointer behaves similar to native pointers. It's a bit safer in that it initializes to - nullptr by default and checks for attempted dereference of null pointers. */ - template<typename _Ty> - class msev_pointer { - public: - msev_pointer() : m_ptr(nullptr) {} - msev_pointer(_Ty* ptr) : m_ptr(ptr) {} - msev_pointer(const msev_pointer<_Ty>& src) : m_ptr(src.m_ptr) {} - - _Ty& operator*() const { -#ifndef MSE_DISABLE_MSEAR_POINTER_CHECKS - if (nullptr == m_ptr) { MSE_THROW(msevector_null_dereference_error("attempt to dereference null pointer - mse::msev_pointer")); } -#endif /*MSE_DISABLE_MSEAR_POINTER_CHECKS*/ - return (*m_ptr); - } - _Ty* operator->() const { -#ifndef MSE_DISABLE_MSEAR_POINTER_CHECKS - if (nullptr == m_ptr) { MSE_THROW(msevector_null_dereference_error("attempt to dereference null pointer - mse::msev_pointer")); } -#endif /*MSE_DISABLE_MSEAR_POINTER_CHECKS*/ - return m_ptr; - } - msev_pointer<_Ty>& operator=(_Ty* ptr) { - m_ptr = ptr; - return (*this); - } - bool operator==(const msev_pointer _Right_cref) const { return (_Right_cref.m_ptr == m_ptr); } - bool operator!=(const msev_pointer _Right_cref) const { return (!((*this) == _Right_cref)); } - bool operator==(const _Ty* _Right_cref) const { return (_Right_cref == m_ptr); } - bool operator!=(const _Ty* _Right_cref) const { return (!((*this) == _Right_cref)); } - - bool operator!() const { return (!m_ptr); } - operator bool() const { return (m_ptr != nullptr); } - - operator _Ty*() const { return m_ptr; } - - _Ty* m_ptr; - }; - -#ifndef _XSTD -#define _XSTD ::std:: -#endif /*_XSTD*/ - - template<class _Ty, _Ty _Val> - struct integral_constant - { // convenient template for integral constant types - static const _Ty value = _Val; - - typedef _Ty value_type; - typedef integral_constant<_Ty, _Val> type; - - operator value_type() const - { // return stored value - return (value); - } - }; - - template<class _Iter> - struct _mse_Is_iterator - : public integral_constant<bool, !std::is_integral<_Iter>::value> - { // tests for reasonable iterator candidate - }; - template<typename _InIter> - using _mse_RequireInputIter = typename std::enable_if< - std::is_convertible<typename std::iterator_traits<_InIter>::iterator_category, std::input_iterator_tag>::value - //_mse_Is_iterator<_InIter>::value - >::type; - - /* Note that, at the moment, msevector inherits publicly from std::vector. This is not intended to be a permanent - characteristic of msevector and any reference to, or interpretation of, an msevector as an std::vector is (and has - always been) depricated. msevector endeavors to support the subset of the std::vector interface that is compatible - with the security/safety goals of msevector. (The remaining part of the std::vector interface may be supported, as a - user option, for compatibility.) - In particular, keep in mind that std::vector does not have a virtual destructor, so deallocating an msevector as an - std::vector would result in memory leaks. */ - template<class _Ty, class _A = std::allocator<_Ty> > - class msevector : public std::vector<_Ty, _A> { - public: - typedef std::vector<_Ty, _A> base_class; - typedef msevector<_Ty, _A> _Myt; - - typedef typename base_class::value_type value_type; - //typedef typename base_class::size_type size_type; - typedef msev_size_t size_type; - //typedef typename base_class::difference_type difference_type; - typedef msev_int difference_type; - typedef typename base_class::pointer pointer; - typedef typename base_class::const_pointer const_pointer; - typedef typename base_class::reference reference; - typedef typename base_class::const_reference const_reference; - - explicit msevector(const _A& _Al = _A()) - : base_class(_Al), m_mmitset(*this) { - /*m_debug_size = size();*/ - } - explicit msevector(size_type _N) - : base_class(msev_as_a_size_t(_N)), m_mmitset(*this) { - /*m_debug_size = size();*/ - } - explicit msevector(size_type _N, const _Ty& _V, const _A& _Al = _A()) - : base_class(msev_as_a_size_t(_N), _V, _Al), m_mmitset(*this) { - /*m_debug_size = size();*/ - } - msevector(base_class&& _X) : base_class(std::move(_X)), m_mmitset(*this) { /*m_debug_size = size();*/ } - msevector(const base_class& _X) : base_class(_X), m_mmitset(*this) { /*m_debug_size = size();*/ } - msevector(_Myt&& _X) : base_class(std::move(_X)), m_mmitset(*this) { /*m_debug_size = size();*/ } - msevector(const _Myt& _X) : base_class(_X), m_mmitset(*this) { /*m_debug_size = size();*/ } - typedef typename base_class::const_iterator _It; - /* Note that safety cannot be guaranteed when using these constructors that take unsafe typename base_class::iterator and/or pointer parameters. */ - msevector(_It _F, _It _L, const _A& _Al = _A()) : base_class(_F, _L, _Al), m_mmitset(*this) { /*m_debug_size = size();*/ } - msevector(const _Ty* _F, const _Ty* _L, const _A& _Al = _A()) : base_class(_F, _L, _Al), m_mmitset(*this) { /*m_debug_size = size();*/ } - template<class _Iter - //, class = typename std::enable_if<_mse_Is_iterator<_Iter>::value, void>::type - , class = _mse_RequireInputIter<_Iter> > - msevector(_Iter _First, _Iter _Last) : base_class(_First, _Last), m_mmitset(*this) { /*m_debug_size = size();*/ } - template<class _Iter - //, class = typename std::enable_if<_mse_Is_iterator<_Iter>::value, void>::type - , class = _mse_RequireInputIter<_Iter> > - //msevector(_Iter _First, _Iter _Last, const typename base_class::_Alloc& _Al) : base_class(_First, _Last, _Al), m_mmitset(*this) { /*m_debug_size = size();*/ } - msevector(_Iter _First, _Iter _Last, const _A& _Al) : base_class(_First, _Last, _Al), m_mmitset(*this) { /*m_debug_size = size();*/ } - _Myt& operator=(const base_class& _X) { - base_class::operator =(_X); - /*m_debug_size = size();*/ - m_mmitset.reset(); - return (*this); - } - _Myt& operator=(_Myt&& _X) { - operator=(std::move(static_cast<base_class&>(_X))); - m_mmitset.reset(); - return (*this); - } - _Myt& operator=(const _Myt& _X) { - operator=(static_cast<const base_class&>(_X)); - m_mmitset.reset(); - return (*this); - } - void reserve(size_type _Count) - { // determine new minimum length of allocated storage - auto original_capacity = msev_size_t((*this).capacity()); - - base_class::reserve(msev_as_a_size_t(_Count)); - - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - } - void shrink_to_fit() { // reduce capacity - auto original_capacity = msev_size_t((*this).capacity()); - - base_class::shrink_to_fit(); - - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - } - void resize(size_type _N, const _Ty& _X = _Ty()) { - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - bool shrinking = (_N < original_size); - - base_class::resize(msev_as_a_size_t(_N), _X); - /*m_debug_size = size();*/ - - if (shrinking) { - m_mmitset.invalidate_inclusive_range(_N, msev_size_t(original_size - 1)); - } - m_mmitset.shift_inclusive_range(original_size, original_size, msev_size_t(_N) - original_size); /*shift the end markers*/ - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - } - typename base_class::const_reference operator[](size_type _P) const { - return (*this).at(msev_as_a_size_t(_P)); - } - typename base_class::reference operator[](size_type _P) { - return (*this).at(msev_as_a_size_t(_P)); - } - typename base_class::reference front() { // return first element of mutable sequence - if (0 == (*this).size()) { MSE_THROW(msevector_range_error("front() on empty - typename base_class::reference front() - msevector")); } - return base_class::front(); - } - typename base_class::const_reference front() const { // return first element of nonmutable sequence - if (0 == (*this).size()) { MSE_THROW(msevector_range_error("front() on empty - typename base_class::const_reference front() - msevector")); } - return base_class::front(); - } - typename base_class::reference back() { // return last element of mutable sequence - if (0 == (*this).size()) { MSE_THROW(msevector_range_error("back() on empty - typename base_class::reference back() - msevector")); } - return base_class::back(); - } - typename base_class::const_reference back() const { // return last element of nonmutable sequence - if (0 == (*this).size()) { MSE_THROW(msevector_range_error("back() on empty - typename base_class::const_reference back() - msevector")); } - return base_class::back(); - } - void push_back(_Ty&& _X) { - if (m_mmitset.is_empty()) { - base_class::push_back(std::move(_X)); - } - else { - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - base_class::push_back(std::move(_X)); - /*m_debug_size = size();*/ - - assert((original_size + 1) == msev_size_t((*this).size())); - m_mmitset.shift_inclusive_range(original_size, original_size, 1); /*shift the end markers*/ - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - } - } - void push_back(const _Ty& _X) { - if (m_mmitset.is_empty()) { - base_class::push_back(_X); - } - else { - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - base_class::push_back(_X); - /*m_debug_size = size();*/ - - assert((original_size + 1) == msev_size_t((*this).size())); - m_mmitset.shift_inclusive_range(original_size, original_size, 1); /*shift the end markers*/ - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - } - } - void pop_back() { - if (m_mmitset.is_empty()) { - base_class::pop_back(); - } - else { - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - if (0 == original_size) { MSE_THROW(msevector_range_error("pop_back() on empty - void pop_back() - msevector")); } - base_class::pop_back(); - /*m_debug_size = size();*/ - - assert((original_size - 1) == msev_size_t((*this).size())); - m_mmitset.invalidate_inclusive_range(msev_size_t(original_size - 1), msev_size_t(original_size - 1)); - m_mmitset.shift_inclusive_range(original_size, original_size, -1); /*shift the end markers*/ - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - } - } - void assign(_It _F, _It _L) { - base_class::assign(_F, _L); - /*m_debug_size = size();*/ - m_mmitset.reset(); - } - template<class _Iter> - void assign(_Iter _First, _Iter _Last) { // assign [_First, _Last) - base_class::assign(_First, _Last); - /*m_debug_size = size();*/ - m_mmitset.reset(); - } - void assign(size_type _N, const _Ty& _X = _Ty()) { - base_class::assign(msev_as_a_size_t(_N), _X); - /*m_debug_size = size();*/ - m_mmitset.reset(); - } - typename base_class::iterator insert(typename base_class::const_iterator _P, _Ty&& _X) { - return (emplace(_P, std::move(_X))); - } - typename base_class::iterator insert(typename base_class::const_iterator _P, const _Ty& _X = _Ty()) { - if (m_mmitset.is_empty()) { - typename base_class::iterator retval = base_class::insert(_P, _X); - /*m_debug_size = size();*/ - return retval; - } - else { - msev_int di = std::distance(base_class::cbegin(), _P); - msev_size_t d = msev_size_t(di); - if ((0 > di) || (msev_size_t((*this).size()) < di)) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator insert() - msevector")); } - - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - typename base_class::iterator retval = base_class::insert(_P, _X); - /*m_debug_size = size();*/ - - assert((original_size + 1) == msev_size_t((*this).size())); - assert(di == std::distance(base_class::begin(), retval)); - m_mmitset.shift_inclusive_range(d, original_size, 1); - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - return retval; - } - } - -#if !(defined(GPP4P8_COMPATIBLE)) - typename base_class::iterator insert(typename base_class::const_iterator _P, size_type _M, const _Ty& _X) { - if (m_mmitset.is_empty()) { - typename base_class::iterator retval = base_class::insert(_P, msev_as_a_size_t(_M), _X); - /*m_debug_size = size();*/ - return retval; - } - else { - msev_int di = std::distance(base_class::cbegin(), _P); - msev_size_t d = msev_size_t(di); - if ((0 > di) || ((*this).size() < msev_size_t(di))) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator insert() - msevector")); } - - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - typename base_class::iterator retval = base_class::insert(_P, msev_as_a_size_t(_M), _X); - /*m_debug_size = size();*/ - - assert((original_size + _M) == msev_size_t((*this).size())); - assert(di == std::distance(base_class::begin(), retval)); - m_mmitset.shift_inclusive_range(d, original_size, msev_int(_M)); - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - return retval; - } - } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - typename base_class::iterator insert(typename base_class::const_iterator _Where, _Iter _First, _Iter _Last) { // insert [_First, _Last) at _Where - if (m_mmitset.is_empty()) { - auto retval = base_class::insert(_Where, _First, _Last); - /*m_debug_size = size();*/ - return retval; - } - else { - msev_int di = std::distance(base_class::cbegin(), _Where); - msev_size_t d = msev_size_t(di); - if ((0 > di) || ((*this).size() < msev_size_t(di))) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator insert() - msevector")); } - - auto _M = msev_int(std::distance(_First, _Last)); - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - //if (0 > _M) { MSE_THROW(msevector_range_error("invalid argument - typename base_class::iterator insert() - msevector")); } - auto retval = base_class::insert(_Where, _First, _Last); - /*m_debug_size = size();*/ - - assert((original_size + _M) == msev_size_t((*this).size())); - assert(di == std::distance(base_class::begin(), retval)); - m_mmitset.shift_inclusive_range(d, original_size, _M); - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - return retval; - } - } - -#else /*!(defined(GPP4P8_COMPATIBLE))*/ - - /*typename base_class::iterator*/ - void - /* g++4.8 seems to be using the c++98 version of this insert function instead of the c++11 version. */ - insert(typename base_class::/*const_*/iterator _P, size_t _M, const _Ty& _X) { - msev_int di = std::distance(base_class::/*c*/begin(), _P); - msev_size_t d = msev_size_t(di); - if ((0 > di) || (msev_size_t((*this).size()) < di)) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator insert() - msevector")); } - - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - /*typename base_class::iterator retval =*/ - base_class::insert(_P, _M, _X); - /*m_debug_size = size();*/ - - assert((original_size + _M) == msev_size_t((*this).size())); - /*assert(di == std::distance(base_class::begin(), retval));*/ - m_mmitset.shift_inclusive_range(d, original_size, _M); - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - /*return retval;*/ - } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, void>::type - , class = _mse_RequireInputIter<_Iter> > void - insert(typename base_class::/*const_*/iterator _Where, _Iter _First, _Iter _Last) { // insert [_First, _Last) at _Where - msev_int di = std::distance(base_class::/*c*/begin(), _Where); - msev_size_t d = msev_size_t(di); - if ((0 > di) || (msev_size_t((*this).size()) < di)) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator insert() - msevector")); } - - auto _M = msev_int(std::distance(_First, _Last)); - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - //if (0 > _M) { MSE_THROW(msevector_range_error("invalid argument - typename base_class::iterator insert() - msevector")); } - /*auto retval =*/ - base_class::insert(_Where, _First, _Last); - /*m_debug_size = size();*/ - - assert((original_size + _M) == msev_size_t((*this).size())); - /*assert(di == std::distance(base_class::begin(), retval));*/ - m_mmitset.shift_inclusive_range(d, original_size, _M); - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - /*return retval;*/ - } -#endif /*!(defined(GPP4P8_COMPATIBLE))*/ - - template<class ..._Valty> - void emplace_back(_Valty&& ..._Val) - { // insert by moving into element at end - if (m_mmitset.is_empty()) { - base_class::emplace_back(std::forward<_Valty>(_Val)...); - /*m_debug_size = size();*/ - } - else { - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - base_class::emplace_back(std::forward<_Valty>(_Val)...); - /*m_debug_size = size();*/ - - assert((original_size + 1) == msev_size_t((*this).size())); - m_mmitset.shift_inclusive_range(original_size, original_size, 1); /*shift the end markers*/ - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - } - } - template<class ..._Valty> -#if !(defined(GPP4P8_COMPATIBLE)) - typename base_class::iterator emplace(typename base_class::const_iterator _Where, _Valty&& ..._Val) - { // insert by moving _Val at _Where -#else /*!(defined(GPP4P8_COMPATIBLE))*/ - typename base_class::iterator emplace(typename base_class::/*const_*/iterator _Where, _Valty&& ..._Val) - { // insert by moving _Val at _Where -#endif /*!(defined(GPP4P8_COMPATIBLE))*/ - - if (m_mmitset.is_empty()) { - auto retval = base_class::emplace(_Where, std::forward<_Valty>(_Val)...); - /*m_debug_size = size();*/ - return retval; - } - else { - -#if !(defined(GPP4P8_COMPATIBLE)) - msev_int di = std::distance(base_class::cbegin(), _Where); -#else /*!(defined(GPP4P8_COMPATIBLE))*/ - msev_int di = std::distance(base_class::/*c*/begin(), _Where); -#endif /*!(defined(GPP4P8_COMPATIBLE))*/ - - msev_size_t d = msev_size_t(di); - if ((0 > di) || ((*this).size() < msev_size_t(di))) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator emplace() - msevector")); } - - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - auto retval = base_class::emplace(_Where, std::forward<_Valty>(_Val)...); - /*m_debug_size = size();*/ - - assert((original_size + 1) == msev_size_t((*this).size())); - assert(di == std::distance(base_class::begin(), retval)); - m_mmitset.shift_inclusive_range(d, original_size, 1); - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - return retval; - } - } - typename base_class::iterator erase(typename base_class::const_iterator _P) { - if (m_mmitset.is_empty()) { - typename base_class::iterator retval = base_class::erase(_P); - /*m_debug_size = size();*/ - return retval; - } - else { - msev_int di = std::distance(base_class::cbegin(), _P); - msev_size_t d = msev_size_t(di); - if ((0 > di) || ((*this).size() < msev_size_t(di))) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator erase() - msevector")); } - - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - if (base_class::end() == _P) { MSE_THROW(msevector_range_error("invalid argument - typename base_class::iterator erase(typename base_class::const_iterator _P) - msevector")); } - typename base_class::iterator retval = base_class::erase(_P); - /*m_debug_size = size();*/ - - assert((original_size - 1) == msev_size_t((*this).size())); - assert(di == std::distance(base_class::begin(), retval)); - { - m_mmitset.invalidate_inclusive_range(d, d); - m_mmitset.shift_inclusive_range(msev_size_t(d + 1), original_size, -1); - } - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - return retval; - } - } - typename base_class::iterator erase(typename base_class::const_iterator _F, typename base_class::const_iterator _L) { - if (m_mmitset.is_empty()) { - typename base_class::iterator retval = base_class::erase(_F, _L); - /*m_debug_size = size();*/ - return retval; - } - else { - msev_int di = std::distance(base_class::cbegin(), _F); - msev_size_t d = msev_size_t(di); - if ((0 > di) || ((*this).size() < msev_size_t(di))) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator erase() - msevector")); } - msev_int di2 = std::distance(base_class::cbegin(), _L); - msev_size_t d2 = msev_size_t(di2); - if ((0 > di2) || ((*this).size() < msev_size_t(di2))) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator erase() - msevector")); } - - auto _M = msev_int(std::distance(_F, _L)); - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - if ((base_class::end() == _F)/* || (0 > _M)*/) { MSE_THROW(msevector_range_error("invalid argument - typename base_class::iterator erase(typename base_class::iterator _F, typename base_class::iterator _L) - msevector")); } - typename base_class::iterator retval = base_class::erase(_F, _L); - /*m_debug_size = size();*/ - - assert((original_size - _M) == msev_size_t((*this).size())); - assert(di == std::distance(base_class::begin(), retval)); - { - if (1 <= _M) { - m_mmitset.invalidate_inclusive_range(d, msev_size_t(d + _M - 1)); - } - m_mmitset.shift_inclusive_range(msev_size_t(d + _M), original_size, -_M); - } - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - return retval; - } - } - void clear() { - base_class::clear(); - /*m_debug_size = size();*/ - m_mmitset.reset(); - } - void swap(base_class& _X) { - base_class::swap(_X); - /*m_debug_size = size();*/ - m_mmitset.reset(); - } - void swap(_Myt& _X) { - swap(static_cast<base_class&>(_X)); - m_mmitset.reset(); - } - - msevector(_XSTD initializer_list<typename base_class::value_type> _Ilist, - const _A& _Al = _A()) - : base_class(_Ilist, _Al), m_mmitset(*this) { // construct from initializer_list - /*m_debug_size = size();*/ - } - _Myt& operator=(_XSTD initializer_list<typename base_class::value_type> _Ilist) { // assign initializer_list - operator=(static_cast<base_class>(_Ilist)); - m_mmitset.reset(); - return (*this); - } - void assign(_XSTD initializer_list<typename base_class::value_type> _Ilist) { // assign initializer_list - base_class::assign(_Ilist); - /*m_debug_size = size();*/ - m_mmitset.reset(); - } -#if defined(GPP4P8_COMPATIBLE) - /* g++4.8 seems to be (incorrectly) using the c++98 version of this insert function instead of the c++11 version. */ - /*typename base_class::iterator*/void insert(typename base_class::/*const_*/iterator _Where, _XSTD initializer_list<typename base_class::value_type> _Ilist) { // insert initializer_list - msev_int di = std::distance(base_class::/*c*/begin(), _Where); - msev_size_t d = msev_size_t(di); - if ((0 > di) || (msev_size_t((*this).size()) < di)) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator insert() - msevector")); } - - auto _M = _Ilist.size(); - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - /*auto retval = */base_class::insert(_Where, _Ilist); - /*m_debug_size = size();*/ - - assert((original_size + _M) == msev_size_t((*this).size())); - /*assert(di == std::distance(base_class::begin(), retval));*/ - m_mmitset.shift_inclusive_range(d, original_size, _M); - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - /*return retval;*/ - } -#else /*defined(GPP4P8_COMPATIBLE)*/ - typename base_class::iterator insert(typename base_class::const_iterator _Where, _XSTD initializer_list<typename base_class::value_type> _Ilist) { // insert initializer_list - if (m_mmitset.is_empty()) { - auto retval = base_class::insert(_Where, _Ilist); - /*m_debug_size = size();*/ - return retval; - } - else { - msev_int di = std::distance(base_class::cbegin(), _Where); - msev_size_t d = msev_size_t(di); - if ((0 > di) || ((*this).size() < msev_size_t(di))) { MSE_THROW(msevector_range_error("index out of range - typename base_class::iterator insert() - msevector")); } - - auto _M = _Ilist.size(); - auto original_size = msev_size_t((*this).size()); - auto original_capacity = msev_size_t((*this).capacity()); - - auto retval = base_class::insert(_Where, _Ilist); - /*m_debug_size = size();*/ - - assert((original_size + _M) == msev_size_t((*this).size())); - assert(di == std::distance(base_class::begin(), retval)); - m_mmitset.shift_inclusive_range(d, original_size, msev_int(_M)); - auto new_capacity = msev_size_t((*this).capacity()); - bool realloc_occured = (new_capacity != original_capacity); - if (realloc_occured) { - m_mmitset.sync_iterators_to_index(); - } - return retval; - } - } -#endif /*defined(GPP4P8_COMPATIBLE)*/ - - //size_t m_debug_size; - - class random_access_const_iterator_base : public std::iterator<std::random_access_iterator_tag, value_type, difference_type, const_pointer, const_reference> {}; - class random_access_iterator_base : public std::iterator<std::random_access_iterator_tag, value_type, difference_type, pointer, reference> {}; - - /* mm_const_iterator_type acts much like a list iterator. */ - class mm_const_iterator_type : public random_access_const_iterator_base { - public: - typedef typename base_class::const_iterator::iterator_category iterator_category; - typedef typename base_class::const_iterator::value_type value_type; - //typedef typename base_class::const_iterator::difference_type difference_type; - typedef msev_int difference_type; - typedef difference_type distance_type; // retained - typedef typename base_class::const_iterator::pointer pointer; - typedef typename base_class::const_iterator::pointer const_pointer; - typedef typename base_class::const_iterator::reference reference; - typedef typename base_class::const_reference const_reference; - - void reset() { set_to_end_marker(); } - bool points_to_an_item() const { - if (m_points_to_an_item) { assert((1 <= m_owner_cptr->size()) && (m_index < m_owner_cptr->size())); return true; } - else { assert(!((1 <= m_owner_cptr->size()) && (m_index < m_owner_cptr->size()))); return false; } - } - bool points_to_end_marker() const { - if (false == points_to_an_item()) { assert(m_index == m_owner_cptr->size()); return true; } - else { return false; } - } - bool points_to_beginning() const { - if (0 == m_index) { return true; } - else { return false; } - } - /* has_next_item_or_end_marker() is just an alias for points_to_an_item(). */ - bool has_next_item_or_end_marker() const { return points_to_an_item(); } //his is - /* has_next() is just an alias for points_to_an_item() that's familiar to java programmers. */ - bool has_next() const { return has_next_item_or_end_marker(); } - bool has_previous() const { return (!points_to_beginning()); } - void set_to_beginning() { - m_index = 0; - if (1 <= m_owner_cptr->size()) { - m_points_to_an_item = true; - } - else { assert(false == m_points_to_an_item); } - } - void set_to_end_marker() { - m_index = m_owner_cptr->size(); - m_points_to_an_item = false; - } - void set_to_next() { - if (points_to_an_item()) { - m_index += 1; - if (m_owner_cptr->size() <= m_index) { - (*this).m_points_to_an_item = false; - if (m_owner_cptr->size() < m_index) { assert(false); reset(); } - } - } - else { - MSE_THROW(msevector_range_error("attempt to use invalid const_item_pointer - void set_to_next() - mm_const_iterator_type - msevector")); - } - } - void set_to_previous() { - if (has_previous()) { - m_index -= 1; - (*this).m_points_to_an_item = true; - } - else { - MSE_THROW(msevector_range_error("attempt to use invalid const_item_pointer - void set_to_previous() - mm_const_iterator_type - msevector")); - } - } - mm_const_iterator_type& operator ++() { (*this).set_to_next(); return (*this); } - mm_const_iterator_type operator++(int) { mm_const_iterator_type _Tmp = *this; ++*this; return (_Tmp); } - mm_const_iterator_type& operator --() { (*this).set_to_previous(); return (*this); } - mm_const_iterator_type operator--(int) { mm_const_iterator_type _Tmp = *this; --*this; return (_Tmp); } - void advance(difference_type n) { - auto new_index = msev_int(m_index) + n; - if ((0 > new_index) || (m_owner_cptr->size() < msev_size_t(new_index))) { - MSE_THROW(msevector_range_error("index out of range - void advance(difference_type n) - mm_const_iterator_type - msevector")); - } - else { - m_index = msev_size_t(new_index); - if (m_owner_cptr->size() <= m_index) { - (*this).m_points_to_an_item = false; - } - else { - (*this).m_points_to_an_item = true; - } - } - } - void regress(difference_type n) { advance(-n); } - mm_const_iterator_type& operator +=(difference_type n) { (*this).advance(n); return (*this); } - mm_const_iterator_type& operator -=(difference_type n) { (*this).regress(n); return (*this); } - mm_const_iterator_type operator+(difference_type n) const { - mm_const_iterator_type retval(*this); - retval = (*this); - retval.advance(n); - return retval; - } - mm_const_iterator_type operator-(difference_type n) const { return ((*this) + (-n)); } - difference_type operator-(const mm_const_iterator_type &rhs) const { - if ((rhs.m_owner_cptr) != ((*this).m_owner_cptr)) { MSE_THROW(msevector_range_error("invalid argument - difference_type operator-(const mm_const_iterator_type &rhs) const - msevector::mm_const_iterator_type")); } - auto retval = difference_type((*this).m_index) - difference_type(rhs.m_index); - assert(difference_type(m_owner_cptr->size()) >= retval); - return retval; - } - const_reference operator*() const { - return m_owner_cptr->at(msev_as_a_size_t(m_index)); - } - const_reference item() const { return operator*(); } - const_reference previous_item() const { - return m_owner_cptr->at(msev_as_a_size_t(m_index - 1)); - } - const_pointer operator->() const { - return &(m_owner_cptr->at(msev_as_a_size_t(m_index))); - } - const_reference operator[](difference_type _Off) const { return (*m_owner_cptr).at(msev_as_a_size_t(difference_type(m_index) + _Off)); } - /* - mm_const_iterator_type& operator=(const typename base_class::const_iterator& _Right_cref) - { - msev_int d = std::distance<typename base_class::iterator>(m_owner_cptr->cbegin(), _Right_cref); - if ((0 <= d) && (m_owner_cptr->size() >= d)) { - if (m_owner_cptr->size() == d) { - assert(m_owner_cptr->cend() == _Right_cref); - m_points_to_an_item = false; - } else { - m_points_to_an_item = true; - } - m_index = msev_size_t(d); - base_class::const_iterator::operator=(_Right_cref); - } - else { - MSE_THROW(msevector_range_error("doesn't seem to be a valid assignment value - mm_const_iterator_type& operator=(const typename base_class::const_iterator& _Right_cref) - mm_const_iterator_type - msevector")); - } - return (*this); - } - */ - mm_const_iterator_type& operator=(const mm_const_iterator_type& _Right_cref) - { - if (((*this).m_owner_cptr) == (_Right_cref.m_owner_cptr)) { - assert((*this).m_owner_cptr->size() >= _Right_cref.m_index); - (*this).m_points_to_an_item = _Right_cref.m_points_to_an_item; - (*this).m_index = _Right_cref.m_index; - } - else { - MSE_THROW(msevector_range_error("doesn't seem to be a valid assignment value - mm_const_iterator_type& operator=(const typename base_class::iterator& _Right_cref) - mm_const_iterator_type - msevector")); - } - return (*this); - } - bool operator==(const mm_const_iterator_type& _Right_cref) const { - if (((*this).m_owner_cptr) != (_Right_cref.m_owner_cptr)) { MSE_THROW(msevector_range_error("invalid argument - mm_const_iterator_type& operator==(const mm_const_iterator_type& _Right) - mm_const_iterator_type - msevector")); } - return (_Right_cref.m_index == m_index); - } - bool operator!=(const mm_const_iterator_type& _Right_cref) const { return (!(_Right_cref == (*this))); } - bool operator<(const mm_const_iterator_type& _Right) const { - if (((*this).m_owner_cptr) != (_Right.m_owner_cptr)) { MSE_THROW(msevector_range_error("invalid argument - mm_const_iterator_type& operator<(const mm_const_iterator_type& _Right) - mm_const_iterator_type - msevector")); } - return (m_index < _Right.m_index); - } - bool operator<=(const mm_const_iterator_type& _Right) const { return (((*this) < _Right) || (_Right == (*this))); } - bool operator>(const mm_const_iterator_type& _Right) const { return (!((*this) <= _Right)); } - bool operator>=(const mm_const_iterator_type& _Right) const { return (!((*this) < _Right)); } - void set_to_const_item_pointer(const mm_const_iterator_type& _Right_cref) { - (*this) = _Right_cref; - } - void invalidate_inclusive_range(msev_size_t index_of_first, msev_size_t index_of_last) { - if ((index_of_first <= (*this).m_index) && (index_of_last >= (*this).m_index)) { - (*this).reset(); - } - } - void shift_inclusive_range(msev_size_t index_of_first, msev_size_t index_of_last, msev_int shift) { - if ((index_of_first <= (*this).m_index) && (index_of_last >= (*this).m_index)) { - auto new_index = (*this).m_index + shift; - if ((0 > new_index) || (m_owner_cptr->size() < new_index)) { - MSE_THROW(msevector_range_error("void shift_inclusive_range() - mm_const_iterator_type - msevector")); - } - else { - (*this).m_index = msev_size_t(new_index); - (*this).sync_const_iterator_to_index(); - } - } - } - msev_size_t position() const { - return m_index; - } - operator typename base_class::const_iterator() const { - typename base_class::const_iterator retval = (*m_owner_cptr).cbegin(); - retval += msev_as_a_size_t(m_index); - return retval; - } - - /* We actually want to make this constructor private, but doing so seems to break std::make_shared<mm_const_iterator_type>. */ - mm_const_iterator_type(const _Myt& owner_cref) : m_owner_cptr(&owner_cref) { set_to_beginning(); } - private: - mm_const_iterator_type(const mm_const_iterator_type& src_cref) : m_owner_cptr(src_cref.m_owner_cptr) { (*this) = src_cref; } - void sync_const_iterator_to_index() { - assert(m_owner_cptr->size() >= (*this).m_index); - } - msev_bool m_points_to_an_item = false; - msev_size_t m_index = 0; - const _Myt* m_owner_cptr = nullptr; - friend class mm_iterator_set_type; - friend class /*_Myt*/msevector<_Ty, _A>; - friend class mm_iterator_type; - }; - /* mm_iterator_type acts much like a list iterator. */ - class mm_iterator_type : random_access_iterator_base { - public: - typedef typename base_class::iterator::iterator_category iterator_category; - typedef typename base_class::iterator::value_type value_type; - //typedef typename base_class::iterator::difference_type difference_type; - typedef msev_int difference_type; - typedef difference_type distance_type; // retained - typedef typename base_class::iterator::pointer pointer; - typedef typename base_class::iterator::reference reference; - - void reset() { set_to_end_marker(); } - bool points_to_an_item() const { - if (m_points_to_an_item) { assert((1 <= m_owner_ptr->size()) && (m_index < m_owner_ptr->size())); return true; } - else { assert(!((1 <= m_owner_ptr->size()) && (m_index < m_owner_ptr->size()))); return false; } - } - bool points_to_end_marker() const { - if (false == points_to_an_item()) { assert(m_index == m_owner_ptr->size()); return true; } - else { return false; } - } - bool points_to_beginning() const { - if (0 == m_index) { return true; } - else { return false; } - } - /* has_next_item_or_end_marker() is just an alias for points_to_an_item(). */ - bool has_next_item_or_end_marker() const { return points_to_an_item(); } - /* has_next() is just an alias for points_to_an_item() that's familiar to java programmers. */ - bool has_next() const { return has_next_item_or_end_marker(); } - bool has_previous() const { return (!points_to_beginning()); } - void set_to_beginning() { - m_index = 0; - if (1 <= m_owner_ptr->size()) { - m_points_to_an_item = true; - } - else { assert(false == m_points_to_an_item); } - } - void set_to_end_marker() { - m_index = m_owner_ptr->size(); - m_points_to_an_item = false; - } - void set_to_next() { - if (points_to_an_item()) { - m_index += 1; - if (m_owner_ptr->size() <= m_index) { - (*this).m_points_to_an_item = false; - if (m_owner_ptr->size() < m_index) { assert(false); reset(); } - } - } - else { - MSE_THROW(msevector_range_error("attempt to use invalid item_pointer - void set_to_next() - mm_const_iterator_type - msevector")); - } - } - void set_to_previous() { - if (has_previous()) { - m_index -= 1; - (*this).m_points_to_an_item = true; - } - else { - MSE_THROW(msevector_range_error("attempt to use invalid item_pointer - void set_to_previous() - mm_iterator_type - msevector")); - } - } - mm_iterator_type& operator ++() { (*this).set_to_next(); return (*this); } - mm_iterator_type operator++(int) { mm_iterator_type _Tmp = *this; ++*this; return (_Tmp); } - mm_iterator_type& operator --() { (*this).set_to_previous(); return (*this); } - mm_iterator_type operator--(int) { mm_iterator_type _Tmp = *this; --*this; return (_Tmp); } - void advance(difference_type n) { - auto new_index = msev_int(m_index) + n; - if ((0 > new_index) || (m_owner_ptr->size() < msev_size_t(new_index))) { - MSE_THROW(msevector_range_error("index out of range - void advance(difference_type n) - mm_iterator_type - msevector")); - } - else { - m_index = msev_size_t(new_index); - if (m_owner_ptr->size() <= m_index) { - (*this).m_points_to_an_item = false; - } - else { - (*this).m_points_to_an_item = true; - } - } - } - void regress(int n) { advance(-n); } - mm_iterator_type& operator +=(difference_type n) { (*this).advance(n); return (*this); } - mm_iterator_type& operator -=(difference_type n) { (*this).regress(n); return (*this); } - mm_iterator_type operator+(difference_type n) const { - mm_iterator_type retval(*this); - retval = (*this); - retval.advance(n); - return retval; - } - mm_iterator_type operator-(difference_type n) const { return ((*this) + (-n)); } - difference_type operator-(const mm_iterator_type& rhs) const { - if ((rhs.m_owner_ptr) != ((*this).m_owner_ptr)) { MSE_THROW(msevector_range_error("invalid argument - difference_type operator-(const mm_iterator_type& rhs) const - msevector::mm_iterator_type")); } - auto retval = difference_type((*this).m_index) - difference_type(rhs.m_index); - assert(difference_type(m_owner_ptr->size()) >= retval); - return retval; - } - reference operator*() const { - return m_owner_ptr->at(msev_as_a_size_t(m_index)); - } - reference item() const { return operator*(); } - reference previous_item() const { - return m_owner_ptr->at(msev_as_a_size_t(m_index - 1)); - } - pointer operator->() const { - return &(m_owner_ptr->at(msev_as_a_size_t(m_index))); - } - reference operator[](difference_type _Off) const { return (*m_owner_ptr).at(msev_as_a_size_t(difference_type(m_index) + _Off)); } - /* - mm_iterator_type& operator=(const typename base_class::iterator& _Right_cref) - { - msev_int d = std::distance<typename base_class::iterator>(m_owner_ptr->begin(), _Right_cref); - if ((0 <= d) && (m_owner_ptr->size() >= d)) { - if (m_owner_ptr->size() == d) { - assert(m_owner_ptr->end() == _Right_cref); - m_points_to_an_item = false; - } else { - m_points_to_an_item = true; - } - m_index = msev_size_t(d); - base_class::iterator::operator=(_Right_cref); - } - else { - MSE_THROW(msevector_range_error("doesn't seem to be a valid assignment value - mm_iterator_type& operator=(const typename base_class::iterator& _Right_cref) - mm_const_iterator_type - msevector")); - } - return (*this); - } - */ - mm_iterator_type& operator=(const mm_iterator_type& _Right_cref) - { - if (((*this).m_owner_ptr) == (_Right_cref.m_owner_ptr)) { - assert((*this).m_owner_ptr->size() >= _Right_cref.m_index); - (*this).m_points_to_an_item = _Right_cref.m_points_to_an_item; - (*this).m_index = _Right_cref.m_index; - } - else { - MSE_THROW(msevector_range_error("doesn't seem to be a valid assignment value - mm_iterator_type& operator=(const typename base_class::iterator& _Right_cref) - mm_const_iterator_type - msevector")); - } - return (*this); - } - bool operator==(const mm_iterator_type& _Right_cref) const { - if (((*this).m_owner_ptr) != (_Right_cref.m_owner_ptr)) { MSE_THROW(msevector_range_error("invalid argument - mm_iterator_type& operator==(const typename base_class::iterator& _Right) - mm_iterator_type - msevector")); } - return (_Right_cref.m_index == m_index); - } - bool operator!=(const mm_iterator_type& _Right_cref) const { return (!(_Right_cref == (*this))); } - bool operator<(const mm_iterator_type& _Right) const { - if (((*this).m_owner_ptr) != (_Right.m_owner_ptr)) { MSE_THROW(msevector_range_error("invalid argument - mm_iterator_type& operator<(const typename base_class::iterator& _Right) - mm_iterator_type - msevector")); } - return (m_index < _Right.m_index); - } - bool operator<=(const mm_iterator_type& _Right) const { return (((*this) < _Right) || (_Right == (*this))); } - bool operator>(const mm_iterator_type& _Right) const { return (!((*this) <= _Right)); } - bool operator>=(const mm_iterator_type& _Right) const { return (!((*this) < _Right)); } - void set_to_item_pointer(const mm_iterator_type& _Right_cref) { - (*this) = _Right_cref; - } - void invalidate_inclusive_range(msev_size_t index_of_first, msev_size_t index_of_last) { - if ((index_of_first <= (*this).m_index) && (index_of_last >= (*this).m_index)) { - (*this).reset(); - } - } - void shift_inclusive_range(msev_size_t index_of_first, msev_size_t index_of_last, msev_int shift) { - if ((index_of_first <= (*this).m_index) && (index_of_last >= (*this).m_index)) { - auto new_index = (*this).m_index + shift; - if ((0 > new_index) || (m_owner_ptr->size() < new_index)) { - MSE_THROW(msevector_range_error("void shift_inclusive_range() - mm_iterator_type - msevector")); - } - else { - (*this).m_index = msev_size_t(new_index); - (*this).sync_iterator_to_index(); - } - } - } - msev_size_t position() const { - return m_index; - } - operator mm_const_iterator_type() const { - mm_const_iterator_type retval(*m_owner_ptr); - retval.set_to_beginning(); - retval.advance(msev_int(m_index)); - return retval; - } - /* We actually want to make this constructor private, but doing so seems to break std::make_shared<mm_iterator_type>. */ - mm_iterator_type(_Myt& owner_ref) : m_owner_ptr(&owner_ref) { set_to_beginning(); } - private: - mm_iterator_type(const mm_iterator_type& src_cref) : m_owner_ptr(src_cref.m_owner_ptr) { (*this) = src_cref; } - void sync_iterator_to_index() { - assert(m_owner_ptr->size() >= (*this).m_index); - } - msev_bool m_points_to_an_item = false; - msev_size_t m_index = 0; - _Myt* m_owner_ptr = nullptr; - friend class mm_iterator_set_type; - friend class /*_Myt*/msevector<_Ty, _A>; - }; - - private: - typedef std::size_t CHashKey1; - class mm_const_iterator_handle_type { - public: - mm_const_iterator_handle_type(const CHashKey1& key_cref, const std::shared_ptr<mm_const_iterator_type>& shptr_cref) : m_shptr(shptr_cref), m_key(key_cref) {} - private: - std::shared_ptr<mm_const_iterator_type> m_shptr; - CHashKey1 m_key; - friend class /*_Myt*/msevector<_Ty, _A>; - friend class mm_iterator_set_type; - }; - class mm_iterator_handle_type { - public: - mm_iterator_handle_type(const CHashKey1& key_cref, const std::shared_ptr<mm_iterator_type>& shptr_ref) : m_shptr(shptr_ref), m_key(key_cref) {} - private: - std::shared_ptr<mm_iterator_type> m_shptr; - CHashKey1 m_key; - friend class /*_Myt*/msevector<_Ty, _A>; - friend class mm_iterator_set_type; - }; - - class mm_iterator_set_type { - public: - class CMMConstIterators : public std::unordered_map<CHashKey1, std::shared_ptr<mm_const_iterator_type>> {}; - class CMMIterators : public std::unordered_map<CHashKey1, std::shared_ptr<mm_iterator_type>> {}; - - class assignable_CMMConstIterators_value_type : public std::pair<CHashKey1, std::shared_ptr<mm_const_iterator_type>> { - public: - assignable_CMMConstIterators_value_type() {} - assignable_CMMConstIterators_value_type(const typename CMMConstIterators::value_type& src) : std::pair<CHashKey1, std::shared_ptr<mm_iterator_type>>(src.first, src.second) {} - assignable_CMMConstIterators_value_type& operator=(const typename CMMConstIterators::value_type& rhs) { (*this).first = rhs.first; (*this).second = rhs.second; return (*this); } - operator typename CMMConstIterators::value_type() const { return CMMConstIterators::value_type((*this).first, (*this).second); } - }; - class assignable_CMMIterators_value_type : public std::pair<CHashKey1, std::shared_ptr<mm_iterator_type>> { - public: - assignable_CMMIterators_value_type() {} - assignable_CMMIterators_value_type(const typename CMMIterators::value_type& src) : std::pair<CHashKey1, std::shared_ptr<mm_iterator_type>>(src.first, src.second) {} - assignable_CMMIterators_value_type& operator=(const typename CMMIterators::value_type& rhs) { (*this).first = rhs.first; (*this).second = rhs.second; return (*this); } - operator typename CMMIterators::value_type() const { return CMMIterators::value_type((*this).first, (*this).second); } - }; - - ~mm_iterator_set_type() { - if (!mm_const_fast_mode1()) { - delete m_aux_mm_const_iterator_shptrs_ptr; - } - if (!mm_fast_mode1()) { - delete m_aux_mm_iterator_shptrs_ptr; - } - } - - void apply_to_all_mm_const_iterator_shptrs(const std::function<void(std::shared_ptr<mm_const_iterator_type>&)>& func_obj_ref) { - if (!mm_const_fast_mode1()) { - for (auto it = (*m_aux_mm_const_iterator_shptrs_ptr).begin(); (*m_aux_mm_const_iterator_shptrs_ptr).end() != it; it++) { - func_obj_ref((*it).second); - } - } - else { - for (int i = 0; i < m_fm1_num_mm_const_iterators; i += 1) { - func_obj_ref(m_fm1_key_mm_const_it_array[i].second); - } - } - } - void apply_to_all_mm_iterator_shptrs(const std::function<void(std::shared_ptr<mm_iterator_type>&)>& func_obj_ref) { - if (!mm_fast_mode1()) { - for (auto it = (*m_aux_mm_iterator_shptrs_ptr).begin(); (*m_aux_mm_iterator_shptrs_ptr).end() != it; it++) { - func_obj_ref((*it).second); - } - } - else { - for (int i = 0; i < m_fm1_num_mm_iterators; i += 1) { - func_obj_ref(m_fm1_key_mm_it_array[i].second); - } - } - } - mm_iterator_set_type(_Myt& owner_ref) : m_next_available_key(0), m_owner_ptr(&owner_ref) {} - void reset() { - /* We can use "static" here because the lambda function does not capture any parameters. */ - static const std::function<void(std::shared_ptr<mm_const_iterator_type>&)> cit_func_obj = [](std::shared_ptr<mm_const_iterator_type>& a) { a->reset(); }; - apply_to_all_mm_const_iterator_shptrs(cit_func_obj); - static const std::function<void(std::shared_ptr<mm_iterator_type>&)> it_func_obj = [](std::shared_ptr<mm_iterator_type>& a) { a->reset(); }; - apply_to_all_mm_iterator_shptrs(it_func_obj); - } - void sync_iterators_to_index() { - /* No longer used. Relic from when mm_iterator_type contained a "native" iterator. */ - /* We can use "static" here because the lambda function does not capture any parameters. */ - /* - static const std::function<void(std::shared_ptr<mm_const_iterator_type>&)> cit_func_obj = [](std::shared_ptr<mm_const_iterator_type>& a) { a->sync_const_iterator_to_index(); }; - apply_to_all_mm_const_iterator_shptrs(cit_func_obj); - static const std::function<void(std::shared_ptr<mm_iterator_type>&)> it_func_obj = [](std::shared_ptr<mm_iterator_type>& a) { a->sync_iterator_to_index(); }; - apply_to_all_mm_iterator_shptrs(it_func_obj); - */ - } - void invalidate_inclusive_range(msev_size_t start_index, msev_size_t end_index) { - const std::function<void(std::shared_ptr<mm_const_iterator_type>&)> cit_func_obj = [start_index, end_index](std::shared_ptr<mm_const_iterator_type>& a) { a->invalidate_inclusive_range(start_index, end_index); }; - apply_to_all_mm_const_iterator_shptrs(cit_func_obj); - const std::function<void(std::shared_ptr<mm_iterator_type>&)> it_func_obj = [start_index, end_index](std::shared_ptr<mm_iterator_type>& a) { a->invalidate_inclusive_range(start_index, end_index); }; - apply_to_all_mm_iterator_shptrs(it_func_obj); - } - void shift_inclusive_range(msev_size_t start_index, msev_size_t end_index, msev_int shift) { - const std::function<void(std::shared_ptr<mm_const_iterator_type>&)> cit_func_obj = [start_index, end_index, shift](std::shared_ptr<mm_const_iterator_type>& a) { a->shift_inclusive_range(start_index, end_index, shift); }; - apply_to_all_mm_const_iterator_shptrs(cit_func_obj); - const std::function<void(std::shared_ptr<mm_iterator_type>&)> it_func_obj = [start_index, end_index, shift](std::shared_ptr<mm_iterator_type>& a) { a->shift_inclusive_range(start_index, end_index, shift); }; - apply_to_all_mm_iterator_shptrs(it_func_obj); - } - bool is_empty() const { - if (mm_const_fast_mode1()) { - if (1 <= m_fm1_num_mm_const_iterators) { - return false; - } - } - else { - if (1 <= m_aux_mm_const_iterator_shptrs_ptr->size()) { - return false; - } - } - if (mm_fast_mode1()) { - if (1 <= m_fm1_num_mm_iterators) { - return false; - } - } - else { - if (1 <= m_aux_mm_iterator_shptrs_ptr->size()) { - return false; - } - } - return true; - } - - mm_const_iterator_handle_type allocate_new_const_item_pointer() { - //auto shptr = std::shared_ptr<mm_const_iterator_type>(new mm_const_iterator_type(*m_owner_ptr)); - auto shptr = std::make_shared<mm_const_iterator_type>(*m_owner_ptr); - auto key = m_next_available_key; m_next_available_key++; - mm_const_iterator_handle_type retval(key, shptr); - typename CMMConstIterators::value_type new_item(key, shptr); - if (!mm_const_fast_mode1()) { - (*m_aux_mm_const_iterator_shptrs_ptr).insert(new_item); - } else { - if (sc_fm1_max_mm_iterators == m_fm1_num_mm_const_iterators) { - /* Too many items. Initiate and switch to slow mode. */ - /* Initialize slow storage. */ - m_aux_mm_const_iterator_shptrs_ptr = new CMMConstIterators(); - /* First copy the items from fast storage to slow storage. */ - for (int i = 0; i < sc_fm1_max_mm_iterators; i += 1) { - (*m_aux_mm_const_iterator_shptrs_ptr).insert(m_fm1_key_mm_const_it_array[i]); - } - /* Add the new items to slow storage. */ - (*m_aux_mm_const_iterator_shptrs_ptr).insert(new_item); - } - else { - m_fm1_key_mm_const_it_array[m_fm1_num_mm_const_iterators] = new_item; - m_fm1_num_mm_const_iterators += 1; - } - } - return retval; - } - void release_const_item_pointer(mm_const_iterator_handle_type handle) { - if (!mm_const_fast_mode1()) { - auto it = (*m_aux_mm_const_iterator_shptrs_ptr).find(handle.m_key); - if ((*m_aux_mm_const_iterator_shptrs_ptr).end() != it) { - (*m_aux_mm_const_iterator_shptrs_ptr).erase(it); - } - else { - /* Do we need to throw here? */ - MSE_THROW(msevector_range_error("invalid handle - void release_aux_mm_const_iterator(mm_const_iterator_handle_type handle) - msevector::mm_iterator_set_type")); - } - } - else { - int found_index = -1; - for (int i = 0; i < m_fm1_num_mm_const_iterators; i += 1) { - if (handle.m_key == m_fm1_key_mm_const_it_array[i].first) { - found_index = i; - break; - } - } - if (0 <= found_index) { - m_fm1_num_mm_const_iterators -= 1; - assert(0 <= m_fm1_num_mm_const_iterators); - for (int j = found_index; j < m_fm1_num_mm_const_iterators; j += 1) { - m_fm1_key_mm_const_it_array[j] = m_fm1_key_mm_const_it_array[j + 1]; - } - } - else { - /* Do we need to throw here? */ - MSE_THROW(msevector_range_error("invalid handle - void release_aux_mm_const_iterator(mm_const_iterator_handle_type handle) - msevector::mm_iterator_set_type")); - } - } - } - - mm_iterator_handle_type allocate_new_item_pointer() { - //auto shptr = std::shared_ptr<mm_iterator_type>(new mm_iterator_type(*m_owner_ptr)); - auto shptr = std::make_shared<mm_iterator_type>(*m_owner_ptr); - auto key = m_next_available_key; m_next_available_key++; - mm_iterator_handle_type retval(key, shptr); - typename CMMIterators::value_type new_item(key, shptr); - if (!mm_fast_mode1()) { - (*m_aux_mm_iterator_shptrs_ptr).insert(new_item); - } - else { - if (sc_fm1_max_mm_iterators == m_fm1_num_mm_iterators) { - /* Too many items. Initiate and switch to slow mode. */ - /* Initialize slow storage. */ - m_aux_mm_iterator_shptrs_ptr = new CMMIterators(); - /* First copy the items from fast storage to slow storage. */ - for (int i = 0; i < sc_fm1_max_mm_iterators; i += 1) { - (*m_aux_mm_iterator_shptrs_ptr).insert(m_fm1_key_mm_it_array[i]); - } - /* Add the new items to slow storage. */ - (*m_aux_mm_iterator_shptrs_ptr).insert(new_item); - } - else { - m_fm1_key_mm_it_array[m_fm1_num_mm_iterators] = new_item; - m_fm1_num_mm_iterators += 1; - } - } - return retval; - } - void release_item_pointer(mm_iterator_handle_type handle) { - if (!mm_fast_mode1()) { - auto it = (*m_aux_mm_iterator_shptrs_ptr).find(handle.m_key); - if ((*m_aux_mm_iterator_shptrs_ptr).end() != it) { - (*m_aux_mm_iterator_shptrs_ptr).erase(it); - } - else { - /* Do we need to throw here? */ - MSE_THROW(msevector_range_error("invalid handle - void release_aux_mm_iterator(mm_iterator_handle_type handle) - msevector::mm_iterator_set_type")); - } - } - else { - int found_index = -1; - for (int i = 0; i < m_fm1_num_mm_iterators; i += 1) { - if (handle.m_key == m_fm1_key_mm_it_array[i].first) { - found_index = i; - break; - } - } - if (0 <= found_index) { - m_fm1_num_mm_iterators -= 1; - assert(0 <= m_fm1_num_mm_iterators); - for (int j = found_index; j < m_fm1_num_mm_iterators; j += 1) { - m_fm1_key_mm_it_array[j] = m_fm1_key_mm_it_array[j + 1]; - } - } - else { - /* Do we need to throw here? */ - MSE_THROW(msevector_range_error("invalid handle - void release_aux_mm_iterator(mm_iterator_handle_type handle) - msevector::mm_iterator_set_type")); - } - } - } - void release_all_item_pointers() { - if (!mm_fast_mode1()) { - (*m_aux_mm_iterator_shptrs_ptr).clear(); - } - else { - for (int i = 0; i < m_fm1_num_mm_iterators; i += 1) { - m_fm1_key_mm_it_array[i] = assignable_CMMIterators_value_type(); - } - m_fm1_num_mm_iterators = 0; - } - } - mm_const_iterator_type &const_item_pointer(mm_const_iterator_handle_type handle) const { - return (*(handle.m_shptr)); - } - mm_iterator_type &item_pointer(mm_iterator_handle_type handle) { - return (*(handle.m_shptr)); - } - - private: - void release_all_const_item_pointers() { - if (!mm_const_fast_mode1()) { - (*m_aux_mm_const_iterator_shptrs_ptr).clear(); - } - else { - for (int i = 0; i < m_fm1_num_mm_const_iterators; i += 1) { - m_fm1_key_mm_const_it_array[i] = assignable_CMMConstIterators_value_type(); - } - m_fm1_num_mm_const_iterators = 0; - } - } - - mm_iterator_set_type& operator=(const mm_iterator_set_type& src_cref) { - /* This is a special type of class. The state (i.e. member values) of an object of this class is specific to (and only - valid for) the particular instance of the object (or the object of which it is a member). So the correct state of a new - copy of this type of object is not a copy of the state, but rather the state of a new object (which is just the default - initialization state). */ - (*this).reset(); - return (*this); - } - mm_iterator_set_type& operator=(mm_iterator_set_type&& src) { /* see above */ (*this).reset(); return (*this); } - mm_iterator_set_type(const mm_iterator_set_type& src) { /* see above */ } - mm_iterator_set_type(const mm_iterator_set_type&& src) { /* see above */ } - - CHashKey1 m_next_available_key = 0; - - static const int sc_fm1_max_mm_iterators = 6/*arbitrary*/; - - bool mm_const_fast_mode1() const { return (nullptr == m_aux_mm_const_iterator_shptrs_ptr); } - int m_fm1_num_mm_const_iterators = 0; - assignable_CMMConstIterators_value_type m_fm1_key_mm_const_it_array[sc_fm1_max_mm_iterators]; - CMMConstIterators* m_aux_mm_const_iterator_shptrs_ptr = nullptr; - - bool mm_fast_mode1() const { return (nullptr == m_aux_mm_iterator_shptrs_ptr); } - int m_fm1_num_mm_iterators = 0; - assignable_CMMIterators_value_type m_fm1_key_mm_it_array[sc_fm1_max_mm_iterators]; - CMMIterators* m_aux_mm_iterator_shptrs_ptr = nullptr; - - _Myt* m_owner_ptr = nullptr; - - friend class /*_Myt*/msevector<_Ty, _A>; - }; - mutable mm_iterator_set_type m_mmitset; - - public: - mm_const_iterator_type &const_item_pointer(mm_const_iterator_handle_type handle) const { - return m_mmitset.const_item_pointer(handle); - } - mm_iterator_type &item_pointer(mm_iterator_handle_type handle) { - return m_mmitset.item_pointer(handle); - } - - private: - mm_const_iterator_handle_type allocate_new_const_item_pointer() const { return m_mmitset.allocate_new_const_item_pointer(); } - void release_const_item_pointer(mm_const_iterator_handle_type handle) const { m_mmitset.release_const_item_pointer(handle); } - void release_all_const_item_pointers() const { m_mmitset.release_all_const_item_pointers(); } - mm_iterator_handle_type allocate_new_item_pointer() const { return m_mmitset.allocate_new_item_pointer(); } - void release_item_pointer(mm_iterator_handle_type handle) const { m_mmitset.release_item_pointer(handle); } - void release_all_item_pointers() const { m_mmitset.release_all_item_pointers(); } - - public: - class cipointer : public random_access_const_iterator_base { - public: - typedef typename mm_const_iterator_type::iterator_category iterator_category; - typedef typename mm_const_iterator_type::value_type value_type; - typedef typename mm_const_iterator_type::difference_type difference_type; - typedef difference_type distance_type; // retained - typedef typename mm_const_iterator_type::pointer pointer; - typedef typename mm_const_iterator_type::const_pointer const_pointer; - typedef typename mm_const_iterator_type::reference reference; - typedef typename mm_const_iterator_type::const_reference const_reference; - - cipointer(const _Myt& owner_cref) : m_owner_cptr(&owner_cref) { - mm_const_iterator_handle_type handle = m_owner_cptr->allocate_new_const_item_pointer(); - m_handle_shptr = std::make_shared<mm_const_iterator_handle_type>(handle); - } - cipointer(const cipointer& src_cref) : m_owner_cptr(src_cref.m_owner_cptr) { - mm_const_iterator_handle_type handle = m_owner_cptr->allocate_new_const_item_pointer(); - m_handle_shptr = std::make_shared<mm_const_iterator_handle_type>(handle); - const_item_pointer() = src_cref.const_item_pointer(); - } - ~cipointer() { - m_owner_cptr->release_const_item_pointer(*m_handle_shptr); - } - mm_const_iterator_type& const_item_pointer() const { return m_owner_cptr->const_item_pointer(*m_handle_shptr); } - mm_const_iterator_type& cip() const { return const_item_pointer(); } - //const mm_const_iterator_handle_type& handle() const { return (*m_handle_shptr); } - - void reset() { const_item_pointer().reset(); } - bool points_to_an_item() const { return const_item_pointer().points_to_an_item(); } - bool points_to_end_marker() const { return const_item_pointer().points_to_end_marker(); } - bool points_to_beginning() const { return const_item_pointer().points_to_beginning(); } - /* has_next_item_or_end_marker() is just an alias for points_to_an_item(). */ - bool has_next_item_or_end_marker() const { return const_item_pointer().has_next_item_or_end_marker(); } - /* has_next() is just an alias for points_to_an_item() that's familiar to java programmers. */ - bool has_next() const { return const_item_pointer().has_next(); } - bool has_previous() const { return const_item_pointer().has_previous(); } - void set_to_beginning() { const_item_pointer().set_to_beginning(); } - void set_to_end_marker() { const_item_pointer().set_to_end_marker(); } - void set_to_next() { const_item_pointer().set_to_next(); } - void set_to_previous() { const_item_pointer().set_to_previous(); } - cipointer& operator ++() { const_item_pointer().operator ++(); return (*this); } - cipointer operator++(int) { cipointer _Tmp = *this; ++*this; return (_Tmp); } - cipointer& operator --() { const_item_pointer().operator --(); return (*this); } - cipointer operator--(int) { cipointer _Tmp = *this; --*this; return (_Tmp); } - void advance(difference_type n) { const_item_pointer().advance(n); } - void regress(difference_type n) { const_item_pointer().regress(n); } - cipointer& operator +=(difference_type n) { const_item_pointer().operator +=(n); return (*this); } - cipointer& operator -=(difference_type n) { const_item_pointer().operator -=(n); return (*this); } - cipointer operator+(difference_type n) const { auto retval = (*this); retval += n; return retval; } - cipointer operator-(difference_type n) const { return ((*this) + (-n)); } - difference_type operator-(const cipointer& _Right_cref) const { return const_item_pointer() - (_Right_cref.const_item_pointer()); } - const_reference operator*() const { return const_item_pointer().operator*(); } - const_reference item() const { return operator*(); } - const_reference previous_item() const { return const_item_pointer().previous_item(); } - const_pointer operator->() const { return const_item_pointer().operator->(); } - const_reference operator[](difference_type _Off) const { return const_item_pointer()[_Off]; } - cipointer& operator=(const cipointer& _Right_cref) { const_item_pointer().operator=(_Right_cref.const_item_pointer()); return (*this); } - bool operator==(const cipointer& _Right_cref) const { return const_item_pointer().operator==(_Right_cref.const_item_pointer()); } - bool operator!=(const cipointer& _Right_cref) const { return (!(_Right_cref == (*this))); } - bool operator<(const cipointer& _Right) const { return (const_item_pointer() < _Right.const_item_pointer()); } - bool operator<=(const cipointer& _Right) const { return (const_item_pointer() <= _Right.const_item_pointer()); } - bool operator>(const cipointer& _Right) const { return (const_item_pointer() > _Right.const_item_pointer()); } - bool operator>=(const cipointer& _Right) const { return (const_item_pointer() >= _Right.const_item_pointer()); } - void set_to_const_item_pointer(const cipointer& _Right_cref) { const_item_pointer().set_to_const_item_pointer(_Right_cref.const_item_pointer()); } - msev_size_t position() const { return const_item_pointer().position(); } - private: - const _Myt* m_owner_cptr = nullptr; - std::shared_ptr<mm_const_iterator_handle_type> m_handle_shptr; - friend class /*_Myt*/msevector<_Ty, _A>; - }; - class ipointer : public random_access_iterator_base { - public: - typedef typename mm_iterator_type::iterator_category iterator_category; - typedef typename mm_iterator_type::value_type value_type; - typedef typename mm_iterator_type::difference_type difference_type; - typedef difference_type distance_type; // retained - typedef typename mm_iterator_type::pointer pointer; - typedef typename mm_iterator_type::reference reference; - - ipointer(_Myt& owner_ref) : m_owner_ptr(&owner_ref) { - mm_iterator_handle_type handle = m_owner_ptr->allocate_new_item_pointer(); - m_handle_shptr = std::make_shared<mm_iterator_handle_type>(handle); - } - ipointer(const ipointer& src_cref) : m_owner_ptr(src_cref.m_owner_ptr) { - mm_iterator_handle_type handle = m_owner_ptr->allocate_new_item_pointer(); - m_handle_shptr = std::make_shared<mm_iterator_handle_type>(handle); - item_pointer() = src_cref.item_pointer(); - } - ~ipointer() { - m_owner_ptr->release_item_pointer(*m_handle_shptr); - } - mm_iterator_type& item_pointer() const { return m_owner_ptr->item_pointer(*m_handle_shptr); } - mm_iterator_type& ip() const { return item_pointer(); } - //const mm_iterator_handle_type& handle() const { return (*m_handle_shptr); } - operator cipointer() const { - cipointer retval(*m_owner_ptr); - retval.const_item_pointer().set_to_beginning(); - retval.const_item_pointer().advance(msev_int(item_pointer().position())); - return retval; - } - - void reset() { item_pointer().reset(); } - bool points_to_an_item() const { return item_pointer().points_to_an_item(); } - bool points_to_end_marker() const { return item_pointer().points_to_end_marker(); } - bool points_to_beginning() const { return item_pointer().points_to_beginning(); } - /* has_next_item_or_end_marker() is just an alias for points_to_an_item(). */ - bool has_next_item_or_end_marker() const { return item_pointer().has_next_item_or_end_marker(); } - /* has_next() is just an alias for points_to_an_item() that's familiar to java programmers. */ - bool has_next() const { return item_pointer().has_next(); } - bool has_previous() const { return item_pointer().has_previous(); } - void set_to_beginning() { item_pointer().set_to_beginning(); } - void set_to_end_marker() { item_pointer().set_to_end_marker(); } - void set_to_next() { item_pointer().set_to_next(); } - void set_to_previous() { item_pointer().set_to_previous(); } - ipointer& operator ++() { item_pointer().operator ++(); return (*this); } - ipointer operator++(int) { ipointer _Tmp = *this; ++*this; return (_Tmp); } - ipointer& operator --() { item_pointer().operator --(); return (*this); } - ipointer operator--(int) { ipointer _Tmp = *this; --*this; return (_Tmp); } - void advance(difference_type n) { item_pointer().advance(n); } - void regress(difference_type n) { item_pointer().regress(n); } - ipointer& operator +=(difference_type n) { item_pointer().operator +=(n); return (*this); } - ipointer& operator -=(difference_type n) { item_pointer().operator -=(n); return (*this); } - ipointer operator+(difference_type n) const { auto retval = (*this); retval += n; return retval; } - ipointer operator-(difference_type n) const { return ((*this) + (-n)); } - difference_type operator-(const ipointer& _Right_cref) const { return item_pointer() - (_Right_cref.item_pointer()); } - reference operator*() const { return item_pointer().operator*(); } - reference item() const { return operator*(); } - reference previous_item() const { return item_pointer().previous_item(); } - pointer operator->() const { return item_pointer().operator->(); } - reference operator[](difference_type _Off) const { return item_pointer()[_Off]; } - ipointer& operator=(const ipointer& _Right_cref) { item_pointer().operator=(_Right_cref.item_pointer()); return (*this); } - bool operator==(const ipointer& _Right_cref) const { return item_pointer().operator==(_Right_cref.item_pointer()); } - bool operator!=(const ipointer& _Right_cref) const { return (!(_Right_cref == (*this))); } - bool operator<(const ipointer& _Right) const { return (item_pointer() < _Right.item_pointer()); } - bool operator<=(const ipointer& _Right) const { return (item_pointer() <= _Right.item_pointer()); } - bool operator>(const ipointer& _Right) const { return (item_pointer() > _Right.item_pointer()); } - bool operator>=(const ipointer& _Right) const { return (item_pointer() >= _Right.item_pointer()); } - void set_to_item_pointer(const ipointer& _Right_cref) { item_pointer().set_to_item_pointer(_Right_cref.item_pointer()); } - msev_size_t position() const { return item_pointer().position(); } - private: - _Myt* m_owner_ptr = nullptr; - std::shared_ptr<mm_iterator_handle_type> m_handle_shptr; - friend class /*_Myt*/msevector<_Ty, _A>; - }; - - ipointer ibegin() { // return ipointer for beginning of mutable sequence - ipointer retval(*this); - retval.set_to_beginning(); - return retval; - } - cipointer ibegin() const { // return ipointer for beginning of nonmutable sequence - cipointer retval(*this); - retval.set_to_beginning(); - return retval; - } - ipointer iend() { // return ipointer for end of mutable sequence - ipointer retval(*this); - retval.set_to_end_marker(); - return retval; - } - cipointer iend() const { // return ipointer for end of nonmutable sequence - cipointer retval(*this); - retval.set_to_end_marker(); - return retval; - } - cipointer cibegin() const { // return ipointer for beginning of nonmutable sequence - cipointer retval(*this); - retval.set_to_beginning(); - return retval; - } - cipointer ciend() const { // return ipointer for end of nonmutable sequence - cipointer retval(*this); - retval.set_to_end_marker(); - return retval; - } - - msevector(const cipointer &start, const cipointer &end, const _A& _Al = _A()) - : base_class(_Al), m_mmitset(*this) { - /*m_debug_size = size();*/ - assign(start, end); - } - void assign(const mm_const_iterator_type &start, const mm_const_iterator_type &end) { - if (start.m_owner_cptr != end.m_owner_cptr) { MSE_THROW(msevector_range_error("invalid arguments - void assign(const mm_const_iterator_type &start, const mm_const_iterator_type &end) - msevector")); } - if (start > end) { MSE_THROW(msevector_range_error("invalid arguments - void assign(const mm_const_iterator_type &start, const mm_const_iterator_type &end) - msevector")); } - typename base_class::const_iterator _F = start; - typename base_class::const_iterator _L = end; - (*this).assign(_F, _L); - } - void assign_inclusive(const mm_const_iterator_type &first, const mm_const_iterator_type &last) { - auto end = last; - end++; // this should include some checks - (*this).assign(first, end); - } - void assign(const cipointer &start, const cipointer &end) { - assign(start.const_item_pointer(), end.const_item_pointer()); - } - void assign_inclusive(const cipointer &first, const cipointer &last) { - assign_inclusive(first.const_item_pointer(), last.const_item_pointer()); - } - void insert_before(const mm_const_iterator_type &pos, size_type _M, const _Ty& _X) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before() - msevector")); } - typename base_class::const_iterator _P = pos; - (*this).insert(_P, _M, _X); - } - void insert_before(const mm_const_iterator_type &pos, _Ty&& _X) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before() - msevector")); } - typename base_class::const_iterator _P = pos; - (*this).insert(_P, 1, std::move(_X)); - } - void insert_before(const mm_const_iterator_type &pos, const _Ty& _X = _Ty()) { (*this).insert(pos, 1, _X); } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - void insert_before(const mm_const_iterator_type &pos, const _Iter &start, const _Iter &end) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before() - msevector")); } - //if (start.m_owner_cptr != end.m_owner_cptr) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before(const mm_const_iterator_type &pos, const mm_const_iterator_type &start, const mm_const_iterator_type &end) - msevector")); } - typename base_class::const_iterator _P = pos; - (*this).insert(_P, start, end); - } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - void insert_before_inclusive(const mm_const_iterator_type &pos, const _Iter &first, const _Iter &last) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before() - msevector")); } - if (first.m_owner_cptr != last.m_owner_cptr) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before_inclusive(const mm_const_iterator_type &pos, const mm_const_iterator_type &first, const mm_const_iterator_type &last) - msevector")); } - if (!(last.points_to_item())) { MSE_THROW(msevector_range_error("invalid argument - void insert_before_inclusive(const mm_const_iterator_type &pos, const mm_const_iterator_type &first, const mm_const_iterator_type &last) - msevector")); } - typename base_class::const_iterator _P = pos; - auto _L = last; - _L++; - (*this).insert(_P, first, _L); - } - void insert_before(const mm_const_iterator_type &pos, _XSTD initializer_list<typename base_class::value_type> _Ilist) { // insert initializer_list - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before() - msevector")); } - typename base_class::const_iterator _P = pos; - (*this).insert(_P, _Ilist); - } - ipointer insert_before(const cipointer &pos, size_type _M, const _Ty& _X) { - msev_size_t original_pos = pos.position(); - insert_before(pos.const_item_pointer(), _M, _X); - ipointer retval(*this); retval.advance(msev_int(original_pos)); - return retval; - } - ipointer insert_before(const cipointer &pos, _Ty&& _X) { - msev_size_t original_pos = pos.position(); - insert_before(pos.const_item_pointer(), std::move(_X)); - ipointer retval(*this); retval.advance(msev_int(original_pos)); - return retval; - } - ipointer insert_before(const cipointer &pos, const _Ty& _X = _Ty()) { return insert_before(pos, 1, _X); } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - ipointer insert_before(const cipointer &pos, const _Iter &start, const _Iter &end) { - msev_size_t original_pos = pos.position(); - insert_before(pos.const_item_pointer(), start, end); - ipointer retval(*this); retval.advance(msev_int(original_pos)); - return retval; - } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - ipointer insert_before_inclusive(const cipointer &pos, const _Iter &first, const _Iter &last) { - auto end = last; end++; - return insert_before(pos, first, end); - } - ipointer insert_before(const cipointer &pos, _XSTD initializer_list<typename base_class::value_type> _Ilist) { // insert initializer_list - msev_size_t original_pos = pos.position(); - (*this).insert_before(pos.const_item_pointer(), _Ilist); - ipointer retval(*this); retval.advance(msev_int(original_pos)); - return retval; - } - void insert_before(msev_size_t pos, _Ty&& _X) { - typename base_class::const_iterator _P = (*this).begin() + msev_as_a_size_t(pos); - (*this).insert(_P, std::move(_X)); - } - void insert_before(msev_size_t pos, const _Ty& _X = _Ty()) { - typename base_class::const_iterator _P = (*this).begin() + msev_as_a_size_t(pos); - (*this).insert(_P, _X); - } - void insert_before(msev_size_t pos, size_t _M, const _Ty& _X) { - typename base_class::const_iterator _P = (*this).begin() + msev_as_a_size_t(pos); - (*this).insert(_P, _M, _X); - } - void insert_before(msev_size_t pos, _XSTD initializer_list<typename base_class::value_type> _Ilist) { // insert initializer_list - typename base_class::const_iterator _P = (*this).begin() + msev_as_a_size_t(pos); - (*this).insert(_P, _Ilist); - } - /* These insert() functions are just aliases for their corresponding insert_before() functions. */ - ipointer insert(const cipointer &pos, size_type _M, const _Ty& _X) { return insert_before(pos, _M, _X); } - ipointer insert(const cipointer &pos, _Ty&& _X) { return insert_before(pos, std::move(_X)); } - ipointer insert(const cipointer &pos, const _Ty& _X = _Ty()) { return insert_before(pos, _X); } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - ipointer insert(const cipointer &pos, const _Iter &start, const _Iter &end) { return insert_before(pos, start, end); } - ipointer insert(const cipointer &pos, _XSTD initializer_list<typename base_class::value_type> _Ilist) { return insert_before(pos, _Ilist); } - template<class ..._Valty> -#if !(defined(GPP4P8_COMPATIBLE)) - void emplace(const mm_const_iterator_type &pos, _Valty&& ..._Val) - { // insert by moving _Val at pos -#else /*!(defined(GPP4P8_COMPATIBLE))*/ - void emplace(const mm_iterator_type &pos, _Valty&& ..._Val) - { // insert by moving _Val at pos -#endif /*!(defined(GPP4P8_COMPATIBLE))*/ - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void emplace() - msevector")); } - typename base_class::const_iterator _P = pos; - auto retval = base_class::emplace(_P, std::forward<_Valty>(_Val)...); - } - template<class ..._Valty> -#if !(defined(GPP4P8_COMPATIBLE)) - ipointer emplace(const cipointer &pos, _Valty&& ..._Val) - { // insert by moving _Val at pos -#else /*!(defined(GPP4P8_COMPATIBLE))*/ - ipointer emplace(const ipointer &pos, _Valty&& ..._Val) - { // insert by moving _Val at pos -#endif /*!(defined(GPP4P8_COMPATIBLE))*/ - msev_size_t original_pos = pos.position(); - (*this).emplace(pos.const_item_pointer(), std::forward<_Valty>(_Val)...); - ipointer retval(*this); retval.advance(msev_int(original_pos)); - return retval; - } - void erase(const mm_const_iterator_type &pos) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void erase() - msevector")); } - typename base_class::const_iterator _P = pos; - (*this).erase(_P); - } - void erase(const mm_const_iterator_type &start, const mm_const_iterator_type &end) { - if (start.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void erase() - msevector")); } - if (end.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void erase() - msevector")); } - typename base_class::const_iterator _F = start; - typename base_class::const_iterator _L = end; - (*this).erase(_F, _L); - } - void erase_inclusive(const mm_const_iterator_type &first, const mm_const_iterator_type &last) { - if (first.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void erase_inclusive() - msevector")); } - if (last.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void erase_inclusive() - msevector")); } - if (!(last.points_to_item())) { MSE_THROW(msevector_range_error("invalid argument - void erase_inclusive() - msevector")); } - typename base_class::const_iterator _F = first; - typename base_class::const_iterator _L = last; - _L++; - (*this).erase(_F, _L); - } - ipointer erase(const cipointer &pos) { - auto retval_pos = pos; - retval_pos.set_to_next(); - erase(pos.const_item_pointer()); - ipointer retval = (*this).ibegin(); - retval.advance(msev_int(retval_pos.position())); - return retval; - } - ipointer erase(const cipointer &start, const cipointer &end) { - auto retval_pos = end; - retval_pos.set_to_next(); - erase(start.const_item_pointer(), end.const_item_pointer()); - ipointer retval = (*this).ibegin(); - retval.advance(msev_int(retval_pos.position())); - return retval; - } - ipointer erase_inclusive(const cipointer &first, const cipointer &last) { - auto end = last; end.set_to_next(); - return erase(first, end); - } - void erase_previous_item(const mm_const_iterator_type &pos) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void erase_previous_item() - msevector")); } - if (!(pos.has_previous())) { MSE_THROW(msevector_range_error("invalid arguments - void erase_previous_item() - msevector")); } - typename base_class::const_iterator _P = pos; - _P--; - (*this).erase(_P); - } - ipointer erase_previous_item(const cipointer &pos) { - erase_previous_item(pos.const_item_pointer()); - ipointer retval = (*this).ibegin(); - retval.advance(pos.position()); - return retval; - } - - - /* ss_const_iterator_type is a bounds checked iterator. */ - class ss_const_iterator_type : public random_access_const_iterator_base { - public: - typedef typename base_class::const_iterator::iterator_category iterator_category; - typedef typename base_class::const_iterator::value_type value_type; - //typedef typename base_class::const_iterator::difference_type difference_type; - typedef typename _Myt::difference_type difference_type; - typedef difference_type distance_type; // retained - typedef typename base_class::const_iterator::pointer pointer; - typedef typename base_class::const_pointer const_pointer; - typedef typename base_class::const_iterator::reference reference; - typedef typename base_class::const_reference const_reference; - - ss_const_iterator_type() {} - void assert_valid_index() const { - if (m_owner_cptr->size() < m_index) { MSE_THROW(msevector_range_error("invalid index - void assert_valid_index() const - ss_const_iterator_type - msevector")); } - } - void reset() { set_to_end_marker(); } - bool points_to_an_item() const { - if (m_owner_cptr->size() > m_index) { return true; } - else { - if (m_index == m_owner_cptr->size()) { return false; } - else { MSE_THROW(msevector_range_error("attempt to use invalid ss_const_iterator_type - bool points_to_an_item() const - ss_const_iterator_type - msevector")); } - } - } - bool points_to_end_marker() const { - if (false == points_to_an_item()) { - assert(m_index == m_owner_cptr->size()); - return true; - } - else { return false; } - } - bool points_to_beginning() const { - if (0 == m_index) { return true; } - else { return false; } - } - /* has_next_item_or_end_marker() is just an alias for points_to_an_item(). */ - bool has_next_item_or_end_marker() const { return points_to_an_item(); } - /* has_next() is just an alias for points_to_an_item() that's familiar to java programmers. */ - bool has_next() const { return has_next_item_or_end_marker(); } - bool has_previous() const { - if (m_owner_cptr->size() < m_index) { - MSE_THROW(msevector_range_error("attempt to use invalid ss_const_iterator_type - bool has_previous() const - ss_const_iterator_type - msevector")); - } - else if (1 <= m_index) { - return true; - } - else { - return false; - } - } - void set_to_beginning() { - m_index = 0; - } - void set_to_end_marker() { - m_index = m_owner_cptr->size(); - } - void set_to_next() { - if (points_to_an_item()) { - m_index += 1; - } - else { - MSE_THROW(msevector_range_error("attempt to use invalid const_item_pointer - void set_to_next() - ss_const_iterator_type - msevector")); - } - } - void set_to_previous() { - if (has_previous()) { - m_index -= 1; - } - else { - MSE_THROW(msevector_range_error("attempt to use invalid const_item_pointer - void set_to_previous() - ss_const_iterator_type - msevector")); - } - } - ss_const_iterator_type& operator ++() { (*this).set_to_next(); return (*this); } - ss_const_iterator_type operator++(int) { ss_const_iterator_type _Tmp = *this; (*this).set_to_next(); return (_Tmp); } - ss_const_iterator_type& operator --() { (*this).set_to_previous(); return (*this); } - ss_const_iterator_type operator--(int) { ss_const_iterator_type _Tmp = *this; (*this).set_to_previous(); return (_Tmp); } - void advance(difference_type n) { - auto new_index = msev_int(m_index) + n; - if ((0 > new_index) || (m_owner_cptr->size() < msev_size_t(new_index))) { - MSE_THROW(msevector_range_error("index out of range - void advance(difference_type n) - ss_const_iterator_type - msevector")); - } - else { - m_index = msev_size_t(new_index); - } - } - void regress(difference_type n) { advance(-n); } - ss_const_iterator_type& operator +=(difference_type n) { (*this).advance(n); return (*this); } - ss_const_iterator_type& operator -=(difference_type n) { (*this).regress(n); return (*this); } - ss_const_iterator_type operator+(difference_type n) const { - ss_const_iterator_type retval; retval.m_owner_cptr = m_owner_cptr; - retval = (*this); - retval.advance(n); - return retval; - } - ss_const_iterator_type operator-(difference_type n) const { return ((*this) + (-n)); } - difference_type operator-(const ss_const_iterator_type &rhs) const { - if (rhs.m_owner_cptr != (*this).m_owner_cptr) { MSE_THROW(msevector_range_error("invalid argument - difference_type operator-(const ss_const_iterator_type &rhs) const - msevector::ss_const_iterator_type")); } - auto retval = difference_type((*this).m_index) - difference_type(rhs.m_index); - assert(difference_type((*m_owner_cptr).size()) >= retval); - return retval; - } - const_reference operator*() const { - return (*m_owner_cptr).at(msev_as_a_size_t((*this).m_index)); - } - const_reference item() const { return operator*(); } - const_reference previous_item() const { - return m_owner_cptr->at(msev_as_a_size_t(m_index - 1)); - } - const_pointer operator->() const { - return &((*m_owner_cptr).at(msev_as_a_size_t((*this).m_index))); - } - const_reference operator[](difference_type _Off) const { return (*m_owner_cptr).at(msev_as_a_size_t(difference_type(m_index) + _Off)); } - /* - ss_const_iterator_type& operator=(const typename base_class::const_iterator& _Right_cref) - { - msev_int d = std::distance<typename base_class::iterator>(m_owner_cptr->cbegin(), _Right_cref); - if ((0 <= d) && (m_owner_cptr->size() >= d)) { - if (m_owner_cptr->size() == d) { - assert(m_owner_cptr->cend() == _Right_cref); - } - m_index = msev_size_t(d); - base_class::const_iterator::operator=(_Right_cref); - } - else { - MSE_THROW(msevector_range_error("doesn't seem to be a valid assignment value - ss_const_iterator_type& operator=(const typename base_class::const_iterator& _Right_cref) - ss_const_iterator_type - msevector")); - } - return (*this); - } - */ - ss_const_iterator_type& operator=(const ss_const_iterator_type& _Right_cref) { - ((*this).m_owner_cptr) = _Right_cref.m_owner_cptr; - (*this).m_index = _Right_cref.m_index; - return (*this); - } - bool operator==(const ss_const_iterator_type& _Right_cref) const { - if (this->m_owner_cptr != _Right_cref.m_owner_cptr) { MSE_THROW(msevector_range_error("invalid argument - ss_const_iterator_type& operator==(const ss_const_iterator_type& _Right) - ss_const_iterator_type - msevector")); } - return (_Right_cref.m_index == m_index); - } - bool operator!=(const ss_const_iterator_type& _Right_cref) const { return (!(_Right_cref == (*this))); } - bool operator<(const ss_const_iterator_type& _Right) const { - if (this->m_owner_cptr != _Right.m_owner_cptr) { MSE_THROW(msevector_range_error("invalid argument - ss_const_iterator_type& operator<(const ss_const_iterator_type& _Right) - ss_const_iterator_type - msevector")); } - return (m_index < _Right.m_index); - } - bool operator<=(const ss_const_iterator_type& _Right) const { return (((*this) < _Right) || (_Right == (*this))); } - bool operator>(const ss_const_iterator_type& _Right) const { return (!((*this) <= _Right)); } - bool operator>=(const ss_const_iterator_type& _Right) const { return (!((*this) < _Right)); } - void set_to_const_item_pointer(const ss_const_iterator_type& _Right_cref) { - (*this) = _Right_cref; - } - void invalidate_inclusive_range(msev_size_t index_of_first, msev_size_t index_of_last) { - if ((index_of_first <= (*this).m_index) && (index_of_last >= (*this).m_index)) { - (*this).reset(); - } - } - void shift_inclusive_range(msev_size_t index_of_first, msev_size_t index_of_last, msev_int shift) { - if ((index_of_first <= (*this).m_index) && (index_of_last >= (*this).m_index)) { - auto new_index = (*this).m_index + shift; - if ((0 > new_index) || (m_owner_cptr->size() < new_index)) { - MSE_THROW(msevector_range_error("void shift_inclusive_range() - ss_const_iterator_type - msevector")); - } - else { - (*this).m_index = msev_size_t(new_index); - (*this).sync_const_iterator_to_index(); - } - } - } - msev_size_t position() const { - return m_index; - } - operator typename base_class::const_iterator() const { - typename base_class::const_iterator retval = (*m_owner_cptr).cbegin(); - retval += msev_as_a_size_t(m_index); - return retval; - } - private: - void sync_const_iterator_to_index() { - assert(m_owner_cptr->size() >= (*this).m_index); - //base_class::const_iterator::operator=(m_owner_cptr->cbegin()); - //base_class::const_iterator::operator+=(msev_as_a_size_t(m_index)); - } - msev_size_t m_index = 0; - msev_pointer<const _Myt> m_owner_cptr = nullptr; - friend class /*_Myt*/msevector<_Ty, _A>; - }; - /* ss_iterator_type is a bounds checked iterator. */ - class ss_iterator_type : public random_access_iterator_base { - public: - typedef typename base_class::iterator::iterator_category iterator_category; - typedef typename base_class::iterator::value_type value_type; - //typedef typename base_class::iterator::difference_type difference_type; - typedef typename _Myt::difference_type difference_type; - typedef difference_type distance_type; // retained - typedef typename base_class::iterator::pointer pointer; - typedef typename base_class::iterator::reference reference; - - ss_iterator_type() {} - void reset() { set_to_end_marker(); } - bool points_to_an_item() const { - if (m_owner_ptr->size() > m_index) { return true; } - else { - if (m_index == m_owner_ptr->size()) { return false; } - else { MSE_THROW(msevector_range_error("attempt to use invalid ss_iterator_type - bool points_to_an_item() const - ss_iterator_type - msevector")); } - } - } - bool points_to_end_marker() const { - if (false == points_to_an_item()) { - assert(m_index == m_owner_ptr->size()); - return true; - } - else { return false; } - } - bool points_to_beginning() const { - if (0 == m_index) { return true; } - else { return false; } - } - /* has_next_item_or_end_marker() is just an alias for points_to_an_item(). */ - bool has_next_item_or_end_marker() const { return points_to_an_item(); } - /* has_next() is just an alias for points_to_an_item() that's familiar to java programmers. */ - bool has_next() const { return has_next_item_or_end_marker(); } - bool has_previous() const { - if (m_owner_ptr->size() < m_index) { - MSE_THROW(msevector_range_error("attempt to use invalid ss_iterator_type - bool has_previous() const - ss_iterator_type - msevector")); - } else if (1 <= m_index) { - return true; - } - else { - return false; - } - } - void set_to_beginning() { - m_index = 0; - } - void set_to_end_marker() { - m_index = m_owner_ptr->size(); - } - void set_to_next() { - if (points_to_an_item()) { - m_index += 1; - } - else { - MSE_THROW(msevector_range_error("attempt to use invalid item_pointer - void set_to_next() - ss_const_iterator_type - msevector")); - } - } - void set_to_previous() { - if (has_previous()) { - m_index -= 1; - } - else { - MSE_THROW(msevector_range_error("attempt to use invalid item_pointer - void set_to_previous() - ss_iterator_type - msevector")); - } - } - ss_iterator_type& operator ++() { (*this).set_to_next(); return (*this); } - ss_iterator_type operator++(int) { ss_iterator_type _Tmp = *this; (*this).set_to_next(); return (_Tmp); } - ss_iterator_type& operator --() { (*this).set_to_previous(); return (*this); } - ss_iterator_type operator--(int) { ss_iterator_type _Tmp = *this; (*this).set_to_previous(); return (_Tmp); } - void advance(difference_type n) { - auto new_index = msev_int(m_index) + n; - if ((0 > new_index) || (m_owner_ptr->size() < msev_size_t(new_index))) { - MSE_THROW(msevector_range_error("index out of range - void advance(difference_type n) - ss_iterator_type - msevector")); - } - else { - m_index = msev_size_t(new_index); - } - } - void regress(difference_type n) { advance(-n); } - ss_iterator_type& operator +=(difference_type n) { (*this).advance(n); return (*this); } - ss_iterator_type& operator -=(difference_type n) { (*this).regress(n); return (*this); } - ss_iterator_type operator+(difference_type n) const { - ss_iterator_type retval; retval.m_owner_ptr = m_owner_ptr; - retval = (*this); - retval.advance(n); - return retval; - } - ss_iterator_type operator-(difference_type n) const { return ((*this) + (-n)); } - difference_type operator-(const ss_iterator_type& rhs) const { - if (rhs.m_owner_ptr != (*this).m_owner_ptr) { MSE_THROW(msevector_range_error("invalid argument - difference_type operator-(const ss_iterator_type& rhs) const - msevector::ss_iterator_type")); } - auto retval = difference_type((*this).m_index) - difference_type(rhs.m_index); - assert(int((*m_owner_ptr).size()) >= retval); - return retval; - } - reference operator*() const { - return (*m_owner_ptr).at(msev_as_a_size_t((*this).m_index)); - } - reference item() const { return operator*(); } - reference previous_item() const { - return m_owner_ptr->at(msev_as_a_size_t(m_index - 1)); - } - pointer operator->() const { - return &((*m_owner_ptr).at(msev_as_a_size_t((*this).m_index))); - } - reference operator[](difference_type _Off) const { return (*m_owner_ptr).at(msev_as_a_size_t(difference_type(m_index) + _Off)); } - /* - ss_iterator_type& operator=(const typename base_class::iterator& _Right_cref) - { - msev_int d = std::distance<typename base_class::iterator>(m_owner_ptr->begin(), _Right_cref); - if ((0 <= d) && (m_owner_ptr->size() >= d)) { - if (m_owner_ptr->size() == d) { - assert(m_owner_ptr->end() == _Right_cref); - } - m_index = msev_size_t(d); - base_class::iterator::operator=(_Right_cref); - } - else { - MSE_THROW(msevector_range_error("doesn't seem to be a valid assignment value - ss_iterator_type& operator=(const typename base_class::iterator& _Right_cref) - ss_const_iterator_type - msevector")); - } - return (*this); - } - */ - ss_iterator_type& operator=(const ss_iterator_type& _Right_cref) { - ((*this).m_owner_ptr) = _Right_cref.m_owner_ptr; - (*this).m_index = _Right_cref.m_index; - return (*this); - } - bool operator==(const ss_iterator_type& _Right_cref) const { - if (this->m_owner_ptr != _Right_cref.m_owner_ptr) { MSE_THROW(msevector_range_error("invalid argument - ss_iterator_type& operator==(const ss_iterator_type& _Right) - ss_iterator_type - msevector")); } - return (_Right_cref.m_index == m_index); - } - bool operator!=(const ss_iterator_type& _Right_cref) const { return (!(_Right_cref == (*this))); } - bool operator<(const ss_iterator_type& _Right) const { - if (this->m_owner_ptr != _Right.m_owner_ptr) { MSE_THROW(msevector_range_error("invalid argument - ss_iterator_type& operator<(const ss_iterator_type& _Right) - ss_iterator_type - msevector")); } - return (m_index < _Right.m_index); - } - bool operator<=(const ss_iterator_type& _Right) const { return (((*this) < _Right) || (_Right == (*this))); } - bool operator>(const ss_iterator_type& _Right) const { return (!((*this) <= _Right)); } - bool operator>=(const ss_iterator_type& _Right) const { return (!((*this) < _Right)); } - void set_to_item_pointer(const ss_iterator_type& _Right_cref) { - (*this) = _Right_cref; - } - void invalidate_inclusive_range(msev_size_t index_of_first, msev_size_t index_of_last) { - if ((index_of_first <= (*this).m_index) && (index_of_last >= (*this).m_index)) { - (*this).reset(); - } - } - void shift_inclusive_range(msev_size_t index_of_first, msev_size_t index_of_last, msev_int shift) { - if ((index_of_first <= (*this).m_index) && (index_of_last >= (*this).m_index)) { - auto new_index = (*this).m_index + shift; - if ((0 > new_index) || (m_owner_ptr->size() < new_index)) { - MSE_THROW(msevector_range_error("void shift_inclusive_range() - ss_iterator_type - msevector")); - } - else { - (*this).m_index = msev_size_t(new_index); - (*this).sync_iterator_to_index(); - } - } - } - msev_size_t position() const { - return m_index; - } - operator ss_const_iterator_type() const { - ss_const_iterator_type retval; - if (nullptr != m_owner_ptr) { - retval = m_owner_ptr->ss_cbegin(); - retval.advance(msev_int(m_index)); - } - return retval; - } - operator typename base_class::iterator() const { - typename base_class::iterator retval = (*m_owner_ptr).begin(); - retval += msev_as_a_size_t(m_index); - return retval; - } - - private: - void sync_iterator_to_index() { - assert(m_owner_ptr->size() >= (*this).m_index); - //base_class::iterator::operator=(m_owner_ptr->begin()); - //base_class::iterator::operator+=(msev_as_a_size_t(m_index)); - } - msev_size_t m_index = 0; - msev_pointer<_Myt> m_owner_ptr = nullptr; - friend class /*_Myt*/msevector<_Ty, _A>; - }; - typedef std::reverse_iterator<ss_iterator_type> ss_reverse_iterator_type; - typedef std::reverse_iterator<ss_const_iterator_type> ss_const_reverse_iterator_type; - - ss_iterator_type ss_begin() - { // return base_class::iterator for beginning of mutable sequence - ss_iterator_type retval; retval.m_owner_ptr = this; - retval.set_to_beginning(); - return retval; - } - - ss_const_iterator_type ss_begin() const - { // return base_class::iterator for beginning of nonmutable sequence - ss_const_iterator_type retval; retval.m_owner_cptr = this; - retval.set_to_beginning(); - return retval; - } - - ss_iterator_type ss_end() - { // return base_class::iterator for end of mutable sequence - ss_iterator_type retval; retval.m_owner_ptr = this; - retval.set_to_end_marker(); - return retval; - } - - ss_const_iterator_type ss_end() const - { // return base_class::iterator for end of nonmutable sequence - ss_const_iterator_type retval; retval.m_owner_cptr = this; - retval.set_to_end_marker(); - return retval; - } - - ss_const_iterator_type ss_cbegin() const - { // return base_class::iterator for beginning of nonmutable sequence - ss_const_iterator_type retval; retval.m_owner_cptr = this; - retval.set_to_beginning(); - return retval; - } - - ss_const_iterator_type ss_cend() const - { // return base_class::iterator for end of nonmutable sequence - ss_const_iterator_type retval; retval.m_owner_cptr = this; - retval.set_to_end_marker(); - return retval; - } - - ss_const_reverse_iterator_type ss_crbegin() const - { // return base_class::iterator for beginning of reversed nonmutable sequence - return (ss_rbegin()); - } - - ss_const_reverse_iterator_type ss_crend() const - { // return base_class::iterator for end of reversed nonmutable sequence - return (ss_rend()); - } - - ss_reverse_iterator_type ss_rbegin() - { // return base_class::iterator for beginning of reversed mutable sequence - return (reverse_iterator(ss_end())); - } - - ss_const_reverse_iterator_type ss_rbegin() const - { // return base_class::iterator for beginning of reversed nonmutable sequence - return (const_reverse_iterator(ss_end())); - } - - ss_reverse_iterator_type ss_rend() - { // return base_class::iterator for end of reversed mutable sequence - return (reverse_iterator(ss_begin())); - } - - ss_const_reverse_iterator_type ss_rend() const - { // return base_class::iterator for end of reversed nonmutable sequence - return (const_reverse_iterator(ss_begin())); - } - - msevector(const ss_const_iterator_type &start, const ss_const_iterator_type &end, const _A& _Al = _A()) - : base_class(_Al), m_mmitset(*this) { - /*m_debug_size = size();*/ - assign(start, end); - } - void assign(const ss_const_iterator_type &start, const ss_const_iterator_type &end) { - if (start.m_owner_cptr != end.m_owner_cptr) { MSE_THROW(msevector_range_error("invalid arguments - void assign(const ss_const_iterator_type &start, const ss_const_iterator_type &end) - msevector")); } - if (start > end) { MSE_THROW(msevector_range_error("invalid arguments - void assign(const ss_const_iterator_type &start, const ss_const_iterator_type &end) - msevector")); } - typename base_class::const_iterator _F = start; - typename base_class::const_iterator _L = end; - (*this).assign(_F, _L); - } - void assign_inclusive(const ss_const_iterator_type &first, const ss_const_iterator_type &last) { - auto end = last; - end++; // this should include some checks - (*this).assign(first, end); - } - ss_iterator_type insert_before(const ss_const_iterator_type &pos, size_type _M, const _Ty& _X) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid argument - void insert_before() - msevector")); } - pos.assert_valid_index(); - msev_size_t original_pos = pos.position(); - typename base_class::const_iterator _P = pos; - (*this).insert(_P, _M, _X); - ss_iterator_type retval = ss_begin(); - retval.advance(msev_int(original_pos)); - return retval; - } - ss_iterator_type insert_before(const ss_const_iterator_type &pos, _Ty&& _X) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid argument - void insert_before() - msevector")); } - pos.assert_valid_index(); - msev_size_t original_pos = pos.position(); - typename base_class::const_iterator _P = pos; - (*this).insert(_P, std::move(_X)); - ss_iterator_type retval = ss_begin(); - retval.advance(msev_int(original_pos)); - return retval; - } - ss_iterator_type insert_before(const ss_const_iterator_type &pos, const _Ty& _X = _Ty()) { return (*this).insert(pos, 1, _X); } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - ss_iterator_type insert_before(const ss_const_iterator_type &pos, const _Iter &start, const _Iter &end) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid argument - ss_iterator_type insert_before() - msevector")); } - //if (start.m_owner_cptr != end.m_owner_cptr) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before(const ss_const_iterator_type &pos, const ss_const_iterator_type &start, const ss_const_iterator_type &end) - msevector")); } - pos.assert_valid_index(); - msev_size_t original_pos = pos.position(); - typename base_class::const_iterator _P = pos; - (*this).insert(_P, start, end); - ss_iterator_type retval = ss_begin(); - retval.advance(msev_int(original_pos)); - return retval; - } - ss_iterator_type insert_before(const ss_const_iterator_type &pos, const ss_const_iterator_type& start, const ss_const_iterator_type &end) { - if (start.m_owner_cptr != end.m_owner_cptr) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before(const ss_const_iterator_type &pos, const ss_const_iterator_type &start, const ss_const_iterator_type &end) - msevector")); } - end.assert_valid_index(); - if (start > end) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before(const ss_const_iterator_type &pos, const ss_const_iterator_type &start, const ss_const_iterator_type &end) - msevector")); } - typename base_class::const_iterator _S = start; - typename base_class::const_iterator _E = end; - return (*this).insert_before(pos, _S, _E); - } - ss_iterator_type insert_before(const ss_const_iterator_type &pos, const _Ty* start, const _Ty* end) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - ss_iterator_type insert_before() - msevector")); } - //if (start.m_owner_cptr != end.m_owner_cptr) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before(const ss_const_iterator_type &pos, const ss_const_iterator_type &start, const ss_const_iterator_type &end) - msevector")); } - if (start > end) { MSE_THROW(msevector_range_error("invalid arguments - ss_iterator_type insert_before() - msevector")); } - pos.assert_valid_index(); - msev_size_t original_pos = pos.position(); - typename base_class::const_iterator _P = pos; - (*this).insert(_P, start, end); - ss_iterator_type retval = ss_begin(); - retval.advance(msev_int(original_pos)); - return retval; - } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - ss_iterator_type insert_before_inclusive(const ss_iterator_type &pos, const _Iter &first, const _Iter &last) { - auto end = last; - end++; // this may include some checks - return (*this).insert_before(pos, first, end); - } - ss_iterator_type insert_before(const ss_const_iterator_type &pos, _XSTD initializer_list<typename base_class::value_type> _Ilist) { // insert initializer_list - if (pos.m_owner_ptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void insert_before() - msevector")); } - pos.assert_valid_index(); - msev_size_t original_pos = pos.position(); - typename base_class::const_iterator _P = pos; - (*this).insert(_P, _Ilist); - ss_iterator_type retval = ss_begin(); - retval.advance(msev_int(original_pos)); - return retval; - } - /* These insert() functions are just aliases for their corresponding insert_before() functions. */ - ss_iterator_type insert(const ss_const_iterator_type &pos, size_type _M, const _Ty& _X) { return insert_before(pos, _M, _X); } - ss_iterator_type insert(const ss_const_iterator_type &pos, _Ty&& _X) { return insert_before(pos, std::move(_X)); } - ss_iterator_type insert(const ss_const_iterator_type &pos, const _Ty& _X = _Ty()) { return insert_before(pos, _X); } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - ss_iterator_type insert(const ss_const_iterator_type &pos, const _Iter &start, const _Iter &end) { return insert_before(pos, start, end); } - ss_iterator_type insert(const ss_const_iterator_type &pos, const _Ty* start, const _Ty* &end) { return insert_before(pos, start, end); } - ss_iterator_type insert(const ss_const_iterator_type &pos, _XSTD initializer_list<typename base_class::value_type> _Ilist) { return insert_before(pos, _Ilist); } - template<class ..._Valty> -#if !(defined(GPP4P8_COMPATIBLE)) - ss_iterator_type emplace(const ss_const_iterator_type &pos, _Valty&& ..._Val) - { // insert by moving _Val at pos - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void emplace() - msevector")); } -#else /*!(defined(GPP4P8_COMPATIBLE))*/ - ipointer emplace(const ipointer &pos, _Valty&& ..._Val) - { // insert by moving _Val at pos - if (pos.m_owner_ptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void emplace() - msevector")); } -#endif /*!(defined(GPP4P8_COMPATIBLE))*/ - pos.assert_valid_index(); - msev_size_t original_pos = pos.position(); - typename base_class::const_iterator _P = pos; - (*this).emplace(_P, std::forward<_Valty>(_Val)...); - ss_iterator_type retval = ss_begin(); - retval.advance(msev_int(original_pos)); - return retval; - } - ss_iterator_type erase(const ss_const_iterator_type &pos) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void erase() - msevector")); } - if (!pos.points_to_an_item()) { MSE_THROW(msevector_range_error("invalid arguments - void erase() - msevector")); } - auto pos_index = pos.position(); - - typename base_class::const_iterator _P = pos; - (*this).erase(_P); - - ss_iterator_type retval = (*this).ss_begin(); - retval.advance(typename ss_const_iterator_type::difference_type(pos_index)); - return retval; - } - ss_iterator_type erase(const ss_const_iterator_type &start, const ss_const_iterator_type &end) { - if (start.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void erase() - msevector")); } - if (end.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void erase() - msevector")); } - if (start.position() > end.position()) { MSE_THROW(msevector_range_error("invalid arguments - void erase() - msevector")); } - auto pos_index = start.position(); - - typename base_class::const_iterator _F = start; - typename base_class::const_iterator _L = end; - (*this).erase(_F, _L); - - ss_iterator_type retval = (*this).ss_begin(); - retval.advance(typename ss_const_iterator_type::difference_type(pos_index)); - return retval; - } - ss_iterator_type erase_inclusive(const ss_const_iterator_type &first, const ss_const_iterator_type &last) { - auto end = last; end.set_to_next(); - return erase(first, end); - } - void erase_previous_item(const ss_const_iterator_type &pos) { - if (pos.m_owner_cptr != this) { MSE_THROW(msevector_range_error("invalid arguments - void erase_previous_item() - msevector")); } - if (!(pos.has_previous())) { MSE_THROW(msevector_range_error("invalid arguments - void erase_previous_item() - msevector")); } - typename base_class::const_iterator _P = pos; - _P--; - (*this).erase(_P); - } - }; - -} - -#undef MSE_THROW - -#endif /*ndef MSEMSEVECTOR_H*/ diff --git a/src/debug/mse/msemstdvector.h b/src/debug/mse/msemstdvector.h deleted file mode 100644 index fa7d848bc..000000000 --- a/src/debug/mse/msemstdvector.h +++ /dev/null @@ -1,413 +0,0 @@ - -// Copyright (c) 2015 Noah Lopez -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef MSEMSTDVECTOR_H -#define MSEMSTDVECTOR_H - -#include "debug/mse/msemsevector.h" - -#ifdef MSE_SAFER_SUBSTITUTES_DISABLED -#define MSE_MSTDVECTOR_DISABLED -#endif /*MSE_SAFER_SUBSTITUTES_DISABLED*/ - -namespace mse { - - namespace mstd { - -#ifdef MSE_MSTDVECTOR_DISABLED - template<class _Ty, class _A = std::allocator<_Ty> > using vector = std::vector<_Ty, _A>; - -#else /*MSE_MSTDVECTOR_DISABLED*/ - -#ifndef _NOEXCEPT -#define _NOEXCEPT -#endif /*_NOEXCEPT*/ - - template<class _Ty, class _A = std::allocator<_Ty> > - class vector { - public: - typedef mse::mstd::vector<_Ty, _A> _Myt; - typedef mse::msevector<_Ty, _A> _MV; - - typedef typename _MV::allocator_type allocator_type; - typedef typename _MV::value_type value_type; - typedef typename _MV::size_type size_type; - typedef typename _MV::difference_type difference_type; - typedef typename _MV::pointer pointer; - typedef typename _MV::const_pointer const_pointer; - typedef typename _MV::reference reference; - typedef typename _MV::const_reference const_reference; - - const _MV& msevector() const { return (*m_shptr); } - _MV& msevector() { return (*m_shptr); } - operator const _MV() const { return msevector(); } - operator _MV() { return msevector(); } - - explicit vector(const _A& _Al = _A()) : m_shptr(std::make_shared<_MV>(_Al)) {} - explicit vector(size_type _N) : m_shptr(std::make_shared<_MV>(_N)) {} - explicit vector(size_type _N, const _Ty& _V, const _A& _Al = _A()) : m_shptr(std::make_shared<_MV>(_N, _V, _Al)) {} - vector(_Myt&& _X) : m_shptr(std::make_shared<_MV>(std::move(_X.msevector()))) {} - vector(const _Myt& _X) : m_shptr(std::make_shared<_MV>(_X.msevector())) {} - vector(_MV&& _X) : m_shptr(std::make_shared<_MV>(std::move(_X))) {} - vector(const _MV& _X) : m_shptr(std::make_shared<_MV>(_X)) {} - vector(std::vector<_Ty>&& _X) : m_shptr(std::make_shared<_MV>(std::move(_X))) {} - vector(const std::vector<_Ty>& _X) : m_shptr(std::make_shared<_MV>(_X)) {} - typedef typename _MV::const_iterator _It; - vector(_It _F, _It _L, const _A& _Al = _A()) : m_shptr(std::make_shared<_MV>(_F, _L, _Al)) {} - vector(const _Ty* _F, const _Ty* _L, const _A& _Al = _A()) : m_shptr(std::make_shared<_MV>(_F, _L, _Al)) {} - template<class _Iter, class = typename std::enable_if<_mse_Is_iterator<_Iter>::value, void>::type> - vector(_Iter _First, _Iter _Last) : m_shptr(std::make_shared<_MV>(_First, _Last)) {} - template<class _Iter, class = typename std::enable_if<_mse_Is_iterator<_Iter>::value, void>::type> - vector(_Iter _First, _Iter _Last, const _A& _Al) : m_shptr(std::make_shared<_MV>(_First, _Last, _Al)) {} - - _Myt& operator=(_MV&& _X) { m_shptr->operator=(std::move(_X)); return (*this); } - _Myt& operator=(const _MV& _X) { m_shptr->operator=(_X); return (*this); } - _Myt& operator=(_Myt&& _X) { m_shptr->operator=(std::move(_X.msevector())); return (*this); } - _Myt& operator=(const _Myt& _X) { m_shptr->operator=(_X.msevector()); return (*this); } - void reserve(size_type _Count) { m_shptr->reserve(_Count); } - void resize(size_type _N, const _Ty& _X = _Ty()) { m_shptr->resize(_N, _X); } - typename _MV::const_reference operator[](size_type _P) const { return m_shptr->operator[](_P); } - typename _MV::reference operator[](size_type _P) { return m_shptr->operator[](_P); } - void push_back(_Ty&& _X) { m_shptr->push_back(std::move(_X)); } - void push_back(const _Ty& _X) { m_shptr->push_back(_X); } - void pop_back() { m_shptr->pop_back(); } - void assign(_It _F, _It _L) { m_shptr->assign(_F, _L); } - void assign(size_type _N, const _Ty& _X = _Ty()) { m_shptr->assign(_N, _X); } - template<class ..._Valty> - void emplace_back(_Valty&& ..._Val) { m_shptr->emplace_back(std::forward<_Valty>(_Val)...); } - void clear() { m_shptr->clear(); } - void swap(_MV& _X) { m_shptr->swap(_X); } - void swap(_Myt& _X) { m_shptr->swap(_X.msevector()); } - - vector(_XSTD initializer_list<typename _MV::value_type> _Ilist, const _A& _Al = _A()) : m_shptr(std::make_shared<_MV>(_Ilist, _Al)) {} - _Myt& operator=(_XSTD initializer_list<typename _MV::value_type> _Ilist) { m_shptr->operator=(_Ilist); return (*this); } - void assign(_XSTD initializer_list<typename _MV::value_type> _Ilist) { m_shptr->assign(_Ilist); } - - size_type capacity() const _NOEXCEPT{ return m_shptr->capacity(); } - void shrink_to_fit() { m_shptr->shrink_to_fit(); } - size_type size() const _NOEXCEPT{ return m_shptr->size(); } - size_type max_size() const _NOEXCEPT{ return m_shptr->max_size(); } - bool empty() const _NOEXCEPT{ return m_shptr->empty(); } - _A get_allocator() const _NOEXCEPT{ return m_shptr->get_allocator(); } - typename _MV::const_reference at(size_type _Pos) const { return m_shptr->at(_Pos); } - typename _MV::reference at(size_type _Pos) { return m_shptr->at(_Pos); } - typename _MV::reference front() { return m_shptr->front(); } - typename _MV::const_reference front() const { return m_shptr->front(); } - typename _MV::reference back() { return m_shptr->back(); } - typename _MV::const_reference back() const { return m_shptr->back(); } - - /* Try to avoid using these whenever possible. */ - value_type *data() _NOEXCEPT { - return m_shptr->data(); - } - const value_type *data() const _NOEXCEPT { - return m_shptr->data(); - } - - - class const_iterator : public _MV::random_access_const_iterator_base { - public: - typedef typename _MV::ss_const_iterator_type::iterator_category iterator_category; - typedef typename _MV::ss_const_iterator_type::value_type value_type; - typedef typename _MV::ss_const_iterator_type::difference_type difference_type; - typedef typename _MV::difference_type distance_type; // retained - typedef typename _MV::ss_const_iterator_type::pointer pointer; - typedef typename _MV::ss_const_iterator_type::reference reference; - - const_iterator() {} - const_iterator(const const_iterator& src_cref) : m_msevector_cshptr(src_cref.m_msevector_cshptr) { - (*this) = src_cref; - } - ~const_iterator() {} - const typename _MV::ss_const_iterator_type& msevector_ss_const_iterator_type() const { return m_ss_const_iterator; } - typename _MV::ss_const_iterator_type& msevector_ss_const_iterator_type() { return m_ss_const_iterator; } - const typename _MV::ss_const_iterator_type& mvssci() const { return msevector_ss_const_iterator_type(); } - typename _MV::ss_const_iterator_type& mvssci() { return msevector_ss_const_iterator_type(); } - - void reset() { msevector_ss_const_iterator_type().reset(); } - bool points_to_an_item() const { return msevector_ss_const_iterator_type().points_to_an_item(); } - bool points_to_end_marker() const { return msevector_ss_const_iterator_type().points_to_end_marker(); } - bool points_to_beginning() const { return msevector_ss_const_iterator_type().points_to_beginning(); } - /* has_next_item_or_end_marker() is just an alias for points_to_an_item(). */ - bool has_next_item_or_end_marker() const { return msevector_ss_const_iterator_type().has_next_item_or_end_marker(); } - /* has_next() is just an alias for points_to_an_item() that's familiar to java programmers. */ - bool has_next() const { return msevector_ss_const_iterator_type().has_next(); } - bool has_previous() const { return msevector_ss_const_iterator_type().has_previous(); } - void set_to_beginning() { msevector_ss_const_iterator_type().set_to_beginning(); } - void set_to_end_marker() { msevector_ss_const_iterator_type().set_to_end_marker(); } - void set_to_next() { msevector_ss_const_iterator_type().set_to_next(); } - void set_to_previous() { msevector_ss_const_iterator_type().set_to_previous(); } - const_iterator& operator ++() { msevector_ss_const_iterator_type().operator ++(); return (*this); } - const_iterator operator++(int) { const_iterator _Tmp = *this; ++*this; return (_Tmp); } - const_iterator& operator --() { msevector_ss_const_iterator_type().operator --(); return (*this); } - const_iterator operator--(int) { const_iterator _Tmp = *this; --*this; return (_Tmp); } - void advance(typename _MV::difference_type n) { msevector_ss_const_iterator_type().advance(n); } - void regress(typename _MV::difference_type n) { msevector_ss_const_iterator_type().regress(n); } - const_iterator& operator +=(difference_type n) { msevector_ss_const_iterator_type().operator +=(n); return (*this); } - const_iterator& operator -=(difference_type n) { msevector_ss_const_iterator_type().operator -=(n); return (*this); } - const_iterator operator+(difference_type n) const { auto retval = (*this); retval += n; return retval; } - const_iterator operator-(difference_type n) const { return ((*this) + (-n)); } - typename _MV::difference_type operator-(const const_iterator& _Right_cref) const { return msevector_ss_const_iterator_type() - (_Right_cref.msevector_ss_const_iterator_type()); } - typename _MV::const_reference operator*() const { return msevector_ss_const_iterator_type().operator*(); } - typename _MV::const_reference item() const { return operator*(); } - typename _MV::const_reference previous_item() const { return msevector_ss_const_iterator_type().previous_item(); } - typename _MV::const_pointer operator->() const { return msevector_ss_const_iterator_type().operator->(); } - typename _MV::const_reference operator[](typename _MV::difference_type _Off) const { return (*(*this + _Off)); } - bool operator==(const const_iterator& _Right_cref) const { return msevector_ss_const_iterator_type().operator==(_Right_cref.msevector_ss_const_iterator_type()); } - bool operator!=(const const_iterator& _Right_cref) const { return (!(_Right_cref == (*this))); } - bool operator<(const const_iterator& _Right) const { return (msevector_ss_const_iterator_type() < _Right.msevector_ss_const_iterator_type()); } - bool operator<=(const const_iterator& _Right) const { return (msevector_ss_const_iterator_type() <= _Right.msevector_ss_const_iterator_type()); } - bool operator>(const const_iterator& _Right) const { return (msevector_ss_const_iterator_type() > _Right.msevector_ss_const_iterator_type()); } - bool operator>=(const const_iterator& _Right) const { return (msevector_ss_const_iterator_type() >= _Right.msevector_ss_const_iterator_type()); } - void set_to_const_item_pointer(const const_iterator& _Right_cref) { msevector_ss_const_iterator_type().set_to_const_item_pointer(_Right_cref.msevector_ss_const_iterator_type()); } - msev_size_t position() const { return msevector_ss_const_iterator_type().position(); } - private: - const_iterator(std::shared_ptr<_MV> msevector_shptr) : m_msevector_cshptr(msevector_shptr) { - m_ss_const_iterator = msevector_shptr->ss_cbegin(); - } - std::shared_ptr<const _MV> m_msevector_cshptr; - /* m_ss_const_iterator needs to be declared after m_msevector_cshptr so that it's destructor will be called first. */ - typename _MV::ss_const_iterator_type m_ss_const_iterator; - friend class /*_Myt*/vector<_Ty, _A>; - friend class iterator; - }; - class iterator : public _MV::random_access_iterator_base { - public: - typedef typename _MV::ss_iterator_type::iterator_category iterator_category; - typedef typename _MV::ss_iterator_type::value_type value_type; - typedef typename _MV::ss_iterator_type::difference_type difference_type; - typedef typename _MV::difference_type distance_type; // retained - typedef typename _MV::ss_iterator_type::pointer pointer; - typedef typename _MV::ss_iterator_type::reference reference; - - iterator() {} - iterator(const iterator& src_cref) : m_msevector_shptr(src_cref.m_msevector_shptr) { - (*this) = src_cref; - } - ~iterator() {} - const typename _MV::ss_iterator_type& msevector_ss_iterator_type() const { return m_ss_iterator; } - typename _MV::ss_iterator_type& msevector_ss_iterator_type() { return m_ss_iterator; } - const typename _MV::ss_iterator_type& mvssi() const { return msevector_ss_iterator_type(); } - typename _MV::ss_iterator_type& mvssi() { return msevector_ss_iterator_type(); } - operator const_iterator() const { - const_iterator retval(m_msevector_shptr); - if (m_msevector_shptr) { - retval.msevector_ss_const_iterator_type().set_to_beginning(); - retval.msevector_ss_const_iterator_type().advance(msev_int(msevector_ss_iterator_type().position())); - } - return retval; - } - - void reset() { msevector_ss_iterator_type().reset(); } - bool points_to_an_item() const { return msevector_ss_iterator_type().points_to_an_item(); } - bool points_to_end_marker() const { return msevector_ss_iterator_type().points_to_end_marker(); } - bool points_to_beginning() const { return msevector_ss_iterator_type().points_to_beginning(); } - /* has_next_item_or_end_marker() is just an alias for points_to_an_item(). */ - bool has_next_item_or_end_marker() const { return msevector_ss_iterator_type().has_next_item_or_end_marker(); } - /* has_next() is just an alias for points_to_an_item() that's familiar to java programmers. */ - bool has_next() const { return msevector_ss_iterator_type().has_next(); } - bool has_previous() const { return msevector_ss_iterator_type().has_previous(); } - void set_to_beginning() { msevector_ss_iterator_type().set_to_beginning(); } - void set_to_end_marker() { msevector_ss_iterator_type().set_to_end_marker(); } - void set_to_next() { msevector_ss_iterator_type().set_to_next(); } - void set_to_previous() { msevector_ss_iterator_type().set_to_previous(); } - iterator& operator ++() { msevector_ss_iterator_type().operator ++(); return (*this); } - iterator operator++(int) { iterator _Tmp = *this; ++*this; return (_Tmp); } - iterator& operator --() { msevector_ss_iterator_type().operator --(); return (*this); } - iterator operator--(int) { iterator _Tmp = *this; --*this; return (_Tmp); } - void advance(typename _MV::difference_type n) { msevector_ss_iterator_type().advance(n); } - void regress(typename _MV::difference_type n) { msevector_ss_iterator_type().regress(n); } - iterator& operator +=(difference_type n) { msevector_ss_iterator_type().operator +=(n); return (*this); } - iterator& operator -=(difference_type n) { msevector_ss_iterator_type().operator -=(n); return (*this); } - iterator operator+(difference_type n) const { auto retval = (*this); retval += n; return retval; } - iterator operator-(difference_type n) const { return ((*this) + (-n)); } - typename _MV::difference_type operator-(const iterator& _Right_cref) const { return msevector_ss_iterator_type() - (_Right_cref.msevector_ss_iterator_type()); } - typename _MV::reference operator*() const { return msevector_ss_iterator_type().operator*(); } - typename _MV::reference item() const { return operator*(); } - typename _MV::reference previous_item() const { return msevector_ss_iterator_type().previous_item(); } - typename _MV::pointer operator->() const { return msevector_ss_iterator_type().operator->(); } - typename _MV::reference operator[](typename _MV::difference_type _Off) const { return (*(*this + _Off)); } - bool operator==(const iterator& _Right_cref) const { return msevector_ss_iterator_type().operator==(_Right_cref.msevector_ss_iterator_type()); } - bool operator!=(const iterator& _Right_cref) const { return (!(_Right_cref == (*this))); } - bool operator<(const iterator& _Right) const { return (msevector_ss_iterator_type() < _Right.msevector_ss_iterator_type()); } - bool operator<=(const iterator& _Right) const { return (msevector_ss_iterator_type() <= _Right.msevector_ss_iterator_type()); } - bool operator>(const iterator& _Right) const { return (msevector_ss_iterator_type() > _Right.msevector_ss_iterator_type()); } - bool operator>=(const iterator& _Right) const { return (msevector_ss_iterator_type() >= _Right.msevector_ss_iterator_type()); } - void set_to_item_pointer(const iterator& _Right_cref) { msevector_ss_iterator_type().set_to_item_pointer(_Right_cref.msevector_ss_iterator_type()); } - msev_size_t position() const { return msevector_ss_iterator_type().position(); } - private: - std::shared_ptr<_MV> m_msevector_shptr; - /* m_ss_iterator needs to be declared after m_msevector_shptr so that it's destructor will be called first. */ - typename _MV::ss_iterator_type m_ss_iterator; - friend class /*_Myt*/vector<_Ty, _A>; - }; - - iterator begin() { // return iterator for beginning of mutable sequence - iterator retval; retval.m_msevector_shptr = this->m_shptr; - (retval.m_ss_iterator) = m_shptr->ss_begin(); - return retval; - } - const_iterator begin() const { // return iterator for beginning of nonmutable sequence - const_iterator retval; retval.m_msevector_cshptr = this->m_shptr; - (retval.m_ss_const_iterator) = m_shptr->ss_begin(); - return retval; - } - iterator end() { // return iterator for end of mutable sequence - iterator retval; retval.m_msevector_shptr = this->m_shptr; - (retval.m_ss_iterator) = m_shptr->ss_end(); - return retval; - } - const_iterator end() const { // return iterator for end of nonmutable sequence - const_iterator retval; retval.m_msevector_cshptr = this->m_shptr; - (retval.m_ss_const_iterator) = m_shptr->ss_end(); - return retval; - } - const_iterator cbegin() const { // return iterator for beginning of nonmutable sequence - const_iterator retval; retval.m_msevector_cshptr = this->m_shptr; - (retval.m_ss_const_iterator) = m_shptr->ss_cbegin(); - return retval; - } - const_iterator cend() const { // return iterator for end of nonmutable sequence - const_iterator retval; retval.m_msevector_cshptr = this->m_shptr; - (retval.m_ss_const_iterator) = m_shptr->ss_cend(); - return retval; - } - - typedef std::reverse_iterator<iterator> reverse_iterator; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - - reverse_iterator rbegin() { // return iterator for beginning of reversed mutable sequence - return (reverse_iterator(end())); - } - const_reverse_iterator rbegin() const { // return iterator for beginning of reversed nonmutable sequence - return (const_reverse_iterator(end())); - } - reverse_iterator rend() { // return iterator for end of reversed mutable sequence - return (reverse_iterator(begin())); - } - const_reverse_iterator rend() const { // return iterator for end of reversed nonmutable sequence - return (const_reverse_iterator(begin())); - } - const_reverse_iterator crbegin() const { // return iterator for beginning of reversed nonmutable sequence - return (rbegin()); - } - const_reverse_iterator crend() const { // return iterator for end of reversed nonmutable sequence - return (rend()); - } - - - vector(const const_iterator &start, const const_iterator &end, const _A& _Al = _A()) - : m_shptr(std::make_shared<_MV>(start.msevector_ss_const_iterator_type(), end.msevector_ss_const_iterator_type(), _Al)) {} - void assign(const const_iterator &start, const const_iterator &end) { - m_shptr->assign(start.msevector_ss_const_iterator_type(), end.msevector_ss_const_iterator_type()); - } - void assign_inclusive(const const_iterator &first, const const_iterator &last) { - m_shptr->assign_inclusive(first.msevector_ss_const_iterator_type(), last.msevector_ss_const_iterator_type()); - } - iterator insert_before(const const_iterator &pos, size_type _M, const _Ty& _X) { - auto res = m_shptr->insert_before(pos.msevector_ss_const_iterator_type(), _M, _X); - iterator retval = begin(); retval.msevector_ss_iterator_type() = res; - return retval; - } - iterator insert_before(const const_iterator &pos, _Ty&& _X) { - auto res = m_shptr->insert_before(pos.msevector_ss_const_iterator_type(), std::move(_X)); - iterator retval = begin(); retval.msevector_ss_iterator_type() = res; - return retval; - } - iterator insert_before(const const_iterator &pos, const _Ty& _X = _Ty()) { return insert_before(pos, 1, _X); } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - iterator insert_before(const const_iterator &pos, const _Iter &start, const _Iter &end) { - auto res = m_shptr->insert_before(pos.msevector_ss_const_iterator_type(), start, end); - iterator retval = begin(); retval.msevector_ss_iterator_type() = res; - return retval; - } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - iterator insert_before_inclusive(const const_iterator &pos, const _Iter &first, const _Iter &last) { - auto end = last; end++; - return insert_before(pos, first, end); - } - iterator insert_before(const const_iterator &pos, _XSTD initializer_list<typename _MV::value_type> _Ilist) { // insert initializer_list - auto res = m_shptr->insert_before(pos.msevector_ss_const_iterator_type(), _Ilist); - iterator retval = begin(); retval.msevector_ss_iterator_type() = res; - return retval; - } - void insert_before(msev_size_t pos, const _Ty& _X = _Ty()) { - m_shptr->insert_before(pos, _X); - } - void insert_before(msev_size_t pos, size_type _M, const _Ty& _X) { - m_shptr->insert_before(pos, _M, _X); - } - void insert_before(msev_size_t pos, _XSTD initializer_list<typename _MV::value_type> _Ilist) { // insert initializer_list - m_shptr->insert_before(pos, _Ilist); - } - /* These insert() functions are just aliases for their corresponding insert_before() functions. */ - iterator insert(const const_iterator &pos, size_type _M, const _Ty& _X) { return insert_before(pos, _M, _X); } - iterator insert(const const_iterator &pos, _Ty&& _X) { return insert_before(pos, std::move(_X)); } - iterator insert(const const_iterator &pos, const _Ty& _X = _Ty()) { return insert_before(pos, _X); } - template<class _Iter - //>typename std::enable_if<_mse_Is_iterator<_Iter>::value, typename base_class::iterator>::type - , class = _mse_RequireInputIter<_Iter> > - iterator insert(const const_iterator &pos, const _Iter &start, const _Iter &end) { return insert_before(pos, start, end); } - iterator insert(const const_iterator &pos, const _Ty* start, const _Ty* end) { return insert_before(pos, start, end); } - iterator insert(const const_iterator &pos, _XSTD initializer_list<typename _MV::value_type> _Ilist) { return insert_before(pos, _Ilist); } - template<class ..._Valty> - iterator emplace(const const_iterator &pos, _Valty&& ..._Val) { - auto res = m_shptr->emplace(pos.msevector_ss_const_iterator_type(), std::forward<_Valty>(_Val)...); - iterator retval = begin(); retval.msevector_ss_iterator_type() = res; - return retval; - } - iterator erase(const const_iterator &pos) { - auto res = m_shptr->erase(pos.msevector_ss_const_iterator_type()); - iterator retval = begin(); retval.msevector_ss_iterator_type() = res; - return retval; - } - iterator erase(const const_iterator &start, const const_iterator &end) { - auto res = m_shptr->erase(start.msevector_ss_const_iterator_type(), end.msevector_ss_const_iterator_type()); - iterator retval = begin(); retval.msevector_ss_iterator_type() = res; - return retval; - } - iterator erase_inclusive(const const_iterator &first, const const_iterator &last) { - auto end = last; end.set_to_next(); - return erase_inclusive(first, end); - } - bool operator==(const _Myt& _Right) const { // test for vector equality - return ((*(_Right.m_shptr)) == (*m_shptr)); - } - bool operator<(const _Myt& _Right) const { // test if _Left < _Right for vectors - return ((*m_shptr) < (*(_Right.m_shptr))); - } - - private: - std::shared_ptr<_MV> m_shptr; - }; - - template<class _Ty, class _Alloc> inline bool operator!=(const vector<_Ty, _Alloc>& _Left, - const vector<_Ty, _Alloc>& _Right) { // test for vector inequality - return (!(_Left == _Right)); - } - - template<class _Ty, class _Alloc> inline bool operator>(const vector<_Ty, _Alloc>& _Left, - const vector<_Ty, _Alloc>& _Right) { // test if _Left > _Right for vectors - return (_Right < _Left); - } - - template<class _Ty, class _Alloc> inline bool operator<=(const vector<_Ty, _Alloc>& _Left, - const vector<_Ty, _Alloc>& _Right) { // test if _Left <= _Right for vectors - return (!(_Right < _Left)); - } - - template<class _Ty, class _Alloc> inline bool operator>=(const vector<_Ty, _Alloc>& _Left, - const vector<_Ty, _Alloc>& _Right) { // test if _Left >= _Right for vectors - return (!(_Left < _Right)); - } -#endif /*MSE_MSTDVECTOR_DISABLED*/ - } -} -#endif /*ndef MSEMSTDVECTOR_H*/ diff --git a/src/debug/mse/mseprimitives.h b/src/debug/mse/mseprimitives.h deleted file mode 100644 index 951577834..000000000 --- a/src/debug/mse/mseprimitives.h +++ /dev/null @@ -1,872 +0,0 @@ - -// Copyright (c) 2015 Noah Lopez -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef MSEPRIMITIVES_H -#define MSEPRIMITIVES_H - -#include <assert.h> -#include <climits> // ULONG_MAX -#include <limits> // std::numeric_limits -#include <stdexcept> // primitives_range_error - -/*compiler specific defines*/ -#ifdef _MSC_VER -#if (1700 > _MSC_VER) -#define MSVC2010_COMPATIBLE 1 -#endif /*(1700 > _MSC_VER)*/ -#if (1900 > _MSC_VER) -#define MSVC2013_COMPATIBLE 1 -#endif /*(1900 > _MSC_VER)*/ -#if (2000 > _MSC_VER) -#define MSVC2015_COMPATIBLE 1 -#endif /*(1900 > _MSC_VER)*/ -#else /*_MSC_VER*/ -#if (defined(__GNUC__) || defined(__GNUG__)) -#define GPP_COMPATIBLE 1 -#if ((5 > __GNUC__) && (!defined(__clang__))) -#define GPP4P8_COMPATIBLE 1 -#endif /*((5 > __GNUC__) && (!defined(__clang__)))*/ -#endif /*(defined(__GNUC__) || defined(__GNUG__))*/ -#endif /*_MSC_VER*/ - -#ifdef MSE_SAFER_SUBSTITUTES_DISABLED -#define MSE_PRIMITIVES_DISABLED -#endif /*MSE_SAFER_SUBSTITUTES_DISABLED*/ - -#if defined(MSVC2013_COMPATIBLE) || defined(MSVC2010_COMPATIBLE) -#define MSE_CONSTEXPR -#else // defined(MSVC2013_COMPATIBLE) || defined(MSVC2010_COMPATIBLE) -#define MSE_CONSTEXPR constexpr -#endif // defined(MSVC2013_COMPATIBLE) || defined(MSVC2010_COMPATIBLE) - -#ifdef MSVC2015_COMPATIBLE -#ifndef MSE_FORCE_PRIMITIVE_ASSIGN_RANGE_CHECK_ENABLED -/* msvc2015's incomplete support for "constexpr" means that range checks that should be done at compile time would -be done at run time, at significant cost. So by default we disable range checks upon assignment. */ -#define MSE_PRIMITIVE_ASSIGN_RANGE_CHECK_DISABLED 1 -#endif // !MSE_FORCE_PRIMITIVE_ASSIGN_RANGE_CHECK_ENABLED -#endif // MSVC2015_COMPATIBLE - - -#ifdef MSE_CUSTOM_THROW_DEFINITION -#include <iostream> -#define MSE_THROW(x) MSE_CUSTOM_THROW_DEFINITION(x) -#else // MSE_CUSTOM_THROW_DEFINITION -#define MSE_THROW(x) throw(x) -#endif // MSE_CUSTOM_THROW_DEFINITION - - -#ifndef MSE_CINT_BASE_INTEGER_TYPE -#if SIZE_MAX <= ULONG_MAX -#define MSE_CINT_BASE_INTEGER_TYPE long int -#else // SIZE_MAX <= ULONG_MAX -#define MSE_CINT_BASE_INTEGER_TYPE long long int -#endif // SIZE_MAX <= ULONG_MAX -#endif // !MSE_CINT_BASE_INTEGER_TYPE - - -namespace mse { - - class primitives_range_error : public std::range_error { - public: - using std::range_error::range_error; - }; - - /* When the mse primitive replacements are "disabled" they lose their default initialization and may cause problems for - code that relies on it. */ -#ifdef MSE_PRIMITIVES_DISABLED - typedef bool CBool; - typedef MSE_CINT_BASE_INTEGER_TYPE CInt; - typedef size_t CSize_t; - static size_t as_a_size_t(CSize_t n) { return (n); } -#else /*MSE_PRIMITIVES_DISABLED*/ - -#ifndef NDEBUG -#ifndef MSE_SUPPRESS_CHECK_USE_BEFORE_SET -#define MSE_CHECK_USE_BEFORE_SET -#endif // !MSE_SUPPRESS_CHECK_USE_BEFORE_SET -#endif // !NDEBUG - - /* This class is just meant to act like the "bool" type, except that it has a default intialization value (false). */ - class CBool { - public: - // Constructs zero. - CBool() : m_val(false) {} - - // Copy constructor - CBool(const CBool &x) : m_val(x.m_val) { note_value_assignment(); }; - - // Assignment operator - CBool& operator=(const CBool &x) { note_value_assignment(); m_val = x.m_val; return (*this); } - - // Constructors from primitive boolean types - CBool(bool x) { note_value_assignment(); m_val = x; } - - // Casts to primitive boolean types - operator bool() const { assert_initialized(); return m_val; } - - CBool& operator |=(const CBool &x) { assert_initialized(); m_val |= x.m_val; return (*this); } - CBool& operator &=(const CBool &x) { assert_initialized(); m_val &= x.m_val; return (*this); } - CBool& operator ^=(const CBool &x) { assert_initialized(); m_val ^= x.m_val; return (*this); } - - bool m_val; - -#ifdef MSE_CHECK_USE_BEFORE_SET - void note_value_assignment() { m_initialized = true; } - void assert_initialized() const { assert(m_initialized); } - bool m_initialized = false; -#else // MSE_CHECK_USE_BEFORE_SET - void note_value_assignment() {} - void assert_initialized() const {} -#endif // MSE_CHECK_USE_BEFORE_SET - }; - - - template<typename _TDestination, typename _TSource> - MSE_CONSTEXPR static bool sg_can_exceed_upper_bound() { - return ( - ((std::numeric_limits<_TSource>::is_signed == std::numeric_limits<_TDestination>::is_signed) - && (std::numeric_limits<_TSource>::digits > std::numeric_limits<_TDestination>::digits)) - || ((std::numeric_limits<_TSource>::is_signed != std::numeric_limits<_TDestination>::is_signed) - && ((std::numeric_limits<_TSource>::is_signed && (std::numeric_limits<_TSource>::digits > (1 + std::numeric_limits<_TDestination>::digits))) - || ((!std::numeric_limits<_TSource>::is_signed) && ((1 + std::numeric_limits<_TSource>::digits) > std::numeric_limits<_TDestination>::digits)) - ) - ) - ); - } - template<typename _TDestination, typename _TSource> - MSE_CONSTEXPR static bool sg_can_exceed_lower_bound() { - return ( - (std::numeric_limits<_TSource>::is_signed && (!std::numeric_limits<_TDestination>::is_signed)) - || (std::numeric_limits<_TSource>::is_signed && (std::numeric_limits<_TSource>::digits > std::numeric_limits<_TDestination>::digits)) - ); - } - - template<typename _TDestination, typename _TSource> - void g_assign_check_range(const _TSource &x) { -#ifndef MSE_PRIMITIVE_ASSIGN_RANGE_CHECK_DISABLED - /* This probably needs to be cleaned up. But at the moment this should be mostly compile time complexity. And - as is it avoids "signed/unsigned" mismatch warnings. */ - MSE_CONSTEXPR const bool rhs_can_exceed_upper_bound = sg_can_exceed_upper_bound<_TDestination, _TSource>(); - MSE_CONSTEXPR const bool rhs_can_exceed_lower_bound = sg_can_exceed_lower_bound<_TDestination, _TSource>(); - MSE_CONSTEXPR const bool can_exceed_bounds = rhs_can_exceed_upper_bound || rhs_can_exceed_lower_bound; - if (can_exceed_bounds) { - if (rhs_can_exceed_upper_bound) { - if (x > _TSource(std::numeric_limits<_TDestination>::max())) { - MSE_THROW(primitives_range_error("range error - value to be assigned is out of range of the target (integer) type")); - } - } - if (rhs_can_exceed_lower_bound) { - /* We're assuming that std::numeric_limits<>::lowest() will never be greater than zero. */ - if (0 > x) { - if (0 == std::numeric_limits<_TDestination>::lowest()) { - MSE_THROW(primitives_range_error("range error - value to be assigned is out of range of the target (integer) type")); - } - else if (x < _TSource(std::numeric_limits<_TDestination>::lowest())) { - MSE_THROW(primitives_range_error("range error - value to be assigned is out of range of the target (integer) type")); - } - } - } - } -#endif // !MSE_PRIMITIVE_ASSIGN_RANGE_CHECK_DISABLED - } - - /* The CInt and CSize_t classes are meant to substitute for standard "int" and "size_t" types. The differences between - the standard types and these classes are that the classes have a default intialization value (zero), and the - classes, as much as possible, try to prevent the problematic behaviour of (possibly negative) signed integers - being cast (inadvertently) to the unsigned size_t type. For example, the expression (0 > (int)5 - (size_t)7) evaluates - (unintuitively) to false, whereas the expression (0 > (CInt)5 - (CSize_t)7) evaluates to true. Also, the classes do - some range checking. For example, the code "CSize_t s = -2;" will throw an exception. */ - template<typename _Ty> - class TIntBase1 { - public: - // Constructs zero. - TIntBase1() : m_val(0) {} - - // Copy constructor - TIntBase1(const TIntBase1 &x) : m_val(x.m_val) { note_value_assignment(); }; - - // Constructors from primitive integer types - explicit TIntBase1(_Ty x) { note_value_assignment(); m_val = x; } - - template<typename _Tz> - void assign_check_range(const _Tz &x) { - note_value_assignment(); - g_assign_check_range<_Ty, _Tz>(x); - } - - _Ty m_val; - -#ifdef MSE_CHECK_USE_BEFORE_SET - void note_value_assignment() { m_initialized = true; } - void assert_initialized() const { assert(m_initialized); } - bool m_initialized = false; -#else // MSE_CHECK_USE_BEFORE_SET - void note_value_assignment() {} - void assert_initialized() const {} -#endif // MSE_CHECK_USE_BEFORE_SET - }; - - class CInt : public TIntBase1<MSE_CINT_BASE_INTEGER_TYPE> { - public: - typedef MSE_CINT_BASE_INTEGER_TYPE _Ty; - typedef TIntBase1<_Ty> _Myt; - - // Constructs zero. - CInt() : _Myt() {} - - // Copy constructor - CInt(const CInt &x) : _Myt(x) {}; - CInt(const _Myt &x) : _Myt(x) {}; - - // Assignment operator - CInt& operator=(const CInt &x) { (*this).note_value_assignment(); m_val = x.m_val; return (*this); } - //CInt& operator=(const _Ty &x) { (*this).note_value_assignment(); m_val = x; return (*this); } - - CInt& operator=(long long x) { assign_check_range<long long>(x); m_val = static_cast<_Ty>(x); return (*this); } - CInt& operator=(long x) { assign_check_range<long>(x); m_val = static_cast<_Ty>(x); return (*this); } - CInt& operator=(int x) { assign_check_range<int>(x); m_val = static_cast<_Ty>(x); return (*this); } - CInt& operator=(short x) { assign_check_range<short>(x); m_val = static_cast<_Ty>(x); return (*this); } - CInt& operator=(char x) { assign_check_range<char>(x); m_val = static_cast<_Ty>(x); return (*this); } - CInt& operator=(size_t x) { assign_check_range<size_t>(x); m_val = static_cast<_Ty>(x); return (*this); } - //CInt& operator=(CSize_t x) { assign_check_range<size_t>(x.as_a_size_t()); m_val = x.as_a_size_t(); return (*this); } - /* We would have liked to have assignment operators for the unsigned primitive integer types, but one of them could - potentially clash with the size_t assignment operator. */ - //CInt& operator=(unsigned long long x) { assign_check_range<unsigned long long>(x); m_val = static_cast<_Ty>(x); return (*this); } - //CInt& operator=(unsigned long x) { assign_check_range<unsigned long>(x); m_val = static_cast<_Ty>(x); return (*this); } - //CInt& operator=(unsigned int x) { assign_check_range<unsigned int>(x); m_val = static_cast<_Ty>(x); return (*this); } - //CInt& operator=(unsigned short x) { assign_check_range<unsigned short>(x); m_val = static_cast<_Ty>(x); return (*this); } - //CInt& operator=(unsigned char x) { assign_check_range<unsigned char>(x); m_val = static_cast<_Ty>(x); return (*this); } - - // Constructors from primitive integer types - //CInt(_Ty x) { m_val = x; } - CInt(long long x) { assign_check_range<long long>(x); m_val = static_cast<_Ty>(x); } - CInt(long x) { assign_check_range< long>(x); m_val = static_cast<_Ty>(x); } - CInt(int x) { assign_check_range<int>(x); m_val = static_cast<_Ty>(x); } - CInt(short x) { assign_check_range<short>(x); m_val = static_cast<_Ty>(x); } - CInt(char x) { assign_check_range<char>(x); m_val = static_cast<_Ty>(x); } - CInt(size_t x) { assign_check_range<size_t>(x); m_val = static_cast<_Ty>(x); } - //CInt(CSize_t x) { assign_check_range<size_t>(x.as_a_size_t()); m_val = x.as_a_size_t(); } - /* We would have liked to have constructors for the unsigned primitive integer types, but one of them could - potentially clash with the size_t constructor. */ - //CInt(unsigned long long x) { assign_check_range<unsigned long long>(x); m_val = static_cast<_Ty>(x); } - //CInt(unsigned long x) { assign_check_range<unsigned long>(x); m_val = static_cast<_Ty>(x); } - //CInt(unsigned int x) { assign_check_range<unsigned int>(x); m_val = static_cast<_Ty>(x); } - //CInt(unsigned short x) { assign_check_range<unsigned short>(x); m_val = static_cast<_Ty>(x); } - //CInt(unsigned char x) { assign_check_range<unsigned char>(x); m_val = static_cast<_Ty>(x); } - - // Casts to primitive integer types - operator _Ty() const { (*this).assert_initialized(); return m_val; } - - CInt operator ~() const { (*this).assert_initialized(); return CInt(~m_val); } - CInt& operator |=(const CInt &x) { (*this).assert_initialized(); m_val |= x.m_val; return (*this); } - CInt& operator &=(const CInt &x) { (*this).assert_initialized(); m_val &= x.m_val; return (*this); } - CInt& operator ^=(const CInt &x) { (*this).assert_initialized(); m_val ^= x.m_val; return (*this); } - - CInt operator -() const { (*this).assert_initialized(); return CInt(-m_val); } - CInt& operator +=(const CInt &x) { (*this).assert_initialized(); m_val += x.m_val; return (*this); } - CInt& operator -=(const CInt &x) { (*this).assert_initialized(); m_val -= x.m_val; return (*this); } - CInt& operator *=(const CInt &x) { (*this).assert_initialized(); m_val *= x.m_val; return (*this); } - CInt& operator /=(const CInt &x) { (*this).assert_initialized(); m_val /= x.m_val; return (*this); } - CInt& operator %=(const CInt &x) { (*this).assert_initialized(); m_val %= x.m_val; return (*this); } - CInt& operator >>=(const CInt &x) { (*this).assert_initialized(); m_val >>= x.m_val; return (*this); } - CInt& operator <<=(const CInt &x) { (*this).assert_initialized(); m_val <<= x.m_val; return (*this); } - - CInt operator +(const CInt &x) const { (*this).assert_initialized(); return CInt(m_val + x.m_val); } - CInt operator +(long long x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - CInt operator +(long x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - CInt operator +(int x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - CInt operator +(short x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - CInt operator +(char x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - CInt operator +(size_t x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - //CInt operator +(CSize_t x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - - CInt operator -(const CInt &x) const { (*this).assert_initialized(); return CInt(m_val - x.m_val); } - CInt operator -(long long x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - CInt operator -(long x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - CInt operator -(int x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - CInt operator -(short x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - CInt operator -(char x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - CInt operator -(size_t x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - //CInt operator -(CSize_t x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - - CInt operator *(const CInt &x) const { (*this).assert_initialized(); return CInt(m_val * x.m_val); } - CInt operator *(long long x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - CInt operator *(long x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - CInt operator *(int x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - CInt operator *(short x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - CInt operator *(char x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - CInt operator *(size_t x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - //CInt operator *(CSize_t x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - - CInt operator /(const CInt &x) const { (*this).assert_initialized(); return CInt(m_val / x.m_val); } - CInt operator /(long long x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - CInt operator /(long x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - CInt operator /(int x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - CInt operator /(short x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - CInt operator /(char x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - CInt operator /(size_t x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - //CInt operator /(CSize_t x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - - bool operator <(const CInt &x) const { (*this).assert_initialized(); return (m_val < x.m_val); } - bool operator <(long long x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - bool operator <(long x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - bool operator <(int x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - bool operator <(short x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - bool operator <(char x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - bool operator <(size_t x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - //bool operator <(CSize_t x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - - bool operator >(const CInt &x) const { (*this).assert_initialized(); return (m_val > x.m_val); } - bool operator >(long long x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - bool operator >(long x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - bool operator >(int x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - bool operator >(short x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - bool operator >(char x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - bool operator >(size_t x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - //bool operator >(CSize_t x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - - bool operator <=(const CInt &x) const { (*this).assert_initialized(); return (m_val <= x.m_val); } - bool operator <=(long long x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - bool operator <=(long x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - bool operator <=(int x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - bool operator <=(short x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - bool operator <=(char x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - bool operator <=(size_t x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - //bool operator <=(CSize_t x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - - bool operator >=(const CInt &x) const { (*this).assert_initialized(); return (m_val >= x.m_val); } - bool operator >=(long long x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - bool operator >=(long x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - bool operator >=(int x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - bool operator >=(short x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - bool operator >=(char x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - bool operator >=(size_t x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - //bool operator >=(CSize_t x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - - bool operator ==(const CInt &x) const { (*this).assert_initialized(); return (m_val == x.m_val); } - bool operator ==(long long x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - bool operator ==(long x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - bool operator ==(int x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - bool operator ==(short x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - bool operator ==(char x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - bool operator ==(size_t x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - //bool operator ==(CSize_t x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - - bool operator !=(const CInt &x) const { (*this).assert_initialized(); return (m_val != x.m_val); } - bool operator !=(long long x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - bool operator !=(long x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - bool operator !=(int x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - bool operator !=(short x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - bool operator !=(char x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - bool operator !=(size_t x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - //bool operator !=(CSize_t x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - - // INCREMENT/DECREMENT OPERATORS - CInt& operator ++() { (*this).assert_initialized(); m_val++; return (*this); } - CInt operator ++(int) { - (*this).assert_initialized(); - CInt tmp(*this); // copy - operator++(); // pre-increment - return tmp; // return old value - } - CInt& operator --() { - (*this).assert_initialized(); - if (0 <= std::numeric_limits<_Ty>::lowest()) { - (*this).assert_initialized(); - (*this) = (*this) - 1; return (*this); - } - else { - (*this).assert_initialized(); - m_val--; return (*this); - } - } - CInt operator --(int) { - (*this).assert_initialized(); - CInt tmp(*this); // copy - operator--(); // pre-decrement - return tmp; // return old value - } - - //_Ty m_val; - }; -} - -namespace std { -#ifndef _THROW0 -#define _THROW0() -#endif // !_THROW0 -#ifndef _STCONS -#define _STCONS(ty, name, val) static constexpr ty name = static_cast<ty>(val) -#endif // !_STCONS - - template<> class numeric_limits<mse::CInt> { // limits for type int - public: - typedef MSE_CINT_BASE_INTEGER_TYPE _Ty; - - static constexpr _Ty(min)() _THROW0() - { // return minimum value - return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::min(); - } - static constexpr _Ty(max)() _THROW0() - { // return maximum value - return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::max(); - } - static constexpr _Ty lowest() _THROW0() - { // return most negative value - return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::lowest(); - } - static constexpr _Ty epsilon() _THROW0() - { // return smallest effective increment from 1.0 - return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::epsilon(); - } - static constexpr _Ty round_error() _THROW0() - { // return largest rounding error - return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::round_error(); - } - static constexpr _Ty denorm_min() _THROW0() - { // return minimum denormalized value - return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::denorm_min(); - } - static constexpr _Ty infinity() _THROW0() - { // return positive infinity - return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::infinity(); - } - static constexpr _Ty quiet_NaN() _THROW0() - { // return non-signaling NaN - return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::quiet_NaN(); - } - static constexpr _Ty signaling_NaN() _THROW0() - { // return signaling NaN - return numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::signaling_NaN(); - } - _STCONS(float_denorm_style, has_denorm, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::has_denorm); - _STCONS(bool, has_denorm_loss, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::has_denorm_loss); - _STCONS(bool, has_infinity, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::has_infinity); - _STCONS(bool, has_quiet_NaN, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::has_quiet_NaN); - _STCONS(bool, has_signaling_NaN, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::has_signaling_NaN); - _STCONS(bool, is_bounded, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_bounded); - _STCONS(bool, is_exact, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_exact); - _STCONS(bool, is_iec559, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_iec559); - _STCONS(bool, is_integer, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_integer); - _STCONS(bool, is_modulo, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_modulo); - _STCONS(bool, is_signed, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_signed); - _STCONS(bool, is_specialized, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::is_specialized); - _STCONS(bool, tinyness_before, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::tinyness_before); - _STCONS(bool, traps, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::traps); - _STCONS(float_round_style, round_style, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::round_style); - _STCONS(int, digits, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::digits); - _STCONS(int, digits10, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::digits10); - _STCONS(int, max_digits10, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::max_digits10); - _STCONS(int, max_exponent, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::max_exponent); - _STCONS(int, max_exponent10, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::max_exponent10); - _STCONS(int, min_exponent, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::min_exponent); - _STCONS(int, min_exponent10, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::min_exponent10); - _STCONS(int, radix, numeric_limits<MSE_CINT_BASE_INTEGER_TYPE>::radix); - }; -} - -namespace mse { - class CSize_t; - static size_t as_a_size_t(CSize_t n); - - /* Note that CSize_t does not have a default conversion to size_t. This is by design. Use the as_a_size_t() member - function to get a size_t when necessary. */ - class CSize_t : public TIntBase1<size_t> { - public: - typedef size_t _Ty; - typedef int _T_signed_primitive_integer_type; - typedef TIntBase1<_Ty> _Myt; - - // Constructs zero. - CSize_t() : _Myt() {} - - // Copy constructor - CSize_t(const CSize_t &x) : _Myt(x) {}; - CSize_t(const _Myt &x) : _Myt(x) {}; - - // Assignment operator - CSize_t& operator=(const CSize_t &x) { m_val = x.m_val; return (*this); } - //CSize_t& operator=(const _Ty &x) { m_val = x; return (*this); } - - CSize_t& operator=(long long x) { assign_check_range<long long>(x); m_val = static_cast<_Ty>(x); return (*this); } - CSize_t& operator=(long x) { assign_check_range<long>(x); m_val = static_cast<_Ty>(x); return (*this); } - CSize_t& operator=(int x) { assign_check_range<int>(x); m_val = static_cast<_Ty>(x); return (*this); } - CSize_t& operator=(short x) { assign_check_range<short>(x); m_val = static_cast<_Ty>(x); return (*this); } - CSize_t& operator=(char x) { assign_check_range<char>(x); m_val = static_cast<_Ty>(x); return (*this); } - CSize_t& operator=(size_t x) { assign_check_range<size_t>(x); m_val = static_cast<_Ty>(x); return (*this); } - CSize_t& operator=(CInt x) { assign_check_range<MSE_CINT_BASE_INTEGER_TYPE>(x); m_val = static_cast<_Ty>(x); return (*this); } - /* We would have liked to have assignment operators for the unsigned primitive integer types, but one of them could - potentially clash with the size_t assignment operator. */ - //CSize_t& operator=(unsigned long long x) { assign_check_range<unsigned long long>(x); m_val = static_cast<_Ty>(x); return (*this); } - //CSize_t& operator=(unsigned long x) { assign_check_range<unsigned long>(x); m_val = static_cast<_Ty>(x); return (*this); } - //CSize_t& operator=(unsigned int x) { assign_check_range<unsigned int>(x); m_val = static_cast<_Ty>(x); return (*this); } - //CSize_t& operator=(unsigned short x) { assign_check_range<unsigned short>(x); m_val = static_cast<_Ty>(x); return (*this); } - //CSize_t& operator=(unsigned char x) { assign_check_range<unsigned char>(x); m_val = static_cast<_Ty>(x); return (*this); } - - // Constructors from primitive integer types - //explicit CSize_t(_Ty x) { m_val = x; } - explicit CSize_t(long long x) { assign_check_range<long long>(x); m_val = static_cast<_Ty>(x); } - explicit CSize_t(long x) { assign_check_range< long>(x); m_val = static_cast<_Ty>(x); } - explicit CSize_t(int x) { assign_check_range<int>(x); m_val = static_cast<_Ty>(x); } - explicit CSize_t(short x) { assign_check_range<short>(x); m_val = static_cast<_Ty>(x); } - explicit CSize_t(char x) { assign_check_range<char>(x); m_val = static_cast<_Ty>(x); } - CSize_t(size_t x) { assign_check_range<size_t>(x); m_val = static_cast<_Ty>(x); } - /*explicit */CSize_t(CInt x) { assign_check_range<MSE_CINT_BASE_INTEGER_TYPE>(x); m_val = static_cast<_Ty>(x); } - /* We would have liked to have constructors for the unsigned primitive integer types, but one of them could - potentially clash with the size_t constructor. */ - //explicit CSize_t(unsigned long long x) { assign_check_range<unsigned long long>(x); m_val = static_cast<_Ty>(x); } - //explicit CSize_t(unsigned long x) { assign_check_range<unsigned long>(x); m_val = static_cast<_Ty>(x); } - //explicit CSize_t(unsigned int x) { assign_check_range<unsigned int>(x); m_val = static_cast<_Ty>(x); } - //explicit CSize_t(unsigned short x) { assign_check_range<unsigned short>(x); m_val = static_cast<_Ty>(x); } - //explicit CSize_t(unsigned char x) { assign_check_range<unsigned char>(x); m_val = static_cast<_Ty>(x); } - - // Casts to primitive integer types - operator CInt() const { (*this).assert_initialized(); return CInt(m_val); } -#ifndef MSVC2010_COMPATIBLE - explicit operator size_t() const { (*this).assert_initialized(); return (m_val); } -#endif /*MSVC2010_COMPATIBLE*/ - //size_t as_a_size_t() const { (*this).assert_initialized(); return m_val; } - - CSize_t operator ~() const { (*this).assert_initialized(); return (~m_val); } - CSize_t& operator |=(const CSize_t &x) { (*this).assert_initialized(); m_val |= x.m_val; return (*this); } - CSize_t& operator &=(const CSize_t &x) { (*this).assert_initialized(); m_val &= x.m_val; return (*this); } - CSize_t& operator ^=(const CSize_t &x) { (*this).assert_initialized(); m_val ^= x.m_val; return (*this); } - - CInt operator -() const { (*this).assert_initialized(); /* Should unsigned types even support this opperator? */ - return (-(CInt(m_val))); - } - CSize_t& operator +=(const CSize_t &x) { (*this).assert_initialized(); m_val += x.m_val; return (*this); } - CSize_t& operator -=(const CSize_t &x) { - (*this).assert_initialized(); - //assert(0 <= std::numeric_limits<_Ty>::lowest()); - if (x.m_val > m_val) { - MSE_THROW(primitives_range_error("range error - value to be assigned is out of range of the target (integer) type")); - } - m_val -= x.m_val; return (*this); - } - CSize_t& operator *=(const CSize_t &x) { (*this).assert_initialized(); m_val *= x.m_val; return (*this); } - CSize_t& operator /=(const CSize_t &x) { (*this).assert_initialized(); m_val /= x.m_val; return (*this); } - CSize_t& operator %=(const CSize_t &x) { (*this).assert_initialized(); m_val %= x.m_val; return (*this); } - CSize_t& operator >>=(const CSize_t &x) { (*this).assert_initialized(); m_val >>= x.m_val; return (*this); } - CSize_t& operator <<=(const CSize_t &x) { (*this).assert_initialized(); m_val <<= x.m_val; return (*this); } - - CSize_t operator +(const CSize_t &x) const { (*this).assert_initialized(); return (m_val + x.m_val); } - CInt operator +(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) + x); } - CInt operator +(long long x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - CInt operator +(long x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - CInt operator +(int x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - CInt operator +(short x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - CInt operator +(char x) const { (*this).assert_initialized(); return ((*this) + CInt(x)); } - CSize_t operator +(size_t x) const { (*this).assert_initialized(); return ((*this) + CSize_t(x)); } - - CInt operator -(const CSize_t &x) const { (*this).assert_initialized(); return (CInt(m_val) - CInt(x.m_val)); } - CInt operator -(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) - x); } - CInt operator -(long long x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - CInt operator -(long x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - CInt operator -(int x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - CInt operator -(short x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - CInt operator -(char x) const { (*this).assert_initialized(); return ((*this) - CInt(x)); } - CInt operator -(size_t x) const { (*this).assert_initialized(); return ((*this) - CSize_t(x)); } - - CSize_t operator *(const CSize_t &x) const { (*this).assert_initialized(); return (m_val * x.m_val); } - CInt operator *(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) * x); } - CInt operator *(long long x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - CInt operator *(long x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - CInt operator *(int x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - CInt operator *(short x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - CInt operator *(char x) const { (*this).assert_initialized(); return ((*this) * CInt(x)); } - CSize_t operator *(size_t x) const { (*this).assert_initialized(); return ((*this) * CSize_t(x)); } - - CSize_t operator /(const CSize_t &x) const { (*this).assert_initialized(); return (m_val / x.m_val); } - CInt operator /(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) / x); } - CInt operator /(long long x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - CInt operator /(long x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - CInt operator /(int x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - CInt operator /(short x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - CInt operator /(char x) const { (*this).assert_initialized(); return ((*this) / CInt(x)); } - CSize_t operator /(size_t x) const { (*this).assert_initialized(); return ((*this) / CSize_t(x)); } - - bool operator <(const CSize_t &x) const { (*this).assert_initialized(); return (m_val < x.m_val); } - bool operator <(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) < x); } - bool operator <(long long x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - bool operator <(long x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - bool operator <(int x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - bool operator <(short x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - bool operator <(char x) const { (*this).assert_initialized(); return ((*this) < CInt(x)); } - bool operator <(size_t x) const { (*this).assert_initialized(); return ((*this) < CSize_t(x)); } - - bool operator >(const CSize_t &x) const { (*this).assert_initialized(); return (m_val > x.m_val); } - bool operator >(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) > x); } - bool operator >(long long x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - bool operator >(long x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - bool operator >(int x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - bool operator >(short x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - bool operator >(char x) const { (*this).assert_initialized(); return ((*this) > CInt(x)); } - bool operator >(size_t x) const { (*this).assert_initialized(); return ((*this) > CSize_t(x)); } - - bool operator <=(const CSize_t &x) const { (*this).assert_initialized(); return (m_val <= x.m_val); } - bool operator <=(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) <= x); } - bool operator <=(long long x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - bool operator <=(long x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - bool operator <=(int x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - bool operator <=(short x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - bool operator <=(char x) const { (*this).assert_initialized(); return ((*this) <= CInt(x)); } - bool operator <=(size_t x) const { (*this).assert_initialized(); return ((*this) <= CSize_t(x)); } - - bool operator >=(const CSize_t &x) const { (*this).assert_initialized(); return (m_val >= x.m_val); } - bool operator >=(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) >= x); } - bool operator >=(long long x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - bool operator >=(long x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - bool operator >=(int x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - bool operator >=(short x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - bool operator >=(char x) const { (*this).assert_initialized(); return ((*this) >= CInt(x)); } - bool operator >=(size_t x) const { (*this).assert_initialized(); return ((*this) >= CSize_t(x)); } - - bool operator ==(const CSize_t &x) const { (*this).assert_initialized(); return (m_val == x.m_val); } - bool operator ==(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) == x); } - bool operator ==(long long x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - bool operator ==(long x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - bool operator ==(int x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - bool operator ==(short x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - bool operator ==(char x) const { (*this).assert_initialized(); return ((*this) == CInt(x)); } - bool operator ==(size_t x) const { (*this).assert_initialized(); return ((*this) == CSize_t(x)); } - - bool operator !=(const CSize_t &x) const { (*this).assert_initialized(); return (m_val != x.m_val); } - bool operator !=(const CInt &x) const { (*this).assert_initialized(); return (CInt(m_val) != x); } - bool operator !=(long long x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - bool operator !=(long x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - bool operator !=(int x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - bool operator !=(short x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - bool operator !=(char x) const { (*this).assert_initialized(); return ((*this) != CInt(x)); } - bool operator !=(size_t x) const { (*this).assert_initialized(); return ((*this) != CSize_t(x)); } - - // INCREMENT/DECREMENT OPERATORS - CSize_t& operator ++() { (*this).assert_initialized(); m_val++; return (*this); } - CSize_t operator ++(int) { (*this).assert_initialized(); - CSize_t tmp(*this); // copy - operator++(); // pre-increment - return tmp; // return old value - } - CSize_t& operator --() { (*this).assert_initialized(); - if (0 <= std::numeric_limits<_Ty>::lowest()) { (*this).assert_initialized(); - (*this) = (*this) - 1; return (*this); - } - else { (*this).assert_initialized(); - m_val--; return (*this); - } - } - CSize_t operator --(int) { (*this).assert_initialized(); - CSize_t tmp(*this); // copy - operator--(); // pre-decrement - return tmp; // return old value - } - - //_Ty m_val; - - friend size_t as_a_size_t(CSize_t n); - }; - size_t as_a_size_t(CSize_t n) { n.assert_initialized(); return n.m_val; } -} - -namespace std { -#ifndef _THROW0 -#define _THROW0() -#endif // !_THROW0 -#ifndef _STCONS -#define _STCONS(ty, name, val) static constexpr ty name = (ty)(val) -#endif // !_STCONS - - template<> class numeric_limits<mse::CSize_t> { // limits for type int - public: - typedef size_t _Ty; - - static constexpr _Ty(min)() _THROW0() - { // return minimum value - return numeric_limits<size_t>::min(); - } - static constexpr _Ty(max)() _THROW0() - { // return maximum value - return numeric_limits<size_t>::max(); - } - static constexpr _Ty lowest() _THROW0() - { // return most negative value - return numeric_limits<size_t>::lowest(); - } - static constexpr _Ty epsilon() _THROW0() - { // return smallest effective increment from 1.0 - return numeric_limits<size_t>::epsilon(); - } - static constexpr _Ty round_error() _THROW0() - { // return largest rounding error - return numeric_limits<size_t>::round_error(); - } - static constexpr _Ty denorm_min() _THROW0() - { // return minimum denormalized value - return numeric_limits<size_t>::denorm_min(); - } - static constexpr _Ty infinity() _THROW0() - { // return positive infinity - return numeric_limits<size_t>::infinity(); - } - static constexpr _Ty quiet_NaN() _THROW0() - { // return non-signaling NaN - return numeric_limits<size_t>::quiet_NaN(); - } - static constexpr _Ty signaling_NaN() _THROW0() - { // return signaling NaN - return numeric_limits<size_t>::signaling_NaN(); - } - _STCONS(float_denorm_style, has_denorm, numeric_limits<size_t>::has_denorm); - _STCONS(bool, has_denorm_loss, numeric_limits<size_t>::has_denorm_loss); - _STCONS(bool, has_infinity, numeric_limits<size_t>::has_infinity); - _STCONS(bool, has_quiet_NaN, numeric_limits<size_t>::has_quiet_NaN); - _STCONS(bool, has_signaling_NaN, numeric_limits<size_t>::has_signaling_NaN); - _STCONS(bool, is_bounded, numeric_limits<size_t>::is_bounded); - _STCONS(bool, is_exact, numeric_limits<size_t>::is_exact); - _STCONS(bool, is_iec559, numeric_limits<size_t>::is_iec559); - _STCONS(bool, is_integer, numeric_limits<size_t>::is_integer); - _STCONS(bool, is_modulo, numeric_limits<size_t>::is_modulo); - _STCONS(bool, is_signed, numeric_limits<size_t>::is_signed); - _STCONS(bool, is_specialized, numeric_limits<size_t>::is_specialized); - _STCONS(bool, tinyness_before, numeric_limits<size_t>::tinyness_before); - _STCONS(bool, traps, numeric_limits<size_t>::traps); - _STCONS(float_round_style, round_style, numeric_limits<size_t>::round_style); - _STCONS(int, digits, numeric_limits<size_t>::digits); - _STCONS(int, digits10, numeric_limits<size_t>::digits10); - _STCONS(int, max_digits10, numeric_limits<size_t>::max_digits10); - _STCONS(int, max_exponent, numeric_limits<size_t>::max_exponent); - _STCONS(int, max_exponent10, numeric_limits<size_t>::max_exponent10); - _STCONS(int, min_exponent, numeric_limits<size_t>::min_exponent); - _STCONS(int, min_exponent10, numeric_limits<size_t>::min_exponent10); - _STCONS(int, radix, numeric_limits<size_t>::radix); - }; -} - -namespace mse { - - inline CInt operator+(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); rhs.assert_initialized(); return CSize_t(lhs) + rhs; } - inline CSize_t operator+(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) + rhs; } - inline CInt operator+(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) + rhs; } - inline CInt operator+(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) + as_a_size_t(rhs); } - inline CInt operator+(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs + as_a_size_t(rhs); } - inline CInt operator-(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) - rhs; } - inline CInt operator-(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) - rhs; } - inline CInt operator-(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) - rhs; } - inline CInt operator-(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) - as_a_size_t(rhs); } - inline CInt operator-(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs - as_a_size_t(rhs); } - inline CInt operator*(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) * rhs; } - inline CSize_t operator*(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) * rhs; } - inline CInt operator*(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) * rhs; } - inline CInt operator*(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) * as_a_size_t(rhs); } - inline CInt operator*(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs * as_a_size_t(rhs); } - inline CInt operator/(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) / rhs; } - inline CSize_t operator/(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) / rhs; } - inline CInt operator/(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) / rhs; } - inline CInt operator/(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) / as_a_size_t(rhs); } - inline CInt operator/(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs / as_a_size_t(rhs); } - - inline bool operator<(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) < rhs; } - inline bool operator<(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) < rhs; } - inline bool operator<(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) < rhs; } - inline bool operator<(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) < as_a_size_t(rhs); } - inline bool operator<(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) < rhs; } - inline bool operator<(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) < as_a_size_t(rhs); } - inline bool operator<(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs < as_a_size_t(rhs); } - inline bool operator>(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) > rhs; } - inline bool operator>(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) > rhs; } - inline bool operator>(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) > rhs; } - inline bool operator>(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) > as_a_size_t(rhs); } - inline bool operator>(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) > rhs; } - inline bool operator>(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) > as_a_size_t(rhs); } - inline bool operator>(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs > as_a_size_t(rhs); } - inline bool operator<=(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) <= rhs; } - inline bool operator<=(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) <= rhs; } - inline bool operator<=(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) <= rhs; } - inline bool operator<=(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) <= as_a_size_t(rhs); } - inline bool operator<=(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) <= rhs; } - inline bool operator<=(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) <= as_a_size_t(rhs); } - inline bool operator<=(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs <= as_a_size_t(rhs); } - inline bool operator>=(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) >= rhs; } - inline bool operator>=(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) >= rhs; } - inline bool operator>=(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) >= rhs; } - inline bool operator>=(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) >= as_a_size_t(rhs); } - inline bool operator>=(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) >= rhs; } - inline bool operator>=(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) >= as_a_size_t(rhs); } - inline bool operator>=(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs >= as_a_size_t(rhs); } - inline bool operator==(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) == rhs; } - inline bool operator==(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) == rhs; } - inline bool operator==(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) == rhs; } - inline bool operator==(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) == as_a_size_t(rhs); } - inline bool operator==(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) == rhs; } - inline bool operator==(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) == as_a_size_t(rhs); } - inline bool operator==(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs == as_a_size_t(rhs); } - inline bool operator!=(size_t lhs, const CInt &rhs) { rhs.assert_initialized(); return CSize_t(lhs) != rhs; } - inline bool operator!=(size_t lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CSize_t(lhs) != rhs; } - inline bool operator!=(int lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) != rhs; } - inline bool operator!=(int lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) != as_a_size_t(rhs); } - inline bool operator!=(long long lhs, const CInt &rhs) { rhs.assert_initialized(); return CInt(lhs) != rhs; } - inline bool operator!=(long long lhs, const CSize_t &rhs) { rhs.assert_initialized(); return CInt(lhs) != as_a_size_t(rhs); } - inline bool operator!=(const CInt &lhs, const CSize_t &rhs) { rhs.assert_initialized(); return lhs != as_a_size_t(rhs); } -#endif /*MSE_PRIMITIVES_DISABLED*/ - - static void s_type_test1() { -#ifdef MSE_SELF_TESTS - CInt i1(3); - CInt i2 = 5; - CInt i3; - i3 = 7; - CInt i4 = i1 + i2; - i4 = i1 + 17; - i4 = 19 + i1; - i4 += i2; - i4 -= 23; - i4++; - CBool b1 = (i1 < i2); - b1 = (i1 < 17); - b1 = (19 < i1); - b1 = (i1 == i2); - b1 = (i1 == 17); - b1 = (19 == i1); - - CSize_t szt1(3); - CSize_t szt2 = 5; - CSize_t szt3; - szt3 = 7; - CSize_t szt4 = szt1 + szt2; - szt4 = szt1 + 17; - szt4 = 19 + szt1; - CInt i11 = 19 + szt1; - szt4 += szt2; - szt4 -= 23; - szt4++; -#ifndef MSVC2010_COMPATIBLE - size_t szt5 = size_t(szt4); -#endif /*MSVC2010_COMPATIBLE*/ - bool b3 = (szt1 < szt2); - b3 = (szt1 < 17); - b3 = (19 < szt1); - CBool b2 = (19 < szt1); - b3 = (szt1 == szt2); - b3 = (szt1 == 17); - b3 = (19 == szt1); - CBool b4 = (b1 < b2); - b4 = (b1 == b2); - b4 = (b1 > b3); - b4 = (b3 >= b1); - b4 = (b3 == b1); - b4 = (b1 && b2); - b4 = (b1 || b3); - b4 = (b3 && b1); - b4 |= b1; - b4 &= b3; -#endif // MSE_SELF_TESTS - } -} - -#undef MSE_THROW - -#endif /*ndef MSEPRIMITIVES_H*/ diff --git a/src/debug/mse/source.txt b/src/debug/mse/source.txt deleted file mode 100644 index 00dc79b25..000000000 --- a/src/debug/mse/source.txt +++ /dev/null @@ -1 +0,0 @@ -https://github.com/duneroadrunner/SaferCPlusPlus diff --git a/src/debug/nvwa/_nvwa.h b/src/debug/nvwa/_nvwa.h deleted file mode 100644 index 096893c59..000000000 --- a/src/debug/nvwa/_nvwa.h +++ /dev/null @@ -1,112 +0,0 @@ -// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -// vim:tabstop=4:shiftwidth=4:expandtab: - -/* - * Copyright (C) 2013-2015 Wu Yongwei <adah at users dot sourceforge dot net> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must - * not claim that you wrote the original software. If you use this - * software in a product, an acknowledgement in the product - * documentation would be appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source - * distribution. - * - * This file is part of Stones of Nvwa: - * http://sourceforge.net/projects/nvwa - * - */ - -/** - * @file _nvwa.h - * - * Common definitions for preprocessing. - * - * @date 2015-10-28 - */ - -#ifndef NVWA_NVWA_H -#define NVWA_NVWA_H - -/** - * @namespace nvwa - * Namespace of the nvwa project. Most functions and global variables - * are defined in this namespace. - */ - -#ifndef NVWA_USE_NAMESPACE -#ifdef __cplusplus -#define NVWA_USE_NAMESPACE 1 -#else -#define NVWA_USE_NAMESPACE 0 -#endif // __cplusplus -#endif // NVWA_USE_NAMESPACE - -#if NVWA_USE_NAMESPACE -#define NVWA_NAMESPACE_BEGIN namespace nvwa { -#define NVWA_NAMESPACE_END } -#define NVWA nvwa -#else // NVWA_USE_NAMESPACE -#define NVWA_NAMESPACE_BEGIN -#define NVWA_NAMESPACE_END -#define NVWA -#endif // NVWA_USE_NAMESPACE - -#ifndef NVWA_APPLE -#if defined(__APPLE__) && defined(__MACH__) -#define NVWA_APPLE 1 -#else -#define NVWA_APPLE 0 -#endif -#endif // NVWA_APPLE - -#ifndef NVWA_CYGWIN -#if defined(__CYGWIN__) -#define NVWA_CYGWIN 1 -#else -#define NVWA_CYGWIN 0 -#endif -#endif // NVWA_CYGWIN - -#ifndef NVWA_LINUX -#if defined(__linux__) || defined(__linux) -#define NVWA_LINUX 1 -#else -#define NVWA_LINUX 0 -#endif -#endif // NVWA_LINUX - -#ifndef NVWA_UNIX -#if defined(__unix__) || defined(__unix) || NVWA_APPLE -#define NVWA_UNIX 1 -#else -#define NVWA_UNIX 0 -#endif -#endif // NVWA_UNIX - -#ifndef NVWA_WIN32 -#if defined(_WIN32) -#define NVWA_WIN32 1 -#else -#define NVWA_WIN32 0 -#endif -#endif // NVWA_WIN32 - -#ifndef NVWA_WINDOWS -#if NVWA_CYGWIN || NVWA_WIN32 -#define NVWA_WINDOWS 1 -#else -#define NVWA_WINDOWS 0 -#endif -#endif // NVWA_WINDOWS - -#endif // NVWA_NVWA_H diff --git a/src/debug/nvwa/c++11.h b/src/debug/nvwa/c++11.h deleted file mode 100644 index 8d8e2d8af..000000000 --- a/src/debug/nvwa/c++11.h +++ /dev/null @@ -1,340 +0,0 @@ -// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -// vim:tabstop=4:shiftwidth=4:expandtab: - -/* - * Copyright (C) 2013-2017 Wu Yongwei <adah at users dot sourceforge dot net> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must - * not claim that you wrote the original software. If you use this - * software in a product, an acknowledgement in the product - * documentation would be appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source - * distribution. - * - * This file is part of Stones of Nvwa: - * http://sourceforge.net/projects/nvwa - * - */ - -/** - * @file c++11.h - * - * C++11 feature detection macros and workarounds. - * - * @date 2017-04-03 - */ - -#ifndef NVWA_CXX11_H -#define NVWA_CXX11_H - -// Only Clang provides these macros; they need to be defined as follows -// to get a valid expression in preprocessing by other compilers. -#ifndef __has_extension -#define __has_extension(x) 0 -#endif -#ifndef __has_feature -#define __has_feature(x) 0 -#endif -#ifndef __has_include -#define __has_include(x) 0 -#endif - -// Detect whether C++11 mode is on (for GCC and Clang). MSVC does not -// have a special C++11 mode, so it is always on for Visual C++ 2010 and -// later. -#if __cplusplus >= 201103L || \ - defined(__GXX_EXPERIMENTAL_CXX0X__) || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) -#define NVWA_CXX11_MODE 1 -#else -#define NVWA_CXX11_MODE 0 -#endif - - -/* Feature checks */ - -#if !defined(HAVE_CXX11_ATOMIC) -#if NVWA_CXX11_MODE && \ - ((__has_include(<atomic>) && !defined(__MINGW32__)) || \ - (defined(_MSC_VER) && _MSC_VER >= 1700) || \ - (((defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405) || \ - defined(__clang__)) && \ - (!defined(__MINGW32__) || defined(_POSIX_THREADS)))) -// Note: MinGW GCC, unless built with POSIX threads (as in -// MinGW-builds), does not support atomics as of 4.8. -#define HAVE_CXX11_ATOMIC 1 -#else -#define HAVE_CXX11_ATOMIC 0 -#endif -#endif - -#if !defined(HAVE_CXX11_AUTO_TYPE) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_auto_type) || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 404)) -#define HAVE_CXX11_AUTO_TYPE 1 -#else -#define HAVE_CXX11_AUTO_TYPE 0 -#endif -#endif - -#if !defined(HAVE_CXX11_DELETED_FUNCTION) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_deleted_functions) || \ - (defined(_MSC_VER) && _MSC_VER >= 1800) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 404)) -#define HAVE_CXX11_DELETED_FUNCTION 1 -#else -#define HAVE_CXX11_DELETED_FUNCTION 0 -#endif -#endif - -#if !defined(HAVE_CXX11_EXPLICIT_CONVERSION) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_explicit_conversions) || \ - (defined(_MSC_VER) && _MSC_VER >= 1900) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405)) -#define HAVE_CXX11_EXPLICIT_CONVERSION 1 -#else -#define HAVE_CXX11_EXPLICIT_CONVERSION 0 -#endif -#endif - -#if !defined(HAVE_CXX11_FINAL) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_override_control) || \ - (defined(_MSC_VER) && _MSC_VER >= 1700) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 407)) -#define HAVE_CXX11_FINAL 1 -#else -#define HAVE_CXX11_FINAL 0 -#endif -#endif - -#if !defined(HAVE_CXX11_FUTURE) -#if NVWA_CXX11_MODE && \ - ((__has_include(<future>) && !defined(__MINGW32__)) || \ - (defined(_MSC_VER) && _MSC_VER >= 1700) || \ - (((defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405) || \ - defined(__clang__)) && \ - (!defined(__MINGW32__) || defined(_POSIX_THREADS)))) -// Note: MinGW GCC, unless built with POSIX threads (as in -// MinGW-builds), does not support futures as of 4.8. -#define HAVE_CXX11_FUTURE 1 -#else -#define HAVE_CXX11_FUTURE 0 -#endif -#endif - -#if !defined(HAVE_CXX11_GENERALIZED_INITIALIZER) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_generalized_initializers) || \ - (defined(_MSC_VER) && _MSC_VER >= 1800) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 404)) -#define HAVE_CXX11_GENERALIZED_INITIALIZER 1 -#else -#define HAVE_CXX11_GENERALIZED_INITIALIZER 0 -#endif -#endif - -#if !defined(HAVE_CXX11_LAMBDA) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_lambdas) || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405)) -#define HAVE_CXX11_LAMBDA 1 -#else -#define HAVE_CXX11_LAMBDA 0 -#endif -#endif - -#if !defined(HAVE_CXX11_MUTEX) -#if NVWA_CXX11_MODE && \ - ((__has_include(<mutex>) && !defined(__MINGW32__)) || \ - (defined(_MSC_VER) && _MSC_VER >= 1700) || \ - (((defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 403) || \ - defined(__clang__)) && \ - (!defined(__MINGW32__) || defined(_POSIX_THREADS)))) -// Note: MinGW GCC, unless built with POSIX threads (as in -// MinGW-builds), does not support std::mutex as of 4.8. -#define HAVE_CXX11_MUTEX 1 -#else -#define HAVE_CXX11_MUTEX 0 -#endif -#endif - -#if !defined(HAVE_CXX11_NOEXCEPT) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_noexcept) || \ - (defined(_MSC_VER) && _MSC_VER >= 1900) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 406)) -#define HAVE_CXX11_NOEXCEPT 1 -#else -#define HAVE_CXX11_NOEXCEPT 0 -#endif -#endif - -#if !defined(HAVE_CXX11_NULLPTR) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_nullptr) || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 406)) -#define HAVE_CXX11_NULLPTR 1 -#else -#define HAVE_CXX11_NULLPTR 0 -#endif -#endif - -#if !defined(HAVE_CXX11_OVERRIDE) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_override_control) || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 407)) -#define HAVE_CXX11_OVERRIDE 1 -#else -#define HAVE_CXX11_OVERRIDE 0 -#endif -#endif - -#if !defined(HAVE_CXX11_RANGE_FOR) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_range_for) || \ - (defined(_MSC_VER) && _MSC_VER >= 1700) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 406)) -#define HAVE_CXX11_RANGE_FOR 1 -#else -#define HAVE_CXX11_RANGE_FOR 0 -#endif -#endif - -#if !defined(HAVE_CXX11_RVALUE_REFERENCE) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_rvalue_references) || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405)) -#define HAVE_CXX11_RVALUE_REFERENCE 1 -#else -#define HAVE_CXX11_RVALUE_REFERENCE 0 -#endif -#endif - -#if !defined(HAVE_CXX11_STATIC_ASSERT) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_static_assert) || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 403)) -#define HAVE_CXX11_STATIC_ASSERT 1 -#else -#define HAVE_CXX11_STATIC_ASSERT 0 -#endif -#endif - -#if !defined(HAVE_CXX11_THREAD) -#if NVWA_CXX11_MODE && \ - ((__has_include(<thread>) && !defined(__MINGW32__)) || \ - (defined(_MSC_VER) && _MSC_VER >= 1700) || \ - (((defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 404) || \ - defined(__clang__)) && \ - (!defined(__MINGW32__) || defined(_POSIX_THREADS)))) -// Note: MinGW GCC, unless built with POSIX threads (as in -// MinGW-builds), does not support std::thread as of 4.8. -#define HAVE_CXX11_THREAD 1 -#else -#define HAVE_CXX11_THREAD 0 -#endif -#endif - -#if !defined(HAVE_CXX11_THREAD_LOCAL) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_thread_local) || \ - (defined(_MSC_VER) && _MSC_VER >= 1900) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 408)) -#define HAVE_CXX11_THREAD_LOCAL 1 -#else -#define HAVE_CXX11_THREAD_LOCAL 0 -#endif -#endif - -#if !defined(HAVE_CXX11_TYPE_TRAITS) -#if NVWA_CXX11_MODE && \ - (__has_include(<type_traits>) || \ - (defined(_MSC_VER) && _MSC_VER >= 1600) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 403)) -#define HAVE_CXX11_TYPE_TRAITS 1 -#else -#define HAVE_CXX11_TYPE_TRAITS 0 -#endif -#endif - -#if !defined(HAVE_CXX11_UNICODE_LITERAL) -#if NVWA_CXX11_MODE && \ - (__has_feature(cxx_unicode_literals) || \ - (defined(_MSC_VER) && _MSC_VER >= 1900) || \ - (defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ >= 405)) -#define HAVE_CXX11_UNICODE_LITERAL 1 -#else -#define HAVE_CXX11_UNICODE_LITERAL 0 -#endif -#endif - - -/* Workarounds */ - -#if HAVE_CXX11_DELETED_FUNCTION -#define _DELETED = delete -#else -#define _DELETED -#endif - -#if HAVE_CXX11_FINAL -#define _FINAL final -#else -#define _FINAL -#endif - -#if HAVE_CXX11_OVERRIDE -#define _OVERRIDE override -#else -#define _OVERRIDE -#endif - -#if HAVE_CXX11_NOEXCEPT -#define _NOEXCEPT noexcept -#define _NOEXCEPT_(x) noexcept(x) -#else -#ifdef _MSC_VER -#define _NOEXCEPT throw () -#else -#define _NOEXCEPT throw() -#endif -#define _NOEXCEPT_(x) -#endif - -#if HAVE_CXX11_NULLPTR -#define _NULLPTR nullptr -#else -#define _NULLPTR NULL -#endif - -#if HAVE_CXX11_THREAD_LOCAL -#define _THREAD_LOCAL thread_local -#else -#ifdef _MSC_VER -#define _THREAD_LOCAL __declspec(thread) -#else -#define _THREAD_LOCAL __thread -#endif -#endif - -#endif // NVWA_CXX11_H diff --git a/src/debug/nvwa/debug_new.cpp b/src/debug/nvwa/debug_new.cpp deleted file mode 100644 index 77ef8f17e..000000000 --- a/src/debug/nvwa/debug_new.cpp +++ /dev/null @@ -1,1197 +0,0 @@ -// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -// vim:tabstop=4:shiftwidth=4:expandtab: - -/* - * Copyright (C) 2004-2016 Wu Yongwei <adah at users dot sourceforge dot net> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must - * not claim that you wrote the original software. If you use this - * software in a product, an acknowledgement in the product - * documentation would be appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source - * distribution. - * - * This file is part of Stones of Nvwa: - * http://sourceforge.net/projects/nvwa - * - */ - -/** - * @file debug_new.cpp - * - * Implementation of debug versions of new and delete to check leakage. - * - * @date 2016-10-14 - */ - -#include "localconsts.h" - -PRAGMACLANG6GCC(GCC diagnostic push) -PRAGMACLANG6GCC(GCC diagnostic ignored "-Wold-style-cast") - -PRAGMA45(GCC diagnostic push) -PRAGMA45(GCC diagnostic ignored "-Wcast-qual") - -#include <new> // std::bad_alloc/nothrow_t -#include <assert.h> // assert -#include <stdio.h> // fprintf/stderr -#include <stdlib.h> // abort -#include <string.h> // strcpy/strncpy/sprintf -#include "debug/nvwa/_nvwa.h" // NVWA macros - -#if NVWA_UNIX -#include <alloca.h> // alloca -#endif -#if NVWA_WIN32 -#include <malloc.h> // alloca -#endif - -#if NVWA_LINUX || NVWA_APPLE -#include <execinfo.h> // backtrace -#endif - -#if NVWA_WINDOWS -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> // CaptureStackBackTrace -#endif - -#include "debug/nvwa/c++11.h" // _NOEXCEPT/_NULLPTR -#include "debug/nvwa/fast_mutex.h" // nvwa::fast_mutex -#include "debug/nvwa/static_assert.h" // STATIC_ASSERT - -#undef _DEBUG_NEW_EMULATE_MALLOC -#undef _DEBUG_NEW_REDEFINE_NEW -/** - * Macro to indicate whether redefinition of \c new is wanted. Here it - * is defined to \c 0 to disable the redefinition of \c new. - */ -#define _DEBUG_NEW_REDEFINE_NEW 0 -#include "debug/nvwa/debug_new.h" - -#if !_FAST_MUTEX_CHECK_INITIALIZATION && !defined(_NOTHREADS) -#error "_FAST_MUTEX_CHECK_INITIALIZATION not set: check_leaks may not work" -#endif - -/** - * @def _DEBUG_NEW_ALIGNMENT - * - * The alignment requirement of allocated memory blocks. It must be a - * power of two. - */ -#ifndef _DEBUG_NEW_ALIGNMENT -#define _DEBUG_NEW_ALIGNMENT 16 -#endif - -/** - * @def _DEBUG_NEW_CALLER_ADDRESS - * - * The expression to return the caller address. nvwa#print_position will - * later on use this address to print the position information of memory - * operation points. - */ -#ifndef _DEBUG_NEW_CALLER_ADDRESS -#ifdef __GNUC__ -#define _DEBUG_NEW_CALLER_ADDRESS __builtin_return_address(0) -#else -#define _DEBUG_NEW_CALLER_ADDRESS _NULLPTR -#endif -#endif - -/** - * @def _DEBUG_NEW_ERROR_ACTION - * - * The action to take when an error occurs. The default behaviour is to - * call \e abort, unless \c _DEBUG_NEW_ERROR_CRASH is defined, in which - * case a segmentation fault will be triggered instead (which can be - * useful on platforms like Windows that do not generate a core dump - * when \e abort is called). - */ -#ifndef _DEBUG_NEW_ERROR_ACTION -#ifndef _DEBUG_NEW_ERROR_CRASH -#define _DEBUG_NEW_ERROR_ACTION abort() -#else -#define _DEBUG_NEW_ERROR_ACTION do { *((char*)0) = 0; abort(); } while (0) -#endif -#endif - -/** - * @def _DEBUG_NEW_FILENAME_LEN - * - * The length of file name stored if greater than zero. If it is zero, - * only a const char pointer will be stored. Currently the default - * value is non-zero (thus to copy the file name) on non-Windows - * platforms, because I once found that the exit leakage check could not - * access the address of the file name on Linux (in my case, a core dump - * occurred when check_leaks tried to access the file name in a shared - * library after a \c SIGINT). This value makes the size of - * new_ptr_list_t \c 64 on non-Windows 32-bit platforms (w/o stack - * backtrace). - */ -#ifndef _DEBUG_NEW_FILENAME_LEN -#if NVWA_WINDOWS -#define _DEBUG_NEW_FILENAME_LEN 0 -#else -#define _DEBUG_NEW_FILENAME_LEN 44 -#endif -#endif - -/** - * @def _DEBUG_NEW_PROGNAME - * - * The program (executable) name to be set at compile time. It is - * better to assign the full program path to nvwa#new_progname in \e main - * (at run time) than to use this (compile-time) macro, but this macro - * serves well as a quick hack. Note also that double quotation marks - * need to be used around the program name, i.e., one should specify a - * command-line option like <code>-D_DEBUG_NEW_PROGNAME=\\"a.out\"</code> - * in \e bash, or <code>-D_DEBUG_NEW_PROGNAME=\\"a.exe\"</code> in the - * Windows command prompt. - */ -#ifndef _DEBUG_NEW_PROGNAME -#define _DEBUG_NEW_PROGNAME _NULLPTR -#endif - -/** - * @def _DEBUG_NEW_REMEMBER_STACK_TRACE - * - * Macro to indicate whether stack traces of allocations should be - * included in NVWA allocation information and be printed while leaks - * are reported. Useful to pinpoint leaks caused by strdup and other - * custom allocation functions. It is also very helpful in filtering - * out false positives caused by internal STL/C runtime operations. It - * is off by default because it is quite memory heavy. Set it to \c 1 - * to make all allocations have stack trace attached, or set to \c 2 to - * make only allocations that lack calling source code information (file - * and line) have the stack trace attached. - */ -#ifndef _DEBUG_NEW_REMEMBER_STACK_TRACE -#define _DEBUG_NEW_REMEMBER_STACK_TRACE 0 -#endif - -/** - * @def _DEBUG_NEW_STD_OPER_NEW - * - * Macro to indicate whether the standard-conformant behaviour of - * <code>operator new</code> is wanted. It is on by default now, but - * the user may set it to \c 0 to revert to the old behaviour. - */ -#ifndef _DEBUG_NEW_STD_OPER_NEW -#define _DEBUG_NEW_STD_OPER_NEW 1 -#endif - -/** - * @def _DEBUG_NEW_TAILCHECK - * - * Macro to indicate whether a writing-past-end check will be performed. - * Define it to a positive integer as the number of padding bytes at the - * end of a memory block for checking. - */ -#ifndef _DEBUG_NEW_TAILCHECK -#define _DEBUG_NEW_TAILCHECK 0 -#endif - -/** - * @def _DEBUG_NEW_TAILCHECK_CHAR - * - * Value of the padding bytes at the end of a memory block. - */ -//#ifndef _DEBUG_NEW_TAILCHECK_CHAR -//#define _DEBUG_NEW_TAILCHECK_CHAR 0xCC -//#endif - -/** - * @def _DEBUG_NEW_USE_ADDR2LINE - * - * Whether to use \e addr2line to convert a caller address to file/line - * information. Defining it to a non-zero value will enable the - * conversion (automatically done if GCC is detected). Defining it to - * zero will disable the conversion. - */ -#ifndef _DEBUG_NEW_USE_ADDR2LINE -#ifdef __GNUC__ -#define _DEBUG_NEW_USE_ADDR2LINE 1 -#else -#define _DEBUG_NEW_USE_ADDR2LINE 0 -#endif -#endif - -#ifdef _MSC_VER -#pragma warning(disable: 4074) // #pragma init_seg(compiler) used -#pragma warning(disable: 4290) // C++ exception specification ignored -#if _MSC_VER >= 1400 // Visual Studio 2005 or later -#pragma warning(disable: 4996) // Use the `unsafe' strncpy -#endif -#pragma init_seg(compiler) -#endif - -/** - * Gets the aligned value of memory block size. - */ -#define ALIGN(s) \ - (((s) + _DEBUG_NEW_ALIGNMENT - 1) & ~(_DEBUG_NEW_ALIGNMENT - 1)) - -NVWA_NAMESPACE_BEGIN - -/** - * The platform memory alignment. The current value works well in - * platforms I have tested: Windows XP, Windows 7 x64, and Mac OS X - * Leopard. It may be smaller than the real alignment, but must be - * bigger than \c sizeof(size_t) for it work. nvwa#debug_new_recorder - * uses it to detect misaligned pointer returned by `<code>new - * NonPODType[size]</code>'. - */ -const size_t PLATFORM_MEM_ALIGNMENT = sizeof(size_t) * 2; - -/** - * Structure to store the position information where \c new occurs. - */ -struct new_ptr_list_t -{ - new_ptr_list_t* next; ///< Pointer to the next memory block - new_ptr_list_t* prev; ///< Pointer to the previous memory block - size_t size; ///< Size of the memory block - union - { -#if _DEBUG_NEW_FILENAME_LEN == 0 - const char* file; ///< Pointer to the file name of the caller -#else - char file[_DEBUG_NEW_FILENAME_LEN]; ///< File name of the caller -#endif - void* addr; ///< Address of the caller to \e new - }; - unsigned line :31; ///< Line number of the caller; or \c 0 - unsigned is_array:1; ///< Non-zero iff <em>new[]</em> is used -#if _DEBUG_NEW_REMEMBER_STACK_TRACE - void** stacktrace; ///< Pointer to stack trace information -#endif - unsigned magic; ///< Magic number for error detection -}; - -/** - * Definition of the constant magic number used for error detection. - */ -static const unsigned DEBUG_NEW_MAGIC = 0x4442474E; - -/** - * The extra memory allocated by <code>operator new</code>. - */ -static const int ALIGNED_LIST_ITEM_SIZE = ALIGN(sizeof(new_ptr_list_t)); - -/** - * List of all new'd pointers. - */ -static new_ptr_list_t new_ptr_list = { - &new_ptr_list, - &new_ptr_list, - 0, - { -#if _DEBUG_NEW_FILENAME_LEN == 0 - _NULLPTR -#else - "" -#endif - }, - 0, - 0, -#if _DEBUG_NEW_REMEMBER_STACK_TRACE - _NULLPTR, -#endif - DEBUG_NEW_MAGIC -}; - -/** - * The mutex guard to protect simultaneous access to the pointer list. - */ -static fast_mutex new_ptr_lock; - -/** - * The mutex guard to protect simultaneous output to #new_output_fp. - */ -static fast_mutex new_output_lock; - -/** - * Total memory allocated in bytes. - */ -static size_t total_mem_alloc = 0; - -/** - * Flag to control whether nvwa#check_leaks will be automatically called - * on program exit. - */ -bool new_autocheck_flag = true; - -/** - * Flag to control whether verbose messages are output. - */ -bool new_verbose_flag = false; - -/** - * Pointer to the output stream. The default output is \e stderr, and - * one may change it to a user stream if needed (say, #new_verbose_flag - * is \c true and there are a lot of (de)allocations). - */ -FILE* new_output_fp = stderr; - -/** - * Pointer to the program name. Its initial value is the macro - * #_DEBUG_NEW_PROGNAME. You should try to assign the program path to - * it early in your application. Assigning <code>argv[0]</code> to it - * in \e main is one way. If you use \e bash or \e ksh (or similar), - * the following statement is probably what you want: - * `<code>new_progname = getenv("_");</code>'. - */ -const char* new_progname = _DEBUG_NEW_PROGNAME; - -/** - * Pointer to the callback used to print the stack backtrace in case of - * a memory problem. A null value causes the default stack trace - * printing routine to be used. - */ -stacktrace_print_callback_t stacktrace_print_callback = _NULLPTR; - -/** - * Pointer to the callback used to filter out false positives from leak - * reports. A null value means the lack of filtering. - */ -leak_whitelist_callback_t leak_whitelist_callback = _NULLPTR; - -#if _DEBUG_NEW_USE_ADDR2LINE -/** - * Tries printing the position information from an instruction address. - * This is the version that uses \e addr2line. - * - * @param addr the instruction address to convert and print - * @return \c true if the address is converted successfully (and - * the result is printed); \c false if no useful - * information is got (and nothing is printed) - */ -static bool print_position_from_addr(const void* addr) -{ - static const void* last_addr = _NULLPTR; - static char last_info[256] = ""; - if (addr == last_addr) - { - if (last_info[0] == '\0') - return false; - fprintf(new_output_fp, "%s", last_info); - return true; - } - if (new_progname) - { -#if NVWA_APPLE - const char addr2line_cmd[] = "atos -o "; -#else - const char addr2line_cmd[] = "addr2line -e "; -#endif - -#if NVWA_WINDOWS - const int exeext_len = 4; -#else - const int exeext_len = 0; -#endif - -#if NVWA_UNIX && !NVWA_CYGWIN - const char ignore_err[] = " 2>/dev/null"; -#elif NVWA_CYGWIN || \ - (NVWA_WIN32 && defined(WINVER) && WINVER >= 0x0500) - const char ignore_err[] = " 2>nul"; -#else - const char ignore_err[] = ""; -#endif - char* cmd = (char*)alloca(strlen(new_progname) - + exeext_len - + sizeof addr2line_cmd - 1 - + sizeof ignore_err - 1 - + sizeof(void*) * 2 - + 4 /* SP + "0x" + null */); - strcpy(cmd, addr2line_cmd); - strcpy(cmd + sizeof addr2line_cmd - 1, new_progname); - size_t len = strlen(cmd); -#if NVWA_WINDOWS - if (len <= 4 - || (strcmp(cmd + len - 4, ".exe") != 0 && - strcmp(cmd + len - 4, ".EXE") != 0)) - { - strcpy(cmd + len, ".exe"); - len += 4; - } -#endif - sprintf(cmd + len, " %p%s", addr, ignore_err); - FILE* fp = popen(cmd, "r"); - if (fp) - { - char buffer[sizeof last_info] = ""; - len = 0; - if (fgets(buffer, sizeof buffer, fp)) - { - len = strlen(buffer); - if (buffer[len - 1] == '\n') - buffer[--len] = '\0'; - } - int res = pclose(fp); - // Display the file/line information only if the command - // is executed successfully and the output points to a - // valid position, but the result will be cached if only - // the command is executed successfully. - if (res == 0 && len > 0) - { - last_addr = addr; - if (buffer[len - 1] == '0' && buffer[len - 2] == ':') - last_info[0] = '\0'; - else - { - fprintf(new_output_fp, "%s", buffer); - strcpy(last_info, buffer); - return true; - } - } - } - } - return false; -} -#else -/** - * Tries printing the position information from an instruction address. - * This is the stub version that does nothing at all. - * - * @return \c false always - */ -static bool print_position_from_addr(const void*) -{ - return false; -} -#endif // _DEBUG_NEW_USE_ADDR2LINE - -/** - * Prints the position information of a memory operation point. When \c - * _DEBUG_NEW_USE_ADDR2LINE is defined to a non-zero value, this - * function will try to convert a given caller address to file/line - * information with \e addr2line. - * - * @param ptr source file name if \e line is non-zero; caller address - * otherwise - * @param line source line number if non-zero; indication that \e ptr - * is the caller address otherwise - */ -static void print_position(const void* ptr, int line) -{ - if (line != 0) // Is file/line information present? - { - fprintf(new_output_fp, "%s:%d", (const char*)ptr, line); - } - else if (ptr != _NULLPTR) // Is caller address present? - { - if (!print_position_from_addr(ptr)) // Fail to get source position? - fprintf(new_output_fp, "%p", ptr); - } - else // No information is present - { - fprintf(new_output_fp, "<Unknown>"); - } -} - -#if _DEBUG_NEW_REMEMBER_STACK_TRACE -/** - * Prints the stack backtrace. - * - * When nvwa#stacktrace_print_callback is not null, it is used for - * printing the stacktrace items. Default implementation of call stack - * printing is very spartan—only stack frame pointers are - * printed—but even that output is still useful. Just do address - * lookup in LLDB etc. - * - * @param stacktrace pointer to the stack trace array - */ -static void print_stacktrace(void** stacktrace) -{ - if (stacktrace_print_callback == _NULLPTR) - { - fprintf(new_output_fp, "Stack backtrace:\n"); - for (size_t i = 0; stacktrace[i] != _NULLPTR; ++i) - fprintf(new_output_fp, "%p\n", stacktrace[i]); - } - else - { - stacktrace_print_callback(new_output_fp, stacktrace); - } -} -#endif - -/** - * Checks whether a leak should be ignored. Its runtime performance - * depends on the callback nvwa#leak_whitelist_callback. - * - * @param ptr pointer to a new_ptr_list_t struct - * @return \c true if the leak should be whitelisted; \c false - * otherwise - */ -static bool is_leak_whitelisted(new_ptr_list_t* ptr) -{ - if (leak_whitelist_callback == _NULLPTR) - return false; - - char const* file = ptr->line != 0 ? ptr->file : _NULLPTR; - int line = ptr->line; - void* addr = ptr->line == 0 ? ptr->addr : _NULLPTR; -#if _DEBUG_NEW_REMEMBER_STACK_TRACE - void** stacktrace = ptr->stacktrace; -#else - void** stacktrace = _NULLPTR; -#endif - - return leak_whitelist_callback(file, line, addr, stacktrace); -} - -#if _DEBUG_NEW_TAILCHECK -/** - * Checks whether the padding bytes at the end of a memory block is - * tampered with. - * - * @param ptr pointer to a new_ptr_list_t struct - * @return \c true if the padding bytes are untouched; \c false - * otherwise - */ -static bool check_tail(new_ptr_list_t* ptr) -{ - const unsigned char* const tail_ptr = (unsigned char*)ptr + - ALIGNED_LIST_ITEM_SIZE + ptr->size; - for (int i = 0; i < _DEBUG_NEW_TAILCHECK; ++i) - if (tail_ptr[i] != _DEBUG_NEW_TAILCHECK_CHAR) - return false; - return true; -} -#endif - -/** - * Allocates memory and initializes control data. - * - * @param size size of the required memory block - * @param file null-terminated string of the file name - * @param line line number - * @param is_array boolean value whether this is an array operation - * @return pointer to the user-requested memory area; null if - * memory allocation is not successful - */ -static void* alloc_mem(size_t size, const char* file, int line, bool is_array) -{ - assert(line >= 0); -#if _DEBUG_NEW_TYPE == 1 - STATIC_ASSERT(_DEBUG_NEW_ALIGNMENT >= PLATFORM_MEM_ALIGNMENT, - Alignment_too_small); -#endif - STATIC_ASSERT((_DEBUG_NEW_ALIGNMENT & (_DEBUG_NEW_ALIGNMENT - 1)) == 0, - Alignment_must_be_power_of_two); - STATIC_ASSERT(_DEBUG_NEW_TAILCHECK >= 0, Invalid_tail_check_length); - size_t s = size + ALIGNED_LIST_ITEM_SIZE + _DEBUG_NEW_TAILCHECK; - new_ptr_list_t* ptr = (new_ptr_list_t*)malloc(s); - if (ptr == _NULLPTR) - { -#if _DEBUG_NEW_STD_OPER_NEW - return _NULLPTR; -#else - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "Out of memory when allocating %lu bytes\n", - (unsigned long)size); - fflush(new_output_fp); - _DEBUG_NEW_ERROR_ACTION; -#endif - } - void* usr_ptr = (char*)ptr + ALIGNED_LIST_ITEM_SIZE; -#if _DEBUG_NEW_FILENAME_LEN == 0 - ptr->file = file; -#else - if (line) - strncpy(ptr->file, file, _DEBUG_NEW_FILENAME_LEN - 1) - [_DEBUG_NEW_FILENAME_LEN - 1] = '\0'; - else - ptr->addr = (void*)file; -#endif - ptr->line = line; -#if _DEBUG_NEW_REMEMBER_STACK_TRACE - ptr->stacktrace = _NULLPTR; - -#if _DEBUG_NEW_REMEMBER_STACK_TRACE == 2 - if (line == 0) -#endif - { - void* buffer [255]; - size_t buffer_length = sizeof(buffer) / sizeof(*buffer); - -#if NVWA_UNIX - int stacktrace_length = backtrace(buffer, int(buffer_length)); -#endif - -#if NVWA_WINDOWS - USHORT stacktrace_length = CaptureStackBackTrace( - 0, DWORD(buffer_length), buffer, _NULLPTR); -#endif - - size_t stacktrace_size = stacktrace_length * sizeof(void*); - ptr->stacktrace = (void**)malloc(stacktrace_size + sizeof(void*)); - - if (ptr->stacktrace != _NULLPTR) - { - memcpy(ptr->stacktrace, buffer, stacktrace_size); - ptr->stacktrace[stacktrace_length] = _NULLPTR; - } - } -#endif - ptr->is_array = is_array; - ptr->size = size; - ptr->magic = DEBUG_NEW_MAGIC; - { - fast_mutex_autolock lock(new_ptr_lock); - ptr->prev = new_ptr_list.prev; - ptr->next = &new_ptr_list; - new_ptr_list.prev->next = ptr; - new_ptr_list.prev = ptr; - } -#if _DEBUG_NEW_TAILCHECK - memset((char*)usr_ptr + size, _DEBUG_NEW_TAILCHECK_CHAR, - _DEBUG_NEW_TAILCHECK); -#endif - if (new_verbose_flag) - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "new%s: allocated %p (size %lu, ", - is_array ? "[]" : "", - usr_ptr, (unsigned long)size); - if (line != 0) - print_position(ptr->file, ptr->line); - else - print_position(ptr->addr, ptr->line); - fprintf(new_output_fp, ")\n"); - } - total_mem_alloc += size; - return usr_ptr; -} - -/** - * Frees memory and adjusts pointers. - * - * @param usr_ptr pointer to the previously allocated memory - * @param addr pointer to the caller - * @param is_array flag indicating whether it is invoked by a - * <code>delete[]</code> call - */ -static void free_pointer(void* usr_ptr, void* addr, bool is_array) -{ - if (usr_ptr == _NULLPTR) - return; - new_ptr_list_t* ptr = - (new_ptr_list_t*)((char*)usr_ptr - ALIGNED_LIST_ITEM_SIZE); - if (ptr->magic != DEBUG_NEW_MAGIC) - { - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, "delete%s: invalid pointer %p (", - is_array ? "[]" : "", usr_ptr); - print_position(addr, 0); - fprintf(new_output_fp, ")\n"); - } - check_mem_corruption(); - fflush(new_output_fp); - _DEBUG_NEW_ERROR_ACTION; - } - if (is_array != ptr->is_array) - { - const char* msg; - if (is_array) - msg = "delete[] after new"; - else - msg = "delete after new[]"; - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "%s: pointer %p (size %lu)\n\tat ", - msg, - (char*)ptr + ALIGNED_LIST_ITEM_SIZE, - (unsigned long)ptr->size); - print_position(addr, 0); - fprintf(new_output_fp, "\n\toriginally allocated at "); - if (ptr->line != 0) - print_position(ptr->file, ptr->line); - else - print_position(ptr->addr, ptr->line); - fprintf(new_output_fp, "\n"); - fflush(new_output_fp); - _DEBUG_NEW_ERROR_ACTION; - } -#if _DEBUG_NEW_TAILCHECK - if (!check_tail(ptr)) - { - check_mem_corruption(); - fflush(new_output_fp); - _DEBUG_NEW_ERROR_ACTION; - } -#endif - { - fast_mutex_autolock lock(new_ptr_lock); - total_mem_alloc -= ptr->size; - ptr->magic = 0; - ptr->prev->next = ptr->next; - ptr->next->prev = ptr->prev; - } - if (new_verbose_flag) - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "delete%s: freed %p (size %lu, %lu bytes still allocated)\n", - is_array ? "[]" : "", - (char*)ptr + ALIGNED_LIST_ITEM_SIZE, - (unsigned long)ptr->size, (unsigned long)total_mem_alloc); - } -#if _DEBUG_NEW_REMEMBER_STACK_TRACE - free(ptr->stacktrace); -#endif - free(ptr); - return; -} - -/** - * Checks for memory leaks. - * - * @return zero if no leakage is found; the number of leaks otherwise - */ -int check_leaks() -{ - int leak_cnt = 0; - int whitelisted_leak_cnt = 0; - fast_mutex_autolock lock_ptr(new_ptr_lock); - fast_mutex_autolock lock_output(new_output_lock); - new_ptr_list_t* ptr = new_ptr_list.next; - - while (ptr != &new_ptr_list) - { - const char* const usr_ptr = (char*)ptr + ALIGNED_LIST_ITEM_SIZE; - if (ptr->magic != DEBUG_NEW_MAGIC) - { - fprintf(new_output_fp, - "warning: heap data corrupt near %p\n", - usr_ptr); - } -#if _DEBUG_NEW_TAILCHECK - if (!check_tail(ptr)) - { - fprintf(new_output_fp, - "warning: overwritten past end of object at %p\n", - usr_ptr); - } -#endif - - if (is_leak_whitelisted(ptr)) - { - ++whitelisted_leak_cnt; - } - else - { - fprintf(new_output_fp, - "Leaked object at %p (size %lu, ", - usr_ptr, - (unsigned long)ptr->size); - - if (ptr->line != 0) - print_position(ptr->file, ptr->line); - else - print_position(ptr->addr, ptr->line); - - fprintf(new_output_fp, ")\n"); - -#if _DEBUG_NEW_REMEMBER_STACK_TRACE - if (ptr->stacktrace != _NULLPTR) - print_stacktrace(ptr->stacktrace); -#endif - } - - ptr = ptr->next; - ++leak_cnt; - } - if (new_verbose_flag || leak_cnt) - { - if (whitelisted_leak_cnt > 0) - { - fprintf(new_output_fp, "*** %d leaks found (%d whitelisted)\n", - leak_cnt, whitelisted_leak_cnt); - } - else - { - fprintf(new_output_fp, "*** %d leaks found\n", leak_cnt); - } - } - - return leak_cnt; -} - -/** - * Checks for heap corruption. - * - * @return zero if no problem is found; the number of found memory - * corruptions otherwise - */ -int check_mem_corruption() -{ - int corrupt_cnt = 0; - fast_mutex_autolock lock_ptr(new_ptr_lock); - fast_mutex_autolock lock_output(new_output_lock); - fprintf(new_output_fp, "*** Checking for memory corruption: START\n"); - for (new_ptr_list_t* ptr = new_ptr_list.next; - ptr != &new_ptr_list; - ptr = ptr->next) - { - const char* const usr_ptr = (char*)ptr + ALIGNED_LIST_ITEM_SIZE; - if (ptr->magic == DEBUG_NEW_MAGIC -#if _DEBUG_NEW_TAILCHECK - && check_tail(ptr) -#endif - ) - continue; -#if _DEBUG_NEW_TAILCHECK - if (ptr->magic != DEBUG_NEW_MAGIC) - { -#endif - fprintf(new_output_fp, - "Heap data corrupt near %p (size %lu, ", - usr_ptr, - (unsigned long)ptr->size); -#if _DEBUG_NEW_TAILCHECK - } - else - { - fprintf(new_output_fp, - "Overwritten past end of object at %p (size %lu, ", - usr_ptr, - (unsigned long)ptr->size); - } -#endif - if (ptr->line != 0) - print_position(ptr->file, ptr->line); - else - print_position(ptr->addr, ptr->line); - fprintf(new_output_fp, ")\n"); - -#if _DEBUG_NEW_REMEMBER_STACK_TRACE - if (ptr->stacktrace != _NULLPTR) - print_stacktrace(ptr->stacktrace); -#endif - - ++corrupt_cnt; - } - fprintf(new_output_fp, "*** Checking for memory corruption: %d FOUND\n", - corrupt_cnt); - return corrupt_cnt; -} - -/** - * Processes the allocated memory and inserts file/line informatin. - * It will only be done when it can ensure the memory is allocated by - * one of our operator new variants. - * - * @param usr_ptr pointer returned by a new-expression - */ -void debug_new_recorder::_M_process(void* usr_ptr) -{ - if (usr_ptr == _NULLPTR) - return; - - // In an expression `new NonPODType[size]', the pointer returned is - // not the pointer returned by operator new[], but offset by size_t - // to leave room for the size. It needs to be compensated here. - size_t offset = (char*)usr_ptr - (char*)_NULLPTR; - if (offset % PLATFORM_MEM_ALIGNMENT != 0) { - offset -= sizeof(size_t); - if (offset % PLATFORM_MEM_ALIGNMENT != 0) { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "warning: memory unaligned; skipping processing (%s:%d)\n", - _M_file, _M_line); - return; - } - usr_ptr = (char*)usr_ptr - sizeof(size_t); - } - - new_ptr_list_t* ptr = - (new_ptr_list_t*)((char*)usr_ptr - ALIGNED_LIST_ITEM_SIZE); - if (ptr->magic != DEBUG_NEW_MAGIC || ptr->line != 0) - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "warning: debug_new used with placement new (%s:%d)\n", - _M_file, _M_line); - return; - } - if (new_verbose_flag) { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "info: pointer %p allocated from %s:%d\n", - usr_ptr, _M_file, _M_line); - } -#if _DEBUG_NEW_FILENAME_LEN == 0 - ptr->file = _M_file; -#else - strncpy(ptr->file, _M_file, _DEBUG_NEW_FILENAME_LEN - 1) - [_DEBUG_NEW_FILENAME_LEN - 1] = '\0'; -#endif - ptr->line = _M_line; -#if _DEBUG_NEW_REMEMBER_STACK_TRACE == 2 - free(ptr->stacktrace); - ptr->stacktrace = _NULLPTR; -#endif -} - -/** - * Count of source files that use debug_new. - */ -int debug_new_counter::_S_count = 0; - -/** - * Constructor to increment the count. - */ -debug_new_counter::debug_new_counter() -{ - ++_S_count; -} - -/** - * Destructor to decrement the count. When the count is zero, - * nvwa#check_leaks will be called. - */ -debug_new_counter::~debug_new_counter() -{ - if (--_S_count == 0 && new_autocheck_flag) - if (check_leaks()) - { - new_verbose_flag = true; -#if defined(__GNUC__) && __GNUC__ == 3 - if (!getenv("GLIBCPP_FORCE_NEW") && !getenv("GLIBCXX_FORCE_NEW")) - fprintf(new_output_fp, -"*** WARNING: GCC 3 is detected, please make sure the environment\n" -" variable GLIBCPP_FORCE_NEW (GCC 3.2 and 3.3) or GLIBCXX_FORCE_NEW\n" -" (GCC 3.4) is defined. Check the README file for details.\n"); -#endif - } -} - -NVWA_NAMESPACE_END - -#if NVWA_USE_NAMESPACE -using namespace nvwa; -#endif // NVWA_USE_NAMESPACE - -/** - * Allocates memory with file/line information. - * - * @param size size of the required memory block - * @param file null-terminated string of the file name - * @param line line number - * @return pointer to the memory allocated; or null if memory is - * insufficient (#_DEBUG_NEW_STD_OPER_NEW is 0) - * @throw bad_alloc memory is insufficient (#_DEBUG_NEW_STD_OPER_NEW is 1) - */ -void* operator new(size_t size, const char* file, int line) -{ - void* ptr = alloc_mem(size, file, line, false); -#if _DEBUG_NEW_STD_OPER_NEW - if (ptr) - return ptr; - else - throw std::bad_alloc(); -#else - return ptr; -#endif -} - -/** - * Allocates array memory with file/line information. - * - * @param size size of the required memory block - * @param file null-terminated string of the file name - * @param line line number - * @return pointer to the memory allocated; or null if memory is - * insufficient (#_DEBUG_NEW_STD_OPER_NEW is 0) - * @throw bad_alloc memory is insufficient (#_DEBUG_NEW_STD_OPER_NEW is 1) - */ -void* operator new[](size_t size, const char* file, int line) -{ - void* ptr = alloc_mem(size, file, line, true); -#if _DEBUG_NEW_STD_OPER_NEW - if (ptr) - return ptr; - else - throw std::bad_alloc(); -#else - return ptr; -#endif -} - -/** - * Allocates memory without file/line information. - * - * @param size size of the required memory block - * @return pointer to the memory allocated; or null if memory is - * insufficient (#_DEBUG_NEW_STD_OPER_NEW is 0) - * @throw bad_alloc memory is insufficient (#_DEBUG_NEW_STD_OPER_NEW is 1) - */ -void* operator new(size_t size) -{ - return operator new(size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0); -} - -/** - * Allocates array memory without file/line information. - * - * @param size size of the required memory block - * @return pointer to the memory allocated; or null if memory is - * insufficient (#_DEBUG_NEW_STD_OPER_NEW is 0) - * @throw bad_alloc memory is insufficient (#_DEBUG_NEW_STD_OPER_NEW is 1) - */ -void* operator new[](size_t size) -{ - return operator new[](size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0); -} - -/** - * Allocates memory with no-throw guarantee. - * - * @param size size of the required memory block - * @return pointer to the memory allocated; or null if memory is - * insufficient - */ -void* operator new(size_t size, const std::nothrow_t&) _NOEXCEPT -{ - return alloc_mem(size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0, false); -} - -/** - * Allocates array memory with no-throw guarantee. - * - * @param size size of the required memory block - * @return pointer to the memory allocated; or null if memory is - * insufficient - */ -void* operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT -{ - return alloc_mem(size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0, true); -} - -/** - * Deallocates memory. - * - * @param ptr pointer to the previously allocated memory - */ -void operator delete(void* ptr) _NOEXCEPT -{ - free_pointer(ptr, _DEBUG_NEW_CALLER_ADDRESS, false); -} - -/** - * Deallocates array memory. - * - * @param ptr pointer to the previously allocated memory - */ -void operator delete[](void* ptr) _NOEXCEPT -{ - free_pointer(ptr, _DEBUG_NEW_CALLER_ADDRESS, true); -} - -#if __cplusplus >= 201402L -// GCC under C++14 wants these definitions - -void operator delete(void* ptr, size_t) _NOEXCEPT -{ - free_pointer(ptr, _DEBUG_NEW_CALLER_ADDRESS, false); -} - -void operator delete[](void* ptr, size_t) _NOEXCEPT -{ - free_pointer(ptr, _DEBUG_NEW_CALLER_ADDRESS, true); -} -#endif - -/** - * Placement deallocation function. For details, please check Section - * 5.3.4 of the C++ 1998 or 2011 Standard. - * - * @param ptr pointer to the previously allocated memory - * @param file null-terminated string of the file name - * @param line line number - * - * @see http://www.csci.csusb.edu/dick/c++std/cd2/expr.html#expr.new - * @see http://wyw.dcweb.cn/leakage.htm - */ -void operator delete(void* ptr, const char* file, int line) _NOEXCEPT -{ - if (new_verbose_flag) - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "info: exception thrown on initializing object at %p (", - ptr); - print_position(file, line); - fprintf(new_output_fp, ")\n"); - } - operator delete(ptr); -} - -/** - * Placement deallocation function. For details, please check Section - * 5.3.4 of the C++ 1998 or 2011 Standard. - * - * @param ptr pointer to the previously allocated memory - * @param file null-terminated string of the file name - * @param line line number - */ -void operator delete[](void* ptr, const char* file, int line) _NOEXCEPT -{ - if (new_verbose_flag) - { - fast_mutex_autolock lock(new_output_lock); - fprintf(new_output_fp, - "info: exception thrown on initializing objects at %p (", - ptr); - print_position(file, line); - fprintf(new_output_fp, ")\n"); - } - operator delete[](ptr); -} - -/** - * Placement deallocation function. For details, please check Section - * 5.3.4 of the C++ 1998 or 2011 Standard. - * - * @param ptr pointer to the previously allocated memory - */ -void operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT -{ - operator delete(ptr, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0); -} - -/** - * Placement deallocation function. For details, please check Section - * 5.3.4 of the C++ 1998 or 2011 Standard. - * - * @param ptr pointer to the previously allocated memory - */ -void operator delete[](void* ptr, const std::nothrow_t&) _NOEXCEPT -{ - operator delete[](ptr, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0); -} - -// This is to make Doxygen happy -#undef _DEBUG_NEW_REMEMBER_STACK_TRACE -//#define _DEBUG_NEW_REMEMBER_STACK_TRACE 0 - -PRAGMA45(GCC diagnostic pop) -PRAGMACLANG6GCC(GCC diagnostic pop) diff --git a/src/debug/nvwa/debug_new.h b/src/debug/nvwa/debug_new.h deleted file mode 100644 index 50b168c2e..000000000 --- a/src/debug/nvwa/debug_new.h +++ /dev/null @@ -1,207 +0,0 @@ -// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -// vim:tabstop=4:shiftwidth=4:expandtab: - -/* - * Copyright (C) 2004-2015 Wu Yongwei <adah at users dot sourceforge dot net> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must - * not claim that you wrote the original software. If you use this - * software in a product, an acknowledgement in the product - * documentation would be appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source - * distribution. - * - * This file is part of Stones of Nvwa: - * http://sourceforge.net/projects/nvwa - * - */ - -/** - * @file debug_new.h - * - * Header file for checking leaks caused by unmatched new/delete. - * - * @date 2015-10-25 - */ - -#ifndef NVWA_DEBUG_NEW_H -#define NVWA_DEBUG_NEW_H - -#include <new> // size_t/std::bad_alloc -#include <stdio.h> // FILE -#include "debug/nvwa/_nvwa.h" // NVWA_NAMESPACE_* -#include "debug/nvwa/c++11.h" // _NOEXCEPT - -/* Special allocation/deallocation functions in the global scope */ -void* operator new(size_t size, const char* file, int line); -void* operator new[](size_t size, const char* file, int line); -void operator delete(void* ptr, const char* file, int line) _NOEXCEPT; -void operator delete[](void* ptr, const char* file, int line) _NOEXCEPT; - -NVWA_NAMESPACE_BEGIN - -/** - * @def _DEBUG_NEW_REDEFINE_NEW - * - * Macro to indicate whether redefinition of \c new is wanted. If one - * wants to define one's own <code>operator new</code>, or to call - * <code>operator new</code> directly, it should be defined to \c 0 to - * alter the default behaviour. Unless, of course, one is willing to - * take the trouble to write something like: - * @code - * # ifdef new - * # define _NEW_REDEFINED - * # undef new - * # endif - * - * // Code that uses new is here - * - * # ifdef _NEW_REDEFINED - * # ifdef DEBUG_NEW - * # define new DEBUG_NEW - * # endif - * # undef _NEW_REDEFINED - * # endif - * @endcode - */ -#ifndef _DEBUG_NEW_REDEFINE_NEW -#define _DEBUG_NEW_REDEFINE_NEW 1 -#endif - -/** - * @def _DEBUG_NEW_TYPE - * - * Macro to indicate which variant of #DEBUG_NEW is wanted. The - * default value \c 1 allows the use of placement new (like - * <code>%new(std::nothrow)</code>), but the verbose output (when - * nvwa#new_verbose_flag is \c true) looks worse than some older - * versions (no file/line information for allocations). Define it - * to \c 2 to revert to the old behaviour that records file and line - * information directly on the call to <code>operator new</code>. - */ -#ifndef _DEBUG_NEW_TYPE -#define _DEBUG_NEW_TYPE 1 -#endif - -/** - * Callback type for stack trace printing. - * - * @param fp pointer to the output stream - * @param stacktrace pointer to the stack trace array (null-terminated) - */ -typedef void (*stacktrace_print_callback_t)(FILE* fp, void** stacktrace); - -/** - * Callback type for the leak whitelist function. \a file, \a address, - * and \a backtrace might be null depending on library configuration, - * platform, and amount of runtime information available. \a line can - * be 0 when line number info is not available at runtime. - * - * @param file null-terminated string of the file name - * @param line line number - * @param addr address of code where leakage happens - * @param stacktrace pointer to the stack trace array (null-terminated) - * @return \c true if the leak should be whitelisted; - * \c false otherwise - */ -typedef bool (*leak_whitelist_callback_t)(char const* file, int line, - void* addr, void** stacktrace); - -/* Prototypes */ -int check_leaks(); -int check_mem_corruption(); - -/* Control variables */ -extern bool new_autocheck_flag; // default to true: call check_leaks() on exit -extern bool new_verbose_flag; // default to false: no verbose information -extern FILE* new_output_fp; // default to stderr: output to console -extern const char* new_progname;// default to null; should be assigned argv[0] -extern stacktrace_print_callback_t stacktrace_print_callback;// default to null -extern leak_whitelist_callback_t leak_whitelist_callback; // default to null - -/** - * @def DEBUG_NEW - * - * Macro to catch file/line information on allocation. If - * #_DEBUG_NEW_REDEFINE_NEW is \c 0, one can use this macro directly; - * otherwise \c new will be defined to it, and one must use \c new - * instead. - */ -# if _DEBUG_NEW_TYPE == 1 -# define DEBUG_NEW NVWA::debug_new_recorder(__FILE__, __LINE__) ->* new -# else -# define DEBUG_NEW new(__FILE__, __LINE__) -# endif - -# if _DEBUG_NEW_REDEFINE_NEW -# define new DEBUG_NEW -# endif -# ifdef _DEBUG_NEW_EMULATE_MALLOC -# include <stdlib.h> -# ifdef new -# define malloc(s) ((void*)(new char[s])) -# else -# define malloc(s) ((void*)(DEBUG_NEW char[s])) -# endif -# define free(p) delete[] (char*)(p) -# endif - -/** - * Recorder class to remember the call context. - * - * The idea comes from <a href="http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/7089382e3bc1c489/85f9107a1dc79ee9?#85f9107a1dc79ee9">Greg Herlihy's post</a> in comp.lang.c++.moderated. - */ -class debug_new_recorder -{ - const char* _M_file; - const int _M_line; - void _M_process(void* ptr); -public: - /** - * Constructor to remember the call context. The information will - * be used in debug_new_recorder::operator->*. - */ - debug_new_recorder(const char* file, int line) - : _M_file(file), _M_line(line) {} - /** - * Operator to write the context information to memory. - * <code>operator->*</code> is chosen because it has the right - * precedence, it is rarely used, and it looks good: so people can - * tell the special usage more quickly. - */ - template <class _Tp> _Tp* operator->*(_Tp* ptr) - { _M_process(ptr); return ptr; } -private: - debug_new_recorder(const debug_new_recorder&); - debug_new_recorder& operator=(const debug_new_recorder&); -}; - -/** - * Counter class for on-exit leakage check. - * - * This technique is learnt from <em>The C++ Programming Language</em> by - * Bjarne Stroustup. - */ -class debug_new_counter -{ - static int _S_count; -public: - debug_new_counter(); - ~debug_new_counter(); -}; -/** Counting object for each file including debug_new.h. */ -static debug_new_counter __debug_new_count; - -NVWA_NAMESPACE_END - -#endif // NVWA_DEBUG_NEW_H diff --git a/src/debug/nvwa/fast_mutex.h b/src/debug/nvwa/fast_mutex.h deleted file mode 100644 index faccc4893..000000000 --- a/src/debug/nvwa/fast_mutex.h +++ /dev/null @@ -1,427 +0,0 @@ -// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -// vim:tabstop=4:shiftwidth=4:expandtab: - -/* - * Copyright (C) 2004-2015 Wu Yongwei <adah at users dot sourceforge dot net> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must - * not claim that you wrote the original software. If you use this - * software in a product, an acknowledgement in the product - * documentation would be appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source - * distribution. - * - * This file is part of Stones of Nvwa: - * http://sourceforge.net/projects/nvwa - * - */ - -/** - * @file fast_mutex.h - * - * A fast mutex implementation for POSIX, Win32, and modern C++. - * - * @date 2015-05-19 - */ - -#ifndef NVWA_FAST_MUTEX_H -#define NVWA_FAST_MUTEX_H - -#include "debug/nvwa/_nvwa.h" // NVWA_NAMESPACE_* -#include "debug/nvwa/c++11.h" // HAVE_CXX11_MUTEX - -# if !defined(_NOTHREADS) -# if !defined(NVWA_USE_CXX11_MUTEX) && HAVE_CXX11_MUTEX != 0 && \ - !defined(_WIN32THREADS) && !defined(NVWA_WIN32THREADS) && \ - !defined(NVWA_PTHREADS) && !defined(NVWA_NOTHREADS) && \ - defined(_WIN32) && defined(_MT) && \ - (!defined(_MSC_VER) || defined(_DLL)) -// Prefer using std::mutex on Windows to avoid the namespace -// pollution caused by <windows.h>. However, MSVC has a re-entry -// issue with its std::mutex implementation, and std::mutex should -// not be used unless /MD or /MDd is used. For more information, -// check out: -// -// https://connect.microsoft.com/VisualStudio/feedback/details/776596/std-mutex-not-a-constexpr-with-mtd-compiler-flag -// http://stackoverflow.com/questions/14319344/stdmutex-lock-hangs-when-overriding-the-new-operator -// -# define NVWA_USE_CXX11_MUTEX 1 -# endif - -# if !defined(_WIN32THREADS) && \ - (defined(_WIN32) && defined(_MT)) -// Automatically use _WIN32THREADS when specifying -MT/-MD in MSVC, -// or -mthreads in MinGW GCC. -# define _WIN32THREADS -# elif !defined(_PTHREADS) && \ - defined(_REENTRANT) -// Automatically use _PTHREADS when specifying -pthread in GCC or Clang. -# define _PTHREADS -# endif -# endif - -# ifndef NVWA_USE_CXX11_MUTEX -# if HAVE_CXX11_MUTEX != 0 && \ - !defined(_NOTHREADS) && !defined(NVWA_NOTHREADS) && \ - !defined(_PTHREADS) && !defined(NVWA_PTHREADS) && \ - !defined(_WIN32THREADS) && !defined(NVWA_WIN32THREADS) -# define NVWA_USE_CXX11_MUTEX 1 -# else -# define NVWA_USE_CXX11_MUTEX 0 -# endif -# endif - -# if !defined(_PTHREADS) && !defined(_WIN32THREADS) && \ - !defined(_NOTHREADS) && NVWA_USE_CXX11_MUTEX == 0 -# define _NOTHREADS -# endif - -# if defined(_NOTHREADS) -# if defined(_PTHREADS) || defined(_WIN32THREADS) || \ - NVWA_USE_CXX11_MUTEX != 0 -# undef _NOTHREADS -# error "Cannot define multi-threaded mode with -D_NOTHREADS" -# endif -# endif - -# if defined(__MINGW32__) && defined(_WIN32THREADS) && !defined(_MT) -# error "Be sure to specify -mthreads with -D_WIN32THREADS" -# endif - -// With all the heuristics above, things may still go wrong, maybe even -// due to a specific inclusion order. So they may be overridden by -// manually defining the NVWA_* macros below. -# if NVWA_USE_CXX11_MUTEX == 0 && \ - !defined(NVWA_WIN32THREADS) && \ - !defined(NVWA_PTHREADS) && \ - !defined(NVWA_NOTHREADS) -// _WIN32THREADS takes precedence, as some C++ libraries have _PTHREADS -// defined even on Win32 platforms. -# if defined(_WIN32THREADS) -# define NVWA_WIN32THREADS -# elif defined(_PTHREADS) -# define NVWA_PTHREADS -# else -# define NVWA_NOTHREADS -# endif -# endif - -# ifndef _FAST_MUTEX_CHECK_INITIALIZATION -/** - * Macro to control whether to check for initialization status for each - * lock/unlock operation. Defining it to a non-zero value will enable - * the check, so that the construction/destruction of a static object - * using a static fast_mutex not yet constructed or already destroyed - * will work (with lock/unlock operations ignored). Defining it to zero - * will disable to check. - */ -# define _FAST_MUTEX_CHECK_INITIALIZATION 1 -# endif - -# ifdef _DEBUG -# include <stdio.h> -# include <stdlib.h> -/** Macro for fast_mutex assertions. Real version (for debug mode). */ -# define _FAST_MUTEX_ASSERT(_Expr, _Msg) \ - if (!(_Expr)) { \ - fprintf(stderr, "fast_mutex::%s\n", _Msg); \ - abort(); \ - } -# else -/** Macro for fast_mutex assertions. Fake version (for release mode). */ -# define _FAST_MUTEX_ASSERT(_Expr, _Msg) \ - ((void)0) -# endif - -# if NVWA_USE_CXX11_MUTEX != 0 -# include <mutex> -NVWA_NAMESPACE_BEGIN -/** - * Macro alias to `volatile' semantics. Here it is truly volatile since - * it is in a multi-threaded (C++11) environment. - */ -# define __VOLATILE volatile - /** - * Class for non-reentrant fast mutexes. This is the implementation - * using the C++11 mutex. - */ - class fast_mutex - { - std::mutex _M_mtx_impl; -# if _FAST_MUTEX_CHECK_INITIALIZATION - bool _M_initialized; -# endif -# ifdef _DEBUG - bool _M_locked; -# endif - public: - fast_mutex() -# ifdef _DEBUG - : _M_locked(false) -# endif - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - _M_initialized = true; -# endif - } - ~fast_mutex() - { - _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked"); -# if _FAST_MUTEX_CHECK_INITIALIZATION - _M_initialized = false; -# endif - } - void lock() - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - if (!_M_initialized) - return; -# endif - _M_mtx_impl.lock(); -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked"); - _M_locked = true; -# endif - } - void unlock() - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - if (!_M_initialized) - return; -# endif -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked"); - _M_locked = false; -# endif - _M_mtx_impl.unlock(); - } - private: - fast_mutex(const fast_mutex&); - fast_mutex& operator=(const fast_mutex&); - }; -NVWA_NAMESPACE_END -# elif defined(NVWA_PTHREADS) -# include <pthread.h> -NVWA_NAMESPACE_BEGIN -/** - * Macro alias to `volatile' semantics. Here it is truly volatile since - * it is in a multi-threaded (POSIX threads) environment. - */ -# define __VOLATILE volatile - /** - * Class for non-reentrant fast mutexes. This is the implementation - * for POSIX threads. - */ - class fast_mutex - { - pthread_mutex_t _M_mtx_impl; -# if _FAST_MUTEX_CHECK_INITIALIZATION - bool _M_initialized; -# endif -# ifdef _DEBUG - bool _M_locked; -# endif - public: - fast_mutex() -# ifdef _DEBUG - : _M_locked(false) -# endif - { - ::pthread_mutex_init(&_M_mtx_impl, _NULLPTR); -# if _FAST_MUTEX_CHECK_INITIALIZATION - _M_initialized = true; -# endif - } - ~fast_mutex() - { - _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked"); -# if _FAST_MUTEX_CHECK_INITIALIZATION - _M_initialized = false; -# endif - ::pthread_mutex_destroy(&_M_mtx_impl); - } - void lock() - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - if (!_M_initialized) - return; -# endif - ::pthread_mutex_lock(&_M_mtx_impl); -# ifdef _DEBUG - // The following assertion should _always_ be true for a - // real `fast' pthread_mutex. However, this assertion can - // help sometimes, when people forget to use `-lpthread' and - // glibc provides an empty implementation. Having this - // assertion is also more consistent. - _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked"); - _M_locked = true; -# endif - } - void unlock() - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - if (!_M_initialized) - return; -# endif -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked"); - _M_locked = false; -# endif - ::pthread_mutex_unlock(&_M_mtx_impl); - } - private: - fast_mutex(const fast_mutex&); - fast_mutex& operator=(const fast_mutex&); - }; -NVWA_NAMESPACE_END -# elif defined(NVWA_WIN32THREADS) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif /* WIN32_LEAN_AND_MEAN */ -# include <windows.h> -NVWA_NAMESPACE_BEGIN -/** - * Macro alias to `volatile' semantics. Here it is truly volatile since - * it is in a multi-threaded (Win32 threads) environment. - */ -# define __VOLATILE volatile - /** - * Class for non-reentrant fast mutexes. This is the implementation - * for Win32 threads. - */ - class fast_mutex - { - CRITICAL_SECTION _M_mtx_impl; -# if _FAST_MUTEX_CHECK_INITIALIZATION - bool _M_initialized; -# endif -# ifdef _DEBUG - bool _M_locked; -# endif - public: - fast_mutex() -# ifdef _DEBUG - : _M_locked(false) -# endif - { - ::InitializeCriticalSection(&_M_mtx_impl); -# if _FAST_MUTEX_CHECK_INITIALIZATION - _M_initialized = true; -# endif - } - ~fast_mutex() - { - _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked"); -# if _FAST_MUTEX_CHECK_INITIALIZATION - _M_initialized = false; -# endif - ::DeleteCriticalSection(&_M_mtx_impl); - } - void lock() - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - if (!_M_initialized) - return; -# endif - ::EnterCriticalSection(&_M_mtx_impl); -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked"); - _M_locked = true; -# endif - } - void unlock() - { -# if _FAST_MUTEX_CHECK_INITIALIZATION - if (!_M_initialized) - return; -# endif -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked"); - _M_locked = false; -# endif - ::LeaveCriticalSection(&_M_mtx_impl); - } - private: - fast_mutex(const fast_mutex&); - fast_mutex& operator=(const fast_mutex&); - }; -NVWA_NAMESPACE_END -# elif defined(NVWA_NOTHREADS) -NVWA_NAMESPACE_BEGIN -/** - * Macro alias to `volatile' semantics. Here it is not truly volatile - * since it is in a single-threaded environment. - */ -# define __VOLATILE - /** - * Class for non-reentrant fast mutexes. This is the null - * implementation for single-threaded environments. - */ - class fast_mutex - { -# ifdef _DEBUG - bool _M_locked; -# endif - public: - fast_mutex() -# ifdef _DEBUG - : _M_locked(false) -# endif - { - } - ~fast_mutex() - { - _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked"); - } - void lock() - { -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked"); - _M_locked = true; -# endif - } - void unlock() - { -# ifdef _DEBUG - _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked"); - _M_locked = false; -# endif - } - private: - fast_mutex(const fast_mutex&); - fast_mutex& operator=(const fast_mutex&); - }; -NVWA_NAMESPACE_END -# endif // Definition of class fast_mutex - -NVWA_NAMESPACE_BEGIN -/** RAII lock class for fast_mutex. */ -class fast_mutex_autolock -{ - fast_mutex& _M_mtx; -public: - explicit fast_mutex_autolock(fast_mutex& mtx) : _M_mtx(mtx) - { - _M_mtx.lock(); - } - ~fast_mutex_autolock() - { - _M_mtx.unlock(); - } -private: - fast_mutex_autolock(const fast_mutex_autolock&); - fast_mutex_autolock& operator=(const fast_mutex_autolock&); -}; -NVWA_NAMESPACE_END - -#endif // NVWA_FAST_MUTEX_H diff --git a/src/debug/nvwa/source.txt b/src/debug/nvwa/source.txt deleted file mode 100644 index 93a15332c..000000000 --- a/src/debug/nvwa/source.txt +++ /dev/null @@ -1 +0,0 @@ -https://github.com/adah1972/nvwa diff --git a/src/debug/nvwa/static_assert.h b/src/debug/nvwa/static_assert.h deleted file mode 100644 index 877ef0f97..000000000 --- a/src/debug/nvwa/static_assert.h +++ /dev/null @@ -1,62 +0,0 @@ -// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -// vim:tabstop=4:shiftwidth=4:expandtab: - -/* - * Copyright (C) 2004-2013 Wu Yongwei <adah at users dot sourceforge dot net> - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any - * damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute - * it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must - * not claim that you wrote the original software. If you use this - * software in a product, an acknowledgement in the product - * documentation would be appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source - * distribution. - * - * This file is part of Stones of Nvwa: - * http://sourceforge.net/projects/nvwa - * - */ - -/** - * @file static_assert.h - * - * Template class to check validity duing compile time (adapted from Loki). - * - * @date 2013-09-07 - */ - -#ifndef STATIC_ASSERT - -#include "debug/nvwa/c++11.h" - -#if HAVE_CXX11_STATIC_ASSERT - -#define STATIC_ASSERT(_Expr, _Msg) static_assert(_Expr, #_Msg) - -#else - -namespace nvwa { - -template <bool> struct compile_time_error; -template <> struct compile_time_error<true> {}; - -#define STATIC_ASSERT(_Expr, _Msg) \ - { \ - nvwa::compile_time_error<((_Expr) != 0)> ERROR_##_Msg; \ - (void)ERROR_##_Msg; \ - } - -} - -#endif // HAVE_CXX11_STATIC_ASSERT - -#endif // STATIC_ASSERT diff --git a/src/debug/readme.txt b/src/debug/readme.txt deleted file mode 100644 index bee507459..000000000 --- a/src/debug/readme.txt +++ /dev/null @@ -1,2 +0,0 @@ -mse and nvwa libraries not used by default. -For enable it, see configure flags. |