summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2017-07-13 22:49:03 +0300
committerAndrei Karas <akaras@inbox.ru>2017-07-13 22:49:03 +0300
commitc3b4284ee079539892e510f7ccd1768c793e9b5f (patch)
tree0dcdbe3a187c85008aa229c401107f0e6c429656
parentf2b51ca5984fc464fbcee652b13c0287752d3c7a (diff)
downloadplus-c3b4284ee079539892e510f7ccd1768c793e9b5f.tar.gz
plus-c3b4284ee079539892e510f7ccd1768c793e9b5f.tar.bz2
plus-c3b4284ee079539892e510f7ccd1768c793e9b5f.tar.xz
plus-c3b4284ee079539892e510f7ccd1768c793e9b5f.zip
Add mse libs for replacing std::vector.
Also add configure flag --enable-stldebug For now unused.
-rwxr-xr-xconfigure.ac13
-rw-r--r--src/Makefile.am12
-rw-r--r--src/debug/mse/msemsevector.h2433
-rw-r--r--src/debug/mse/msemstdvector.h396
-rw-r--r--src/debug/mse/mseprimitives.h873
5 files changed, 3727 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 6ee8ce327..8da4ee8d0 100755
--- a/configure.ac
+++ b/configure.ac
@@ -92,6 +92,19 @@ esac],[glibcdebug_enabled=false])
AM_CONDITIONAL(ENABLE_GLIBCDEBUG, test x$glibcdebug_enabled = xtrue)
+# Enable mse classes replacements for stl
+AC_ARG_ENABLE(stldebug,
+[ --enable-stldebug Enable mse libs],
+[case "${enableval}" in
+ yes) stldebug_enabled=true
+ ;;
+ no) stldebug_enabled=false
+ ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-stldebug) ;;
+esac],[stldebug_enabled=false])
+
+AM_CONDITIONAL(ENABLE_STLDEBUG, test x$stldebug_enabled = xtrue)
+
# Enable OpenGL error reporting
AC_ARG_ENABLE(openglerrors,
[ --enable-openglerrors Enable OpenGL errors reporting],
diff --git a/src/Makefile.am b/src/Makefile.am
index 5bf511b92..af00bbdf8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -132,6 +132,18 @@ manaplus_SOURCES =
dyecmd_SOURCES =
endif
+if ENABLE_STLDEBUG
+dyecmd_CXXFLAGS += -DENABLE_STL_DEBUG
+manaplus_CXXFLAGS += -DENABLE_STL_DEBUG -DDEBUG_DUMP_LEAKS
+
+manaplus_SOURCES += debug/mse/msemsevector.h \
+ debug/mse/msemstdvector.h \
+ debug/mse/mseprimitives.h
+dyecmd_SOURCES += debug/mse/msemsevector.h \
+ debug/mse/msemstdvector.h \
+ debug/mse/mseprimitives.h
+endif
+
if MINGW
manaplus_SOURCES += manaplus.rc
dyecmd_SOURCES += manaplus.rc
diff --git a/src/debug/mse/msemsevector.h b/src/debug/mse/msemsevector.h
new file mode 100644
index 000000000..5ac2c4536
--- /dev/null
+++ b/src/debug/mse/msemsevector.h
@@ -0,0 +1,2433 @@
+
+// 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)
+
+#pragma once
+#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
new file mode 100644
index 000000000..4cb92be7a
--- /dev/null
+++ b/src/debug/mse/msemstdvector.h
@@ -0,0 +1,396 @@
+
+// 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)
+
+#pragma once
+#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;
+ }
+
+
+ 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
new file mode 100644
index 000000000..b470288b9
--- /dev/null
+++ b/src/debug/mse/mseprimitives.h
@@ -0,0 +1,873 @@
+
+// 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)
+
+#pragma once
+#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*/