diff options
Diffstat (limited to 'absl/strings/cord.h')
-rw-r--r-- | absl/strings/cord.h | 57 |
1 files changed, 6 insertions, 51 deletions
diff --git a/absl/strings/cord.h b/absl/strings/cord.h index 8580d803..a0db2797 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h @@ -71,7 +71,6 @@ #include <type_traits> #include "absl/base/internal/endian.h" -#include "absl/base/internal/invoke.h" #include "absl/base/internal/per_thread_tls.h" #include "absl/base/macros.h" #include "absl/base/port.h" @@ -173,10 +172,6 @@ class Cord { // // * be move constructible // * support `void operator()(absl::string_view) const` or `void operator()` - // * not have alignment requirement greater than what is guaranteed by - // `::operator new`. This alignment is dictated by - // `alignof(std::max_align_t)` (pre-C++17 code) or - // `__STDCPP_DEFAULT_NEW_ALIGNMENT__` (C++17 code). // // Example: // @@ -842,47 +837,15 @@ inline void SmallMemmove(char* dst, const char* src, size_t n, } } -struct ExternalRepReleaserPair { - CordRep* rep; - void* releaser_address; -}; - -// Allocates a new external `CordRep` and returns a pointer to it and a pointer -// to `releaser_size` bytes where the desired releaser can be constructed. +// Does non-template-specific `CordRepExternal` initialization. // Expects `data` to be non-empty. -ExternalRepReleaserPair NewExternalWithUninitializedReleaser( - absl::string_view data, ExternalReleaserInvoker invoker, - size_t releaser_size); - -struct Rank1 {}; -struct Rank0 : Rank1 {}; - -template <typename Releaser, typename = ::absl::base_internal::invoke_result_t< - Releaser, absl::string_view>> -void InvokeReleaser(Rank0, Releaser&& releaser, absl::string_view data) { - ::absl::base_internal::invoke(std::forward<Releaser>(releaser), data); -} - -template <typename Releaser, - typename = ::absl::base_internal::invoke_result_t<Releaser>> -void InvokeReleaser(Rank1, Releaser&& releaser, absl::string_view) { - ::absl::base_internal::invoke(std::forward<Releaser>(releaser)); -} +void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep); // Creates a new `CordRep` that owns `data` and `releaser` and returns a pointer // to it, or `nullptr` if `data` was empty. template <typename Releaser> // NOLINTNEXTLINE - suppress clang-tidy raw pointer return. CordRep* NewExternalRep(absl::string_view data, Releaser&& releaser) { - static_assert( -#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) - alignof(Releaser) <= __STDCPP_DEFAULT_NEW_ALIGNMENT__, -#else - alignof(Releaser) <= alignof(max_align_t), -#endif - "Releasers with alignment requirement greater than what is returned by " - "default `::operator new()` are not supported."); - using ReleaserType = absl::decay_t<Releaser>; if (data.empty()) { // Never create empty external nodes. @@ -891,18 +854,10 @@ CordRep* NewExternalRep(absl::string_view data, Releaser&& releaser) { return nullptr; } - auto releaser_invoker = [](void* type_erased_releaser, absl::string_view d) { - auto* my_releaser = static_cast<ReleaserType*>(type_erased_releaser); - InvokeReleaser(Rank0{}, std::move(*my_releaser), d); - my_releaser->~ReleaserType(); - return sizeof(Releaser); - }; - - ExternalRepReleaserPair external = NewExternalWithUninitializedReleaser( - data, releaser_invoker, sizeof(releaser)); - ::new (external.releaser_address) - ReleaserType(std::forward<Releaser>(releaser)); - return external.rep; + CordRepExternal* rep = new CordRepExternalImpl<ReleaserType>( + std::forward<Releaser>(releaser), 0); + InitializeCordRepExternal(data, rep); + return rep; } // Overload for function reference types that dispatches using a function |