Skip to content

Commit

Permalink
Fix Initializer (and thus in particular SharedPtr) for immovable …
Browse files Browse the repository at this point in the history
…types

before C++17. They cannot be returned by value.

To support `SharedPtr` for such types, add `Initializer::ConstructAt()` for
placement `new`. Also add `Initializer::MakeUnique()` for a common application
of placement `new`.

Use `Initializer::{MakeUnique,ConstructAt}()` in `{,Intrusive}SharedPtr` and
`Chain::Block`, so that they support immovable types also before C++17.

This in particular fixes `{Zstd,Lz4}Dictionary` before C++17.

Internal cleanup: do not specialize `Initializer`, choose the appropriate base
class instead. This reduces code duplication.

PiperOrigin-RevId: 669371179
  • Loading branch information
QrczakMK committed Aug 30, 2024
1 parent e5ec82a commit 684f27b
Show file tree
Hide file tree
Showing 9 changed files with 520 additions and 451 deletions.
5 changes: 2 additions & 3 deletions riegeli/base/chain_details.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include <iosfwd>
#include <iterator>
#include <memory>
#include <new>
#include <string>
#include <type_traits>
#include <utility>
Expand Down Expand Up @@ -533,7 +532,7 @@ void Chain::ExternalMethodsFor<T>::RegisterSubobjects(
template <typename T>
inline Chain::RawBlock::RawBlock(Initializer<T> object) {
external_.methods = &ExternalMethodsFor<T>::kMethods;
new (&unchecked_external_object<T>()) T(std::move(object));
std::move(object).ConstructAt(&unchecked_external_object<T>());
const absl::string_view data =
riegeli::ToStringView(unchecked_external_object<T>());
data_ = data.data();
Expand All @@ -547,7 +546,7 @@ inline Chain::RawBlock::RawBlock(Initializer<T> object,
absl::string_view substr)
: data_(substr.data()), size_(substr.size()) {
external_.methods = &ExternalMethodsFor<T>::kMethods;
new (&unchecked_external_object<T>()) T(std::move(object));
std::move(object).ConstructAt(&unchecked_external_object<T>());
RIEGELI_ASSERT(is_external()) << "A RawBlock with allocated_end_ == nullptr "
"should be considered external";
}
Expand Down
2 changes: 1 addition & 1 deletion riegeli/base/external_ref_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ class ExternalRef {
class ObjectForCordWhole {
public:
explicit ObjectForCordWhole(Initializer<T> object)
: ptr_(std::make_unique<T>(std::move(object))) {}
: ptr_(std::move(object).MakeUnique()) {}

ObjectForCordWhole(ObjectForCordWhole&& that) = default;
ObjectForCordWhole& operator=(ObjectForCordWhole&& that) = default;
Expand Down
Loading

0 comments on commit 684f27b

Please sign in to comment.