From f82ed7b744b25e069b314a89033a527208972182 Mon Sep 17 00:00:00 2001 From: owent Date: Wed, 27 May 2026 15:06:23 +0800 Subject: [PATCH] Fixes N5014 warning --- include/memory/allocator_traits.h | 483 ++++++++++-------------------- test/case/wal_object_test.cpp | 44 ++- 2 files changed, 177 insertions(+), 350 deletions(-) diff --git a/include/memory/allocator_traits.h b/include/memory/allocator_traits.h index abdda95e..ce20ddac 100644 --- a/include/memory/allocator_traits.h +++ b/include/memory/allocator_traits.h @@ -2,47 +2,36 @@ // // Licenses under the MIT License // -// @note This is a helper class for user to implement a standard allocator and allocator_traits more easily. +// @note These helpers make it easier to implement standard-compatible allocators. // @example // ```cpp // template > -// struct custom_allocator : public ::std::allocator { -// T* allocate(::std::size_t n) { /* ... */ }; -// void deallocate(T* p, ::std::size_t n) { /* ... */ }; -// template -// struct rebind { -// /* Recursive rebind backend allocator(traditional way) */ -// using __rebind_backend_type_other = -// typename ::std::allocator_traits::template rebind_alloc; -// using other = allocator; -// }; -// }; +// struct custom_allocator +// : public ::atfw::util::memory::allocator_adapter { +// using base_type = ::atfw::util::memory::allocator_adapter; +// using pointer = typename base_type::pointer; +// using size_type = typename base_type::size_type; // -// /* Just use codes below to support standard allocator_traits for custom_allocator */ -// namespace std { -// template -// struct allocator_traits> -// : public ::atfw::util::memory::allocator_traits> { -// template -// using rebind_alloc = custom_allocator::template rebind_alloc>; +// using base_type::base_type; // -// template -// using rebind_traits = allocator_traits>; +// pointer allocate(size_type n) { /* custom logic */ return base_type::allocate(n); } +// void deallocate(pointer p, size_type n) { /* custom logic */ base_type::deallocate(p, n); } // }; -// } // namespace std +// +// using custom_allocator_traits = ::std::allocator_traits>; // ``` +// @note Never specialize ::std::allocator_traits for user allocators. Standard library templates are not extension +// points; put customization on the allocator type itself and let the standard traits primary template detect it. #pragma once #include #include -#include +#include -#include #include +#include #include // STL declare allocator's callbacks as constexpr since C++20, we keep the same behavior for compatibility @@ -60,9 +49,7 @@ # pragma warning(disable : 4996) # endif #elif defined(__GNUC__) && !defined(__clang__) && !defined(__apple_build_version__) -# if (__GNUC__ * 100 + __GNUC_MINOR__ * 10) >= 460 -# pragma GCC diagnostic push -# endif +# pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wdeprecated" #elif defined(__clang__) || defined(__apple_build_version__) # pragma clang diagnostic push @@ -71,358 +58,206 @@ ATFRAMEWORK_UTILS_NAMESPACE_BEGIN namespace memory { -// NOLINTBEGIN(bugprone-macro-parentheses) - -// __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE is used to bind allocator's nested type to allocator_traits -// It will try to use allocator's nested type first, if not exists, it will use default type according to ISO instead. -// @see https://en.cppreference.com/w/cpp/memory/allocator_traits -#if ((defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)) -// Not all compilers support detected_or for template template_args now -# if 0 && (defined(__cpp_template_template_args) && __cpp_template_template_args) -# define __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE(TEST_CLASS, NESTED_TYPE, TYPE_ALIAS, DEFAULT_TYPE) \ - private: \ - template \ - using __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE_##NESTED_TYPE = typename TEST_CLASS::NESTED_TYPE; \ - \ - public: \ - using TYPE_ALIAS = \ - __nested_type_detected_or_t -# else -# if defined(__cpp_concepts) && __cpp_concepts -# define __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE(TEST_CLASS, NESTED_TYPE, TYPE_ALIAS, DEFAULT_TYPE) \ - private: \ - template \ - struct __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE_##NESTED_TYPE { \ - using type = DefaultType; \ - using value_t = ::std::false_type; \ - }; \ - template \ - requires requires { typename TemplateType::NESTED_TYPE; } \ - struct __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE_##NESTED_TYPE { \ - using type = typename TemplateType::NESTED_TYPE; \ - using value_t = ::std::true_type; \ - }; \ - \ - public: \ - using TYPE_ALIAS = \ - typename __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE_##NESTED_TYPE::type - -# else -# define __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE(TEST_CLASS, NESTED_TYPE, TYPE_ALIAS, DEFAULT_TYPE) \ - private: \ - template \ - struct __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE_##NESTED_TYPE { \ - using type = DefaultType; \ - using value_t = ::std::false_type; \ - }; \ - template \ - struct __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE_##NESTED_TYPE< \ - DefaultType, TemplateType, ::std::void_t> { \ - using type = typename TemplateType::NESTED_TYPE; \ - using value_t = ::std::true_type; \ - }; \ - \ - public: \ - using TYPE_ALIAS = \ - typename __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE_##NESTED_TYPE::type -# endif -# endif -#else -# define __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE(TEST_CLASS, NESTED_TYPE, TYPE_ALIAS, DEFAULT_TYPE) \ - private: \ - template \ - static typename __TCNT::NESTED_TYPE __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE_##NESTED_TYPE##_helper( \ - __TCNT*); \ - static DEFAULT_TYPE __util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE_##NESTED_TYPE##_helper(...); \ - \ - public: \ - using TYPE_ALIAS = decltype(__util_memory_allocator_traits_ALLOCATOR_NESTED_TYPE_##NESTED_TYPE##_helper( \ - static_cast(nullptr))) -#endif +template +class __util_memory_allocator_adapter_is_always_equal { + template + static typename AllocatorOther::is_always_equal _S_test(int); -// NOLINTEND(bugprone-macro-parentheses) - -// Inject std::allocator_traits for util_memory_allocator_traits::allocator -template -class __util_memory_allocator_traits_allocator_rebind_detect_other { - template - static UTIL_CONFIG_CONSTEXPR bool _util_memory_allocator_traits_chk( - typename AllocatorTarget::template rebind::other*) { - return true; - } - - template - static UTIL_CONFIG_CONSTEXPR bool _util_memory_allocator_traits_chk(...) { - return false; - } + template + static typename ::std::is_empty::type _S_test(...); public: - static UTIL_CONFIG_CONSTEXPR const bool __value = - _util_memory_allocator_traits_chk(nullptr); + using type = decltype(_S_test(0)); }; -#if !((defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)) -template -UTIL_CONFIG_CONSTEXPR const bool __util_memory_allocator_traits_allocator_rebind_detect_other::__value; -#endif +template +class __util_memory_allocator_adapter_backend_equal { + template + static auto _S_check(int) + -> decltype(::std::declval() == ::std::declval(), + ::std::true_type()); -template ::__value> -struct __util_memory_allocator_traits_allocator_allocator_rebind; + template + static ::std::false_type _S_check(...); -template -struct __util_memory_allocator_traits_allocator_allocator_rebind { - using __rebind_type_other = typename Allocator::template rebind; - using type = typename __rebind_type_other::other; -}; + using has_equal = decltype(_S_check(0)); -template