Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct data_block
- {
- unsigned char data[sizeof(T)];
- reference_count_type reference_count; // does this make sense?
- weak_count_type weak_count;
- [[nodiscard]] inline bool is_empty() const noexcept
- {
- return reference_count == 0 && weak_count == 0;
- }
- void clear_object() noexcept
- {
- reference_count = 0;
- weak_count = 0;
- }
- template <class... Args>
- [[nodiscard]] static data_block mock_block(const reference_count_type reference_count, const weak_count_type weak_count, Args &&...args)
- {
- data_block blank;
- blank.reference_count = reference_count;
- blank.weak_count = weak_count;
- auto *this_object = reinterpret_cast<T *>(&blank.data);
- new (this_object) T(std::forward<Args>(args)...);
- return blank;
- };
- void destroy_held_object()
- {
- auto *this_object = reinterpret_cast<T *>(&data);
- this_object->~T();
- }
- data_block() : reference_count(0), weak_count(0)
- {
- }
- data_block(const data_block &other)
- {
- // copy constructor (does a deep copy)
- // if other holds an object make a copy inside data_block
- reference_count = other.reference_count;
- weak_count = other.weak_count;
- const auto has_objects = !other.is_empty();
- if (has_objects)
- {
- auto *other_object = reinterpret_cast<const T *>(other.data);
- auto *this_object = reinterpret_cast<T *>(this->data);
- new (this_object) T(*other_object);
- }
- }
- data_block(data_block &&other) noexcept
- {
- move_data_block<false>(std::forward<data_block>(other));
- }
- data_block &operator=(const data_block &other)
- {
- return *this = data_block(other);
- }
- data_block &operator=(data_block &&other) noexcept // move assignment
- {
- move_data_block<true>(other);
- return *this;
- }
- private:
- template <bool check_destination> inline void move_data_block(data_block &&other) noexcept
- {
- auto *other_object = reinterpret_cast<T *>(other.data);
- auto *this_object = reinterpret_cast<T *>(this->data);
- if constexpr (check_destination)
- {
- const auto is_memory_alias = other_object == this_object;
- if (is_memory_alias)
- {
- //nothing to do
- return;
- }
- if (!this->is_empty())
- {
- this_object->~T();
- }
- }
- reference_count = other.reference_count;
- weak_count = other.weak_count;
- const auto has_objects = !other.is_empty();
- if (has_objects)
- {
- // this can also call the copy constructor of T
- new (this_object) T(std::move(*other_object));
- // other object has been "moved from" and should be deleted, or it has been copied but we're dropping it, so also delete it
- other_object->~T();
- other.clear_object();
- }
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement