summaryrefslogtreecommitdiff
path: root/absl/strings/cord.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/cord.h')
-rw-r--r--absl/strings/cord.h57
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