Banuba SDK
common.hpp
1 #pragma once
2 
3 #include <stdexcept>
4 #include <memory>
5 
6 namespace bnb::player_api
7 {
8 
9  template<class T>
10  void validate_not_null(const T& ptr)
11  {
12  if (ptr == nullptr) {
13  throw std::runtime_error("Pointer cannot be `nullptr`.");
14  }
15  }
16 
17  template<std::size_t value>
18  constexpr bool is_pow_of_two()
19  {
20  return (value != 0) && !(value & (value - 1));
21  }
22 
23  template<std::size_t align, class T>
24  T align_by(T x)
25  {
26  static_assert(is_pow_of_two<align>(), "Alignment must be a power of two.");
27  constexpr auto align_bits = align - 1;
28  return (x + align_bits) & ~align_bits;
29  }
30 
31  template<class T>
32  T align_by_8(T x)
33  {
34  return align_by<8>(x);
35  }
36 
37  template<class T>
38  T align_by_16(T x)
39  {
40  return align_by<16>(x);
41  }
42 
43  template<class T>
44  T align_by_32(T x)
45  {
46  return align_by<32>(x);
47  }
48 
49  template<class T>
50  T align_by_64(T x)
51  {
52  return align_by<64>(x);
53  }
54 
55  template<std::size_t mem_align>
56  inline uint8_t* aligned_alloc(std::size_t size)
57  {
58  // memory struct: ...*-----------------------*---------------*------------------...---*
59  // ^ ^ ^ ^
60  // (real ptr) (shift to real ptr) (aligned ptr) (end of memory block)
61  // (shift to real ptr) = (aligned ptr) - 8
62  static_assert(is_pow_of_two<mem_align>() && mem_align >= 8, "Alignment must be a power of two and more than 8.");
63  auto full_size = size + mem_align + 8;
64  auto* real_ptr = std::malloc(full_size);
65  constexpr auto align_bits = mem_align - 1;
66  auto* aligned_ptr = reinterpret_cast<uint8_t*>(((reinterpret_cast<std::size_t>(real_ptr) + 8) + align_bits) & ~align_bits);
67  auto* shift_to_real_ptr = reinterpret_cast<std::size_t*>(aligned_ptr - 8);
68  *shift_to_real_ptr = static_cast<std::size_t>(aligned_ptr - reinterpret_cast<uint8_t*>(real_ptr));
69  return aligned_ptr;
70  }
71 
72  inline void aligned_dealloc(uint8_t* p)
73  {
74  auto shift = *reinterpret_cast<std::size_t*>(p - 8);
75  auto* real_ptr = p - shift;
76  std::free(real_ptr);
77  }
78 
79 } // namespace bnb::player_api