TriviallyCopyable.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2024-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #ifndef ZT_TRIVIALLYCOPYABLE_HPP
  14. #define ZT_TRIVIALLYCOPYABLE_HPP
  15. #include "Constants.hpp"
  16. #include "Utils.hpp"
  17. #include <cstring>
  18. #include <cstdlib>
  19. namespace ZeroTier {
  20. /**
  21. * This is a class that others can inherit from to tag themselves as safe to abuse in C-like ways with memcpy, etc.
  22. *
  23. * Later versions of C++ have a built-in auto-detected notion like this, but
  24. * this is more explicit and its use will make audits for memory safety
  25. * a lot easier.
  26. */
  27. class TriviallyCopyable
  28. {
  29. public:
  30. /**
  31. * Be absolutely sure a TriviallyCopyable object is zeroed using Utils::burn()
  32. *
  33. * @tparam T Automatically inferred type of object
  34. * @param obj Any TriviallyCopyable object
  35. */
  36. template<typename T>
  37. static ZT_ALWAYS_INLINE void memoryBurn(T *obj) noexcept
  38. {
  39. TriviallyCopyable *const tmp = obj;
  40. Utils::burn(tmp,sizeof(T));
  41. }
  42. /**
  43. * Be absolutely sure a TriviallyCopyable object is zeroed using Utils::burn()
  44. *
  45. * @tparam T Automatically inferred type of object
  46. * @param obj Any TriviallyCopyable object
  47. */
  48. template<typename T>
  49. static ZT_ALWAYS_INLINE void memoryBurn(T &obj) noexcept
  50. {
  51. TriviallyCopyable *const tmp = &obj;
  52. Utils::burn(tmp,sizeof(T));
  53. }
  54. /**
  55. * Zero a TriviallyCopyable object
  56. *
  57. * @tparam T Automatically inferred type of object
  58. * @param obj Any TriviallyCopyable object
  59. */
  60. template<typename T>
  61. static ZT_ALWAYS_INLINE void memoryZero(T *obj) noexcept
  62. {
  63. TriviallyCopyable *const tmp = obj;
  64. memset(tmp,0,sizeof(T));
  65. }
  66. /**
  67. * Zero a TriviallyCopyable object
  68. *
  69. * @tparam T Automatically inferred type of object
  70. * @param obj Any TriviallyCopyable object
  71. */
  72. template<typename T>
  73. static ZT_ALWAYS_INLINE void memoryZero(T &obj) noexcept
  74. {
  75. TriviallyCopyable *const tmp = &obj;
  76. memset(tmp,0,sizeof(T));
  77. }
  78. /**
  79. * Copy any memory over a TriviallyCopyable object
  80. *
  81. * @tparam T Automatically inferred type of destination
  82. * @param dest Any TriviallyCopyable object
  83. * @param src Source memory of same size or less than sizeof(dest)
  84. */
  85. template<typename T>
  86. static ZT_ALWAYS_INLINE void memoryCopyUnsafe(T *dest,const void *src) noexcept
  87. {
  88. TriviallyCopyable *const tmp = dest;
  89. memcpy(tmp,src,sizeof(T));
  90. }
  91. /**
  92. * Copy any memory over a TriviallyCopyable object
  93. *
  94. * @tparam T Automatically inferred type of destination
  95. * @param dest Any TriviallyCopyable object
  96. * @param src Source memory of same size or less than sizeof(dest)
  97. */
  98. template<typename T>
  99. static ZT_ALWAYS_INLINE void memoryCopyUnsafe(T &dest,const void *src) noexcept
  100. {
  101. TriviallyCopyable *const tmp = &dest;
  102. memcpy(tmp,src,sizeof(T));
  103. }
  104. /**
  105. * Copy a TriviallyCopyable object
  106. *
  107. * @tparam T Automatically inferred type of destination
  108. * @param dest Destination TriviallyCopyable object
  109. * @param src Source TriviallyCopyable object
  110. */
  111. template<typename T>
  112. static ZT_ALWAYS_INLINE void memoryCopy(T *dest,const T *src) noexcept
  113. {
  114. TriviallyCopyable *const tmp = dest;
  115. memcpy(tmp,src,sizeof(T));
  116. }
  117. /**
  118. * Copy a TriviallyCopyable object
  119. *
  120. * @tparam T Automatically inferred type of destination
  121. * @param dest Destination TriviallyCopyable object
  122. * @param src Source TriviallyCopyable object
  123. */
  124. template<typename T>
  125. static ZT_ALWAYS_INLINE void memoryCopy(T *dest,const T &src) noexcept
  126. {
  127. TriviallyCopyable *const tmp = dest;
  128. memcpy(tmp,&src,sizeof(T));
  129. }
  130. /**
  131. * Copy a TriviallyCopyable object
  132. *
  133. * @tparam T Automatically inferred type of destination
  134. * @param dest Destination TriviallyCopyable object
  135. * @param src Source TriviallyCopyable object
  136. */
  137. template<typename T>
  138. static ZT_ALWAYS_INLINE void memoryCopy(T &dest,const T *src) noexcept
  139. {
  140. TriviallyCopyable *const tmp = &dest;
  141. memcpy(tmp,src,sizeof(T));
  142. }
  143. /**
  144. * Copy a TriviallyCopyable object
  145. *
  146. * @tparam T Automatically inferred type of destination
  147. * @param dest Destination TriviallyCopyable object
  148. * @param src Source TriviallyCopyable object
  149. */
  150. template<typename T>
  151. static ZT_ALWAYS_INLINE void memoryCopy(T &dest,const T &src) noexcept
  152. {
  153. TriviallyCopyable *const tmp = &dest;
  154. memcpy(tmp,&src,sizeof(T));
  155. }
  156. };
  157. } // namespace ZeroTier
  158. #endif