Advertisement
Guest User

Untitled

a guest
Mar 4th, 2021
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.40 KB | None | 0 0
  1. struct data_block
  2. {
  3. unsigned char data[sizeof(T)];
  4. reference_count_type reference_count; // does this make sense?
  5. weak_count_type weak_count;
  6. [[nodiscard]] inline bool is_empty() const noexcept
  7. {
  8. return reference_count == 0 && weak_count == 0;
  9. }
  10. void clear_object() noexcept
  11. {
  12. reference_count = 0;
  13. weak_count = 0;
  14. }
  15. template <class... Args>
  16. [[nodiscard]] static data_block mock_block(const reference_count_type reference_count, const weak_count_type weak_count, Args &&...args)
  17. {
  18. data_block blank;
  19. blank.reference_count = reference_count;
  20. blank.weak_count = weak_count;
  21. auto *this_object = reinterpret_cast<T *>(&blank.data);
  22. new (this_object) T(std::forward<Args>(args)...);
  23. return blank;
  24. };
  25.  
  26. void destroy_held_object()
  27. {
  28. auto *this_object = reinterpret_cast<T *>(&data);
  29. this_object->~T();
  30. }
  31.  
  32. data_block() : reference_count(0), weak_count(0)
  33. {
  34. }
  35. data_block(const data_block &other)
  36. {
  37. // copy constructor (does a deep copy)
  38. // if other holds an object make a copy inside data_block
  39. reference_count = other.reference_count;
  40. weak_count = other.weak_count;
  41. const auto has_objects = !other.is_empty();
  42. if (has_objects)
  43. {
  44. auto *other_object = reinterpret_cast<const T *>(other.data);
  45. auto *this_object = reinterpret_cast<T *>(this->data);
  46. new (this_object) T(*other_object);
  47. }
  48. }
  49. data_block(data_block &&other) noexcept
  50. {
  51. move_data_block<false>(std::forward<data_block>(other));
  52. }
  53. data_block &operator=(const data_block &other)
  54. {
  55. return *this = data_block(other);
  56. }
  57. data_block &operator=(data_block &&other) noexcept // move assignment
  58. {
  59. move_data_block<true>(other);
  60. return *this;
  61. }
  62.  
  63. private:
  64. template <bool check_destination> inline void move_data_block(data_block &&other) noexcept
  65. {
  66. auto *other_object = reinterpret_cast<T *>(other.data);
  67. auto *this_object = reinterpret_cast<T *>(this->data);
  68.  
  69. if constexpr (check_destination)
  70. {
  71. const auto is_memory_alias = other_object == this_object;
  72. if (is_memory_alias)
  73. {
  74. //nothing to do
  75. return;
  76. }
  77. if (!this->is_empty())
  78. {
  79. this_object->~T();
  80. }
  81. }
  82. reference_count = other.reference_count;
  83. weak_count = other.weak_count;
  84. const auto has_objects = !other.is_empty();
  85. if (has_objects)
  86. {
  87. // this can also call the copy constructor of T
  88. new (this_object) T(std::move(*other_object));
  89. // other object has been "moved from" and should be deleted, or it has been copied but we're dropping it, so also delete it
  90. other_object->~T();
  91. other.clear_object();
  92. }
  93. }
  94. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement