diff --git a/docs/combininglock.md b/docs/combininglock.md index b951b7ae8..6aba2a41c 100644 --- a/docs/combininglock.md +++ b/docs/combininglock.md @@ -222,7 +222,7 @@ We can now provide our new version of the `with` function that uses the combinin template inline void with(CombiningLock& lock, F&& f) { - CombiningLockNodeTempl node(std::forward(f)); + CombiningLockNodeTempl node(stl::forward(f)); // **************ACQUIRE************** // Add ourselves to the end of the queue. diff --git a/src/snmalloc/aal/aal.h b/src/snmalloc/aal/aal.h index 626cbf68b..3bbf63404 100644 --- a/src/snmalloc/aal/aal.h +++ b/src/snmalloc/aal/aal.h @@ -16,8 +16,9 @@ # define SNMALLOC_TICK_USE_CLOCK_GETTIME # endif #endif +#include "snmalloc/stl/utility.h" + #include -#include #ifndef SNMALLOC_TICK_USE_CLOCK_GETTIME # include diff --git a/src/snmalloc/backend/backend.h b/src/snmalloc/backend/backend.h index ee170c38f..6a3fa8505 100644 --- a/src/snmalloc/backend/backend.h +++ b/src/snmalloc/backend/backend.h @@ -87,7 +87,7 @@ namespace snmalloc * (remote, sizeclass, slab_metadata) * where slab_metadata, is the second element of the pair return. */ - static std::pair, SlabMetadata*> alloc_chunk( + static stl::Pair, SlabMetadata*> alloc_chunk( LocalState& local_state, size_t size, uintptr_t ras, diff --git a/src/snmalloc/backend/fixedglobalconfig.h b/src/snmalloc/backend/fixedglobalconfig.h index 97318c5aa..5873ce2c5 100644 --- a/src/snmalloc/backend/fixedglobalconfig.h +++ b/src/snmalloc/backend/fixedglobalconfig.h @@ -1,8 +1,11 @@ #pragma once #include "../backend_helpers/backend_helpers.h" +#include "snmalloc/stl/type_traits.h" #include "standard_range.h" +#include + namespace snmalloc { /** diff --git a/src/snmalloc/backend_helpers/pagemap.h b/src/snmalloc/backend_helpers/pagemap.h index 6a0cc5965..a6c909069 100644 --- a/src/snmalloc/backend_helpers/pagemap.h +++ b/src/snmalloc/backend_helpers/pagemap.h @@ -3,8 +3,7 @@ #include "../ds/ds.h" #include "../mem/mem.h" #include "snmalloc/stl/atomic.h" - -#include +#include "snmalloc/stl/utility.h" namespace snmalloc { @@ -115,7 +114,7 @@ namespace snmalloc */ template static SNMALLOC_FAST_PATH - stl::enable_if_t> + stl::enable_if_t> get_bounds() { static_assert(fixed_range_ == fixed_range, "Don't set SFINAE parameter!"); diff --git a/src/snmalloc/ds/combininglock.h b/src/snmalloc/ds/combininglock.h index e6e796dfd..190c90deb 100644 --- a/src/snmalloc/ds/combininglock.h +++ b/src/snmalloc/ds/combininglock.h @@ -256,7 +256,7 @@ namespace snmalloc reinterpret_cast(self); self_templ->f(); }), - f(std::forward(f_)) + f(stl::forward(f_)) { attach_slow(lock); } @@ -290,6 +290,6 @@ namespace snmalloc // There is contention for the lock, we need to take the slow path // with the queue. - CombiningLockNodeTempl node(lock, std::forward(f)); + CombiningLockNodeTempl node(lock, stl::forward(f)); } } // namespace snmalloc diff --git a/src/snmalloc/ds/pagemap.h b/src/snmalloc/ds/pagemap.h index 1d285466f..bf1e8ffaf 100644 --- a/src/snmalloc/ds/pagemap.h +++ b/src/snmalloc/ds/pagemap.h @@ -115,7 +115,7 @@ namespace snmalloc * Returns usable range after pagemap has been allocated */ template - stl::enable_if_t> + stl::enable_if_t> init(void* b, size_t s) { SNMALLOC_ASSERT(!is_initialised()); @@ -250,7 +250,7 @@ namespace snmalloc } template - stl::enable_if_t> get_bounds() + stl::enable_if_t> get_bounds() { SNMALLOC_ASSERT(is_initialised()); diff --git a/src/snmalloc/ds_aal/flaglock.h b/src/snmalloc/ds_aal/flaglock.h index f98879904..e8dee95bd 100644 --- a/src/snmalloc/ds_aal/flaglock.h +++ b/src/snmalloc/ds_aal/flaglock.h @@ -24,7 +24,7 @@ namespace snmalloc constexpr DebugFlagWord() = default; template - constexpr DebugFlagWord(Args&&... args) : flag(std::forward(args)...) + constexpr DebugFlagWord(Args&&... args) : flag(stl::forward(args)...) {} /** @@ -87,7 +87,7 @@ namespace snmalloc template constexpr ReleaseFlagWord(Args&&... args) - : flag(std::forward(args)...) + : flag(stl::forward(args)...) {} void set_owner() {} diff --git a/src/snmalloc/ds_core/helpers.h b/src/snmalloc/ds_core/helpers.h index 753b8edf9..2ff314b13 100644 --- a/src/snmalloc/ds_core/helpers.h +++ b/src/snmalloc/ds_core/helpers.h @@ -3,6 +3,7 @@ #include "bits.h" #include "snmalloc/ds_core/defines.h" #include "snmalloc/stl/type_traits.h" +#include "snmalloc/stl/utility.h" #include #include @@ -357,8 +358,8 @@ namespace snmalloc if (fmt[0] == '{' && fmt[1] == '}') { - append(std::forward(head)); - return append(fmt + 2, std::forward(tail)...); + append(stl::forward(head)); + return append(fmt + 2, stl::forward(tail)...); } append_char(*fmt); @@ -374,7 +375,7 @@ namespace snmalloc SNMALLOC_FAST_PATH MessageBuilder(const char* fmt, Args&&... args) { buffer[SafeLength] = 0; - append(fmt, std::forward(args)...); + append(fmt, stl::forward(args)...); append_char('\0'); } diff --git a/src/snmalloc/ds_core/seqset.h b/src/snmalloc/ds_core/seqset.h index 65b188c31..6046bca70 100644 --- a/src/snmalloc/ds_core/seqset.h +++ b/src/snmalloc/ds_core/seqset.h @@ -3,6 +3,7 @@ #include "../aal/aal.h" #include "../ds_core/ds_core.h" #include "snmalloc/stl/type_traits.h" +#include "snmalloc/stl/utility.h" #include @@ -98,7 +99,7 @@ namespace snmalloc SNMALLOC_FAST_PATH bool is_empty() { static_assert( - stl::is_same_v().node)>, + stl::is_same_v().node)>, "T->node must be Node for T"); head.invariant(); return head.next == &head; diff --git a/src/snmalloc/mem/backend_concept.h b/src/snmalloc/mem/backend_concept.h index ee288d37d..12fd0c017 100644 --- a/src/snmalloc/mem/backend_concept.h +++ b/src/snmalloc/mem/backend_concept.h @@ -4,7 +4,7 @@ # include "../ds/ds.h" # include "sizeclasstable.h" -# include +# include namespace snmalloc { @@ -107,7 +107,7 @@ namespace snmalloc { Backend::alloc_chunk(local_state, size, ras, sizeclass) } -> ConceptSame< - std::pair, typename Backend::SlabMetadata*>>; + stl::Pair, typename Backend::SlabMetadata*>>; } && requires(LocalState* local_state, size_t size) { { diff --git a/src/snmalloc/mem/backend_wrappers.h b/src/snmalloc/mem/backend_wrappers.h index 9e1d3370f..4eb39465f 100644 --- a/src/snmalloc/mem/backend_wrappers.h +++ b/src/snmalloc/mem/backend_wrappers.h @@ -46,8 +46,8 @@ namespace snmalloc constexpr SNMALLOC_FAST_PATH auto has_domesticate(int) -> stl::enable_if_t< stl::is_same_v< decltype(Config::capptr_domesticate( - std::declval(), - std::declval>())), + stl::declval(), + stl::declval>())), CapPtr< T, typename B::template with_wildness< diff --git a/src/snmalloc/mem/freelist.h b/src/snmalloc/mem/freelist.h index 75c96f27a..7e5c9ca65 100644 --- a/src/snmalloc/mem/freelist.h +++ b/src/snmalloc/mem/freelist.h @@ -906,7 +906,7 @@ namespace snmalloc template stl::enable_if_t< !RANDOM_, - std::pair< + stl::Pair< Object::BHeadPtr, Object::BHeadPtr>> extract_segment(const FreeListKey& key, address_t key_tweak) diff --git a/src/snmalloc/mem/localalloc.h b/src/snmalloc/mem/localalloc.h index 2cdefc81c..d30d4149d 100644 --- a/src/snmalloc/mem/localalloc.h +++ b/src/snmalloc/mem/localalloc.h @@ -21,8 +21,9 @@ # include "external_alloc.h" #endif +#include "snmalloc/stl/utility.h" + #include -#include namespace snmalloc { diff --git a/src/snmalloc/mem/metadata.h b/src/snmalloc/mem/metadata.h index 9821dc15d..2cbe630bd 100644 --- a/src/snmalloc/mem/metadata.h +++ b/src/snmalloc/mem/metadata.h @@ -620,7 +620,7 @@ namespace snmalloc * available objects for this slab metadata. */ template - static SNMALLOC_FAST_PATH std::pair + static SNMALLOC_FAST_PATH stl::Pair alloc_free_list( Domesticator domesticate, FrontendSlabMetadata* meta, diff --git a/src/snmalloc/mem/remoteallocator.h b/src/snmalloc/mem/remoteallocator.h index 193d753b6..3e021297d 100644 --- a/src/snmalloc/mem/remoteallocator.h +++ b/src/snmalloc/mem/remoteallocator.h @@ -104,7 +104,7 @@ namespace snmalloc } template - SNMALLOC_FAST_PATH static std::pair + SNMALLOC_FAST_PATH static stl::Pair open_free_ring( capptr::Alloc m, size_t objsize, @@ -242,7 +242,7 @@ namespace snmalloc } template - SNMALLOC_FAST_PATH static std::pair + SNMALLOC_FAST_PATH static stl::Pair open_free_ring( capptr::Alloc m, size_t, diff --git a/src/snmalloc/pal/pal.h b/src/snmalloc/pal/pal.h index a194e7934..6fbb8f347 100644 --- a/src/snmalloc/pal/pal.h +++ b/src/snmalloc/pal/pal.h @@ -168,14 +168,14 @@ namespace snmalloc template [[noreturn]] inline void report_fatal_error(Args... args) { - MessageBuilder msg{std::forward(args)...}; + MessageBuilder msg{stl::forward(args)...}; DefaultPal::error(msg.get_message()); } template inline void message(Args... args) { - MessageBuilder msg{std::forward(args)...}; + MessageBuilder msg{stl::forward(args)...}; MessageBuilder msg_tid{ "{}: {}", debug_get_tid(), msg.get_message()}; DefaultPal::message(msg_tid.get_message()); diff --git a/src/snmalloc/pal/pal_posix.h b/src/snmalloc/pal/pal_posix.h index 0d50f36a0..1b1b3b8ab 100644 --- a/src/snmalloc/pal/pal_posix.h +++ b/src/snmalloc/pal/pal_posix.h @@ -5,6 +5,8 @@ #if defined(SNMALLOC_BACKTRACE_HEADER) # include SNMALLOC_BACKTRACE_HEADER #endif +#include "snmalloc/stl/utility.h" + #include #include #include @@ -15,7 +17,6 @@ #include #include #include -#include #if __has_include() # include diff --git a/src/snmalloc/stl/cxx/utility.h b/src/snmalloc/stl/cxx/utility.h new file mode 100644 index 000000000..0853239b2 --- /dev/null +++ b/src/snmalloc/stl/cxx/utility.h @@ -0,0 +1,13 @@ +#include + +namespace snmalloc +{ + namespace stl + { + using std::declval; + using std::forward; + using std::move; + template + using Pair = std::pair; + } // namespace stl +} // namespace snmalloc diff --git a/src/snmalloc/stl/gnu/type_traits.h b/src/snmalloc/stl/gnu/type_traits.h index 7b2d7691a..5ae96685f 100644 --- a/src/snmalloc/stl/gnu/type_traits.h +++ b/src/snmalloc/stl/gnu/type_traits.h @@ -390,5 +390,21 @@ namespace snmalloc template using add_const_t = const T; +#if __has_builtin(__is_lvalue_reference) + template + inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(T); +#else + template + struct is_lvalue_reference : public false_type + {}; + + template + struct is_lvalue_reference : public true_type + {}; + + template + inline constexpr bool is_lvalue_reference_v = is_lvalue_reference::value; +#endif + } // namespace stl } // namespace snmalloc diff --git a/src/snmalloc/stl/gnu/utility.h b/src/snmalloc/stl/gnu/utility.h new file mode 100644 index 000000000..193613097 --- /dev/null +++ b/src/snmalloc/stl/gnu/utility.h @@ -0,0 +1,68 @@ +#pragma once + +#include "snmalloc/stl/type_traits.h" + +// This is used by clang to provide better analysis of lifetimes. +#if __has_cpp_attribute(_Clang::__lifetimebound__) +# define SNMALLOC_LIFETIMEBOUND [[_Clang::__lifetimebound__]] +#else +# define SNMALLOC_LIFETIMEBOUND +#endif + +namespace snmalloc +{ + namespace stl + { + template + [[nodiscard]] inline constexpr T&& + forward(remove_reference_t& ref) noexcept + { + return static_cast(ref); + } + + template + [[nodiscard]] inline constexpr T&& + forward(SNMALLOC_LIFETIMEBOUND remove_reference_t&& ref) noexcept + { + static_assert( + !is_lvalue_reference_v, "cannot forward an rvalue as an lvalue"); + return static_cast(ref); + } + + template + [[nodiscard]] inline constexpr remove_reference_t&& + move(SNMALLOC_LIFETIMEBOUND T&& ref) noexcept + { +#ifdef __clang__ + using U [[gnu::nodebug]] = remove_reference_t; +#else + using U = remove_reference_t; +#endif + return static_cast(ref); + } + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated" + // First try instantiation with reference types, then fall back to value + // types. Use int to prioritize reference types. + template + T&& declval_impl(int); + template + T declval_impl(long); +#pragma GCC diagnostic pop + + template + constexpr inline decltype(declval_impl(0)) declval() noexcept + { + static_assert( + !is_same_v, "declval cannot be used in an evaluation context"); + } + + template + struct Pair + { + T1 first; + T2 second; + }; + } // namespace stl +} // namespace snmalloc diff --git a/src/snmalloc/stl/utility.h b/src/snmalloc/stl/utility.h new file mode 100644 index 000000000..78e3e6af9 --- /dev/null +++ b/src/snmalloc/stl/utility.h @@ -0,0 +1,9 @@ +#pragma once + +#include "snmalloc/stl/common.h" + +#if SNMALLOC_USE_SELF_VENDORED_STL +# include "snmalloc/stl/gnu/utility.h" +#else +# include "snmalloc/stl/cxx/utility.h" +#endif