utils.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /* Declarations for miscelaneous utilities.
  2. This file is part of xrcu.
  3. xrcu is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>. */
  13. #ifndef __XRCU_UTILS_HPP__
  14. #define __XRCU_UTILS_HPP__ 1
  15. #include "xrcu.hpp"
  16. #include <cstddef>
  17. #include <cstdint>
  18. #include <utility>
  19. namespace xrcu
  20. {
  21. namespace detail
  22. {
  23. void* alloc_wrapped (size_t size);
  24. void dealloc_wrapped (void *ptr);
  25. template <class T>
  26. void destroy (void *ptr)
  27. {
  28. ((T *)ptr)->~T ();
  29. }
  30. template <class T>
  31. struct alignas (8) type_wrapper : public finalizable
  32. {
  33. T value;
  34. type_wrapper (const T& val) : value (val)
  35. {
  36. }
  37. template <class ...Args>
  38. type_wrapper (Args&&... args) : value (std::forward<Args>(args)...)
  39. {
  40. }
  41. void safe_destroy ()
  42. {
  43. destroy<T> (&this->value);
  44. dealloc_wrapped (this);
  45. }
  46. };
  47. template <bool Integral, class T>
  48. struct wrapped_traits
  49. {
  50. static const uintptr_t XBIT = (uintptr_t)1 << (sizeof (uintptr_t) * 8 - 1);
  51. static const uintptr_t FREE = (~(uintptr_t)0) & ~XBIT;
  52. static const uintptr_t DELT = FREE >> 1;
  53. typedef T value_type;
  54. static uintptr_t make (T val)
  55. {
  56. return ((uintptr_t)(typename std::make_unsigned<T>::type)val);
  57. }
  58. static T get (uintptr_t w)
  59. {
  60. return ((T)(w & ~XBIT));
  61. }
  62. static void destroy (uintptr_t) {}
  63. static void free (uintptr_t) {}
  64. };
  65. template <class T>
  66. struct wrapped_traits<false, T>
  67. {
  68. static const uintptr_t XBIT = 1;
  69. static const uintptr_t FREE = 2;
  70. static const uintptr_t DELT = 4;
  71. typedef T value_type;
  72. typedef type_wrapper<T> wrapped_type;
  73. static uintptr_t make (const T& val)
  74. {
  75. auto rv = (wrapped_type *)alloc_wrapped (sizeof (wrapped_type));
  76. try
  77. {
  78. new (rv) wrapped_type (val);
  79. return ((uintptr_t)rv);
  80. }
  81. catch (...)
  82. {
  83. dealloc_wrapped (rv);
  84. throw;
  85. }
  86. }
  87. template <class ...Args>
  88. static uintptr_t make (Args&&... args)
  89. {
  90. auto rv = (wrapped_type *)alloc_wrapped (sizeof (wrapped_type));
  91. try
  92. {
  93. new (rv) wrapped_type (std::forward<Args>(args)...);
  94. return ((uintptr_t)rv);
  95. }
  96. catch (...)
  97. {
  98. dealloc_wrapped (rv);
  99. throw;
  100. }
  101. }
  102. static uintptr_t make (T&& val)
  103. {
  104. auto rv = (wrapped_type *)alloc_wrapped (sizeof (wrapped_type));
  105. try
  106. {
  107. new (rv) wrapped_type (std::forward<T&&> (val));
  108. return ((uintptr_t)rv);
  109. }
  110. catch (...)
  111. {
  112. dealloc_wrapped (rv);
  113. throw;
  114. }
  115. }
  116. static T& get (uintptr_t addr)
  117. {
  118. return (((wrapped_type *)(addr & ~XBIT))->value);
  119. }
  120. static void destroy (uintptr_t addr)
  121. {
  122. finalize ((wrapped_type *)addr);
  123. }
  124. static void free (uintptr_t addr)
  125. {
  126. ((wrapped_type *)addr)->safe_destroy ();
  127. }
  128. };
  129. } // namespace detail
  130. } // namespace xrcu
  131. #endif