OGLplus  (0.59.0) a C++ wrapper for rendering APIs

align_alloc.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_MEMORY_ALIGN_ALLOC_HPP
10 #define EAGINE_MEMORY_ALIGN_ALLOC_HPP
11 
12 #include "../assert.hpp"
13 #include "../instead_of.hpp"
14 #include "../int_constant.hpp"
15 #include "default_alloc.hpp"
16 #include "shared_alloc.hpp"
17 #include <array>
18 #include <utility>
19 
20 namespace eagine::memory {
21 
22 // multi_align_byte_allocator - fwd
23 template <typename AlignSeq, typename Policy = default_byte_allocator_policy>
24 class multi_align_byte_allocator;
25 
26 // multi_align_byte_allocator
27 template <std::size_t... Align, typename Policy>
28 class multi_align_byte_allocator<std::index_sequence<Align...>, Policy>
29  : public byte_allocator_impl<
30  Policy,
31  multi_align_byte_allocator,
32  std::index_sequence<Align...>> {
33 public:
34  multi_align_byte_allocator(
35  instead_of_t<size_constant<Align>, shared_byte_allocator>... aligned_alloc,
36  shared_byte_allocator fallback_alloc = default_byte_allocator())
37  : _alignment{{Align...}}
38  , _aligned_alloc{{std::move(aligned_alloc)...}}
39  , _fallback_alloc(std::move(fallback_alloc)) {}
40 
41  using value_type = byte;
42  using size_type = span_size_t;
43 
44  auto equal(byte_allocator* a) const noexcept -> bool override {
45  if(auto* that = dynamic_cast<multi_align_byte_allocator*>(a)) {
46  for(std::size_t i = 0; i < _aligned_alloc.size(); ++i) {
47  if(_aligned_alloc[i] != that->_aligned_alloc[i]) {
48  return false;
49  }
50  }
51 
52  return _fallback_alloc == that->_fallback_alloc;
53  }
54  return false;
55  }
56 
57  auto max_size(span_size_t a) noexcept -> size_type override {
58  return _get_alloc(a).max_size(a);
59  }
60 
61  auto has_allocated(const owned_block& b, span_size_t a) noexcept
62  -> tribool override {
63  for(std::size_t i = 0; i < _aligned_alloc.size(); ++i) {
64  if(_aligned_alloc[i].has_allocated(b, a)) {
65  return true;
66  }
67  }
68  return _fallback_alloc.has_allocated(b, a);
69  }
70 
71  auto allocate(size_type n, size_type a) noexcept -> owned_block override {
72  return _get_alloc(a).allocate(n, a);
73  }
74 
75  void deallocate(owned_block&& b, size_type a) noexcept override {
76  EAGINE_ASSERT(!!_get_alloc(a).has_allocated(b, a));
77  _get_alloc(a).deallocate(std::move(b), a);
78  }
79 
80 private:
81  std::array<span_size_t, sizeof...(Align)> _alignment;
82 
83  std::array<shared_byte_allocator, sizeof...(Align)> _aligned_alloc;
84 
85  shared_byte_allocator _fallback_alloc;
86 
87  auto _get_alloc(span_size_t align) -> shared_byte_allocator& {
88  EAGINE_ASSERT(_alignment.size() == _aligned_alloc.size());
89  for(std::size_t i = 0; i < _alignment.size(); ++i) {
90  if(_alignment[i] == align) {
91  return _aligned_alloc[i];
92  }
93  }
94  return _fallback_alloc;
95  }
96 };
97 
98 } // namespace eagine::memory
99 
100 #endif // EAGINE_MEMORY_ALIGN_ALLOC_HPP
value_type
Value tree value element data type enumeration.
Definition: interface.hpp:27
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
unsigned char byte
Byte type alias.
Definition: types.hpp:24
typename instead_of< Src, Dst >::type instead_of_t
Definition: instead_of.hpp:29

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).