neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
i_contiguous_random_access_container.hpp
Go to the documentation of this file.
1// i_random_access_container.hpp
2/*
3 * Copyright (c) 2019, 2020 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
40
41namespace neolib
42{
43 template <typename T, typename = sfinae>
45 template <typename T>
46 struct offset_pointer<T, typename std::enable_if_t<std::is_const_v<T>, sfinae>> { typedef char const* pointer_type; };
47 template <typename T>
48 struct offset_pointer<T, typename std::enable_if_t<!std::is_const_v<T>, sfinae>> { typedef char* pointer_type; };
49 template <typename T>
51
52 template <typename T>
54 {
55 template <typename T2>
56 friend class offset_iterator;
57 typedef offset_iterator<T> self_type;
58 public:
59 using iterator_category = std::random_access_iterator_tag;
60 using value_type = T;
61 using pointer = T*;
62 using reference = T&;
63 using difference_type = std::ptrdiff_t;
64 public:
66 iElement{}, iOffset{}
67 {
68 }
69 offset_iterator(std::nullptr_t) :
70 iElement{}, iOffset{}
71 {
72 }
73 offset_iterator(T* aElement, std::ptrdiff_t aOffset) :
74 iElement{ aElement }, iOffset{ aOffset }
75 {
76 }
77 offset_iterator(const self_type& aOther) :
78 iElement{ aOther.iElement }, iOffset{ aOther.iOffset }
79 {
80 }
81 template <typename Iterator>
82 offset_iterator(const Iterator& aOther, std::enable_if_t<!std::is_same_v<Iterator, self_type> && std::is_same_v<Iterator, offset_iterator<std::remove_const_t<value_type>>>, sfinae> = {}) :
83 iElement{ aOther.iElement }, iOffset{ aOther.iOffset }
84 {
85 }
86 public:
87 offset_iterator& operator++() { return *this += 1; }
88 offset_iterator& operator--() { return *this -= 1; }
89 offset_iterator operator++(int) { offset_iterator result = *this; ++(*this); return result; }
90 offset_iterator operator--(int) { offset_iterator result = *this; --(*this); return result; }
91 offset_iterator& operator+=(difference_type aDifference) { iElement = reinterpret_cast<T*>(ptr() + aDifference * iOffset); return *this; }
92 offset_iterator& operator-=(difference_type aDifference) { iElement = reinterpret_cast<T*>(ptr() - aDifference * iOffset); return *this; }
93 offset_iterator operator+(difference_type aDifference) const { offset_iterator result = *this; result += aDifference; return result; }
94 offset_iterator operator-(difference_type aDifference) const { offset_iterator result = *this; result -= aDifference; return result; }
95 reference operator[](difference_type aDifference) const { return *(*this + aDifference); }
96 difference_type operator-(const offset_iterator& aOther) const { return (ptr() - aOther.ptr()) / iOffset; }
97 reference operator*() const { return *iElement; }
98 pointer operator->() const { return &(**this); }
99 bool operator==(const offset_iterator& aOther) const { return iElement == aOther.iElement; }
100 bool operator!=(const offset_iterator& aOther) const { return iElement != aOther.iElement; }
101 bool operator<(const offset_iterator& aOther) const { return iElement < aOther.iElement; }
102 bool operator<=(const offset_iterator& aOther) const { return iElement <= aOther.iElement; }
103 bool operator>(const offset_iterator& aOther) const { return iElement > aOther.iElement; }
104 bool operator>=(const offset_iterator& aOther) const { return iElement >= aOther.iElement; }
105 private:
106 offset_pointer_t<T> ptr() const { return reinterpret_cast<offset_pointer_t<T>>(iElement); }
107 private:
108 T* iElement;
109 std::ptrdiff_t iOffset;
110 };
111
112 template <typename T>
114 {
117 public:
119 public:
120 using typename base_type::value_type;
121 using typename base_type::size_type;
124 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
125 typedef std::reverse_iterator<iterator> reverse_iterator;
126 public:
127 using base_type::size;
128 public:
129 virtual const value_type* cdata() const noexcept = 0;
130 virtual const value_type* data() const noexcept = 0;
131 virtual value_type* data() noexcept = 0;
132 public:
133 virtual const value_type& at(size_type aIndex) const = 0;
134 virtual value_type& at(size_type aIndex) = 0;
135 virtual const value_type& operator[](size_type aIndex) const = 0;
136 virtual value_type& operator[](size_type aIndex) = 0;
137 public:
138 const_iterator cbegin() const { return const_iterator{ cdata(), iterator_offset() }; }
139 const_iterator begin() const { return cbegin(); }
140 iterator begin() { return iterator{ data(), iterator_offset() }; }
141 const_iterator cend() const { return cbegin() + size(); }
142 const_iterator end() const { return cend(); }
143 iterator end() { return begin() + size(); }
148 const_reverse_iterator rend() const { return crend(); }
150 iterator insert(const const_iterator& aPosition, const value_type& aValue) { return to_iterator(base_type::insert(from_iterator(aPosition), aValue)); }
151 iterator erase(const const_iterator& aPosition) { return to_iterator(base_type::erase(from_iterator(aPosition))); }
152 private:
153 virtual std::ptrdiff_t iterator_offset() const = 0;
154 typename base_type::const_iterator from_iterator(const_iterator aPosition) const
155 {
156 return std::next(base_type::cbegin(), std::distance(cbegin(), aPosition));
157 }
158 typename base_type::iterator from_iterator(iterator aPosition)
159 {
160 return std::next(base_type::begin(), std::distance(begin(), aPosition));
161 }
162 const_iterator to_iterator(typename base_type::const_iterator aPosition) const
163 {
164 return std::next(cbegin(), std::distance(base_type::cbegin(), aPosition));
165 }
166 iterator to_iterator(typename base_type::iterator aPosition)
167 {
168 return std::next(begin(), std::distance(base_type::begin(), aPosition));
169 }
170 };
171}
iterator erase(const abstract_iterator &aPosition)
virtual size_type size() const noexcept=0
const_iterator begin() const
abstract_const_iterator::iterator_wrapper const_iterator
const_iterator cbegin() const
abstract_iterator::iterator_wrapper iterator
iterator insert(const const_iterator &aPosition, const value_type &aValue)
virtual const value_type & at(size_type aIndex) const =0
virtual const value_type * data() const noexcept=0
virtual const value_type * cdata() const noexcept=0
bool operator==(const offset_iterator &aOther) const
offset_iterator operator-(difference_type aDifference) const
bool operator>(const offset_iterator &aOther) const
bool operator<=(const offset_iterator &aOther) const
bool operator>=(const offset_iterator &aOther) const
std::random_access_iterator_tag iterator_category
bool operator!=(const offset_iterator &aOther) const
difference_type operator-(const offset_iterator &aOther) const
offset_iterator operator+(difference_type aDifference) const
offset_iterator & operator-=(difference_type aDifference)
bool operator<(const offset_iterator &aOther) const
offset_iterator(const Iterator &aOther, std::enable_if_t<!std::is_same_v< Iterator, self_type > &&std::is_same_v< Iterator, offset_iterator< std::remove_const_t< value_type > > >, sfinae >={})
reference operator[](difference_type aDifference) const
offset_iterator & operator+=(difference_type aDifference)
offset_iterator(T *aElement, std::ptrdiff_t aOffset)
typename offset_pointer< T >::pointer_type offset_pointer_t
Definition plf_hive.h:79
it_type next(it_type it, const typename iterator_traits< it_type >::difference_type distance=1)
Definition plf_hive.h:89
iterator_traits< it_type >::difference_type distance(const it_type first, const it_type last)
Definition plf_hive.h:107