2 #ifndef KJY_OBJECT_ORIENTED_OPENGL_CORE_UTILITIES_HPP_ 3 #define KJY_OBJECT_ORIENTED_OPENGL_CORE_UTILITIES_HPP_ 8 #include "OOOGL_Core.hpp" 17 std::map<GLuint, ConstPersistentOglName> possessed_items;
20 template<
class P,
class... Possessibles>
22 typedef std::pair<GLuint, ConstPersistentOglName> item_pair_t;
24 virtual size_t numPossessed()
const {
return(AbstractGenericPossessor::possessed_items.size());}
25 virtual void possessObject(P possessible_object)
override{
26 AbstractGenericPossessor::possessed_items.emplace(item_pair_t(possessible_object.getNameDirect(), possessible_object));
28 virtual bool doesPossessObject(P possessible_object)
const override{
29 return(AbstractGenericPossessor::possessed_items.find(possessible_object.getNameDirect()) == AbstractGenericPossessor::possessed_items.end());
31 virtual void dispossessObject(
const P& possessible_object)
override{
32 if(doesPossessObject(possessible_object)){
33 AbstractGenericPossessor::possessed_items.erase(possessible_object.getNameDirect());
45 virtual void possessObject(
OglObject object)
override;
49 virtual bool doesPossessObject(
OglObject object)
const override;
53 virtual void dispossessObject(
const OglObject&
object)
override;
56 std::map<GLuint, ConstPersistentOglName> possessed_items;
66 virtual const char* what()
const noexcept
override{
67 return(
"Optional OpenGL object does not contain a value");
73 template<
typename... Args>
OptionalGlObject(Args&&... args) : _encapsulated_object_(args...) {}
75 void reset() {_encapsulated_object_ = T(_zombie_name);}
76 bool has_value()
const {
return(_has_value_());}
77 T& value() & {_assert_has_value();
return(_encapsulated_object_);}
78 const T& value()
const& {_assert_has_value();
return(_encapsulated_object_);}
82 template<
typename... Args>
void emplace(Args&&... args) {_encapsulated_object_ = T(args...);}
84 OptionalGlObject& operator=(
const std::nullopt_t nullopt){_encapsulated_object_ = T(_zombie_name);}
85 const T* operator->()
const {_assert_has_value();
return(&_encapsulated_object_);}
86 T* operator->() {_assert_has_value();
return(&_encapsulated_object_);}
87 const T& operator*()
const& {_assert_has_value();
return(_encapsulated_object_);}
88 T& operator*() & {_assert_has_value();
return(_encapsulated_object_);}
91 operator bool()
const {
return(_has_value_());}
94 inline bool _has_value_()
const {
return(!_encapsulated_object_.isZombie());}
96 T _encapsulated_object_;
106 virtual const char* what()
const noexcept
override{
return(_whatstr.c_str());}
108 const std::string _whatstr;
112 UnoccupiedIndexException(GLuint index) : _whatstr(
"Attempted to extract reference from unoccupied index in IndexBindingVector: '" + std::to_string(index) +
"'") {}
113 virtual const char* what()
const noexcept
override{
return(_whatstr.c_str());}
115 const std::string _whatstr;
118 template<
class BoundType,
class IteratorBundle,
typename SizeType =
size_t,
class Allocator = std::allocator<BoundType>>
121 using iterator =
typename IteratorBundle::iterator;
122 using const_iterator =
typename IteratorBundle::const_iterator;
123 using size_type = SizeType;
124 using allocator_type = Allocator;
126 bool isOccupied(size_type pos)
const =
delete;
127 iterator begin() =
delete;
128 const_iterator begin()
const =
delete;
129 BoundType& at(size_type pos) =
delete;
130 const BoundType& at(size_type pos)
const =
delete;
131 size_type size()
const =
delete;
132 void set(size_type pos,
const BoundType& value) =
delete;
133 void clear() =
delete;
134 void clearIndex(size_type pos) =
delete;
135 iterator erase(iterator pos) =
delete;
136 const_iterator erase(const_iterator pos) =
delete;
139 template<
typename internal_iterator,
template<
typename _
internal_iterator>
class OccupationChecker,
typename index_type = GLuint>
141 template<
typename B,
typename IB,
typename ST,
typename A>
143 static_assert(std::is_trivially_constructible<OccupationChecker<internal_iterator>>::value,
"Occupation checker must be trivially constructable");
144 static_assert(std::is_invocable<OccupationChecker<internal_iterator>, internal_iterator>::value,
"Occupation checker must be a callable bool function taking <internal_iterator> as its only parameter");
145 using reference = std::nullptr_t ;
146 using pointer = std::nullptr_t ;
149 reference operator*()
const =
delete;
150 pointer operator->()
const =
delete;
152 if(_internal == _end)
return(*
this);
155 std::advance(_internal,1);
156 }
while(_internal != _end && !_is_occupied(_internal));
163 index_type getIndex()
const {
return(index);}
165 index_type index = 0;
166 internal_iterator _internal;
167 internal_iterator _end;
168 const OccupationChecker<internal_iterator> _is_occupied;
171 template<
typename iterator>
174 template<
class BoundType,
typename internal_iterator,
template<
typename _
internal_iterator>
class OccupationChecker>
178 using reference = std::pair<GLuint, BoundType&>;
179 using pointer = BoundType*;
182 reference operator*()
const{
183 return(std::pair<GLuint, BoundType&>(Abstract_Parent::index, **Abstract_Parent::_internal));
185 pointer operator->()
const{
186 return(&**Abstract_Parent::_internal);
190 template<
class BoundType>
198 <BoundType,
typename std::vector<BoundType*>::const_iterator, IndexedPointersOccupationChecker>
202 template<
class BoundType>
205 typedef std::vector<BoundType*> base_vector;
206 using internal_iterator =
typename std::vector<BoundType*>::iterator;
207 using const_internal_iterator =
typename std::vector<BoundType*>::const_iterator;
210 using reference =
typename const_iterator::reference;
211 using const_reference =
typename const_iterator::reference;
212 using size_type =
typename std::vector<BoundType*>::size_type;
213 using allocator_type =
typename std::vector<BoundType*>::allocator_type;
217 IndexedPointersVector(size_type count, BoundType* value,
const allocator_type& alloc = allocator_type()) : base_vector(count, value, alloc) {}
219 for(const_internal_iterator itr = base_vector::begin(); itr != base_vector::end(); itr++){
220 if(*itr!=
nullptr)
delete *itr;
224 iterator begin() {
return(IndexedPointersVector<BoundType>::iterator(base_vector::begin(), base_vector::end()));}
225 const_iterator begin()
const {
return(IndexedPointersVector<BoundType>::const_iterator(base_vector::begin(), base_vector::end()));}
226 iterator end() {
return(IndexedPointersVector<BoundType>::iterator(base_vector::end(), base_vector::end()));}
227 const_iterator end()
const {
return(IndexedPointersVector<BoundType>::const_iterator(base_vector::end(), base_vector::end()));}
228 internal_iterator beginInternal() {
return(base_vector::begin());}
229 const_internal_iterator beginInternal()
const {
return(base_vector::begin());}
230 internal_iterator endInternal() {
return(base_vector::end());}
231 const_internal_iterator endInternal()
const {
return(base_vector::end());}
233 inline bool isOccupied(size_type pos)
const {
return(pos >= 0 && pos < base_vector::size() && base_vector::at(pos) !=
nullptr);}
235 BoundType& at(size_type pos) {_assert_occupied_index(pos);
return(*base_vector::at(pos));}
236 const BoundType& at(size_type pos)
const {_assert_occupied_index(pos);
return(*base_vector::at(pos));}
237 inline BoundType& operator[](size_type pos) {
return(at(pos));}
238 inline const BoundType& operator[](size_type pos)
const {
return(at(pos));}
239 size_type size()
const {
return(_occupied_count);}
240 using base_vector::capacity;
242 void set(size_type pos,
const BoundType& value) {
243 _assert_valid_index(pos);
245 delete base_vector::at(pos);
249 base_vector::at(pos) =
new BoundType(value);
251 void clearIndex(size_type pos) {
252 _assert_valid_index(pos);
253 const BoundType* ptr_at_index = base_vector::at(pos);
254 if(ptr_at_index !=
nullptr){
256 base_vector::at(pos) =
nullptr;
261 for(internal_iterator itr = base_vector::begin(); itr != base_vector::end(); itr++){
262 if(*itr !=
nullptr)
delete (*itr);
266 iterator erase(iterator pos){
267 if(pos == end())
return(end());
268 clearIndex(pos.getIndex());
271 const_iterator erase(const_iterator pos){
272 if(pos == end())
return(end());
273 clearIndex(pos.getIndex());
278 size_t _occupied_count = 0;
280 void _assert_occupied_index(size_type index){_assert_valid_index(index);
if(!isOccupied(index))
throw UnoccupiedIndexException(index);}
283 template<
typename iterator>
286 template<
class BoundType>
294 <BoundType,
typename std::vector<std::optional<BoundType>>
::const_iterator, IndexedPointersOccupationChecker>
298 template<
class BoundType>
301 typedef std::vector<std::optional<BoundType>> base_vector;
302 using internal_iterator =
typename base_vector::iterator;
303 using const_internal_iterator =
typename base_vector::const_iterator;
306 using reference =
typename const_iterator::reference;
307 using const_reference =
typename const_iterator::reference;
308 using size_type =
typename base_vector::size_type;
309 using allocator_type =
typename base_vector::allocator_type;
313 OptionalIndexedBindingVector(size_type count,
const std::optional<BoundType>& value,
const allocator_type& alloc = allocator_type()) : base_vector(count, value, alloc) {}
316 iterator begin() {
return(OptionalIndexedBindingVector<BoundType>::iterator(base_vector::begin(), base_vector::end()));}
317 const_iterator begin()
const {
return(OptionalIndexedBindingVector<BoundType>::const_iterator(base_vector::begin(), base_vector::end()));}
318 iterator end() {
return(OptionalIndexedBindingVector<BoundType>::iterator(base_vector::end(), base_vector::end()));}
319 const_iterator end()
const {
return(OptionalIndexedBindingVector<BoundType>::const_iterator(base_vector::end(), base_vector::end()));}
320 internal_iterator beginInternal() {
return(base_vector::begin());}
321 const_internal_iterator beginInternal()
const {
return(base_vector::begin());}
322 internal_iterator endInternal() {
return(base_vector::end());}
323 const_internal_iterator endInternal()
const {
return(base_vector::end());}
325 inline bool isOccupied(size_type pos)
const {
return(pos >= 0 && pos < base_vector::size() && base_vector::at(pos));}
327 BoundType& at(size_type pos) {_assert_occupied_index(pos);
return(*base_vector::at(pos));}
328 const BoundType& at(size_type pos)
const {_assert_occupied_index(pos);
return(*base_vector::at(pos));}
329 inline BoundType& operator[](size_type pos) {
return(at(pos));}
330 inline const BoundType& operator[](size_type pos)
const {
return(at(pos));}
331 size_type size()
const {
return(_occupied_count);}
332 using base_vector::capacity;
334 void set(size_type pos,
const BoundType& value) {
335 _assert_valid_index(pos);
336 if(!isOccupied(pos)){
339 base_vector::at(pos) = std::optional<BoundType>(value);
341 void clearIndex(size_type pos) {
342 _assert_valid_index(pos);
343 if(base_vector::at(pos)){
344 base_vector::at(pos) = std::optional<BoundType>();
349 for(internal_iterator itr = base_vector::begin(); itr != base_vector::end(); itr++){
350 *itr = std::optional<BoundType>();
354 iterator erase(iterator pos){
355 if(pos == end())
return(end());
356 clearIndex(pos.getIndex());
359 const_iterator erase(const_iterator pos){
360 if(pos == end())
return(end());
361 clearIndex(pos.getIndex());
366 size_t _occupied_count = 0;
368 void _assert_occupied_index(size_type index)
const {_assert_valid_index(index);
if(!isOccupied(index))
throw UnoccupiedIndexException(index);}
Definition: Core_Utilities.hpp:119
Definition: Core_Utilities.hpp:103
Definition: Core_Utilities.hpp:203
Definition: OOOGL_Core.hpp:92
Definition: Core_Utilities.hpp:15
Definition: OOOGL_Core.hpp:119
Definition: Core_Utilities.hpp:39
Definition: OOOGL_Core.hpp:144
Definition: Core_Utilities.hpp:191
Definition: OOOGL_Core.hpp:105
Definition: Core_Utilities.hpp:140
Definition: OOOGL_Core.hpp:74
Definition: Core_Utilities.hpp:175
Definition: Core_Utilities.hpp:62
Definition: Core_Utilities.hpp:299
Definition: Core_Utilities.hpp:110
Definition: Core_Utilities.cpp:3
Definition: Core_Utilities.hpp:287
Definition: Core_Utilities.hpp:284
Definition: Core_Utilities.hpp:65
Definition: Core_Utilities.hpp:172