diff --git a/cmake/BuildLevelDB.cmake b/cmake/BuildLevelDB.cmake index 2fff806..2b95e18 100644 --- a/cmake/BuildLevelDB.cmake +++ b/cmake/BuildLevelDB.cmake @@ -9,6 +9,20 @@ if(NOT TARGET leveldb_lib) add_subdirectory("${LEVELDB_SOURCE_DIR}" "${LEVELDB_BINARY_DIR}") endif() +# Pin bundled LevelDB to C++17. It only needs C++11 (declared via its own +# target_compile_features) but inherits CMAKE_CXX_STANDARD=20 from the +# top-level project, where some of its atomic-enum syntax +# (std::memory_order::memory_order_relaxed) becomes a hard error. +foreach(_leveldb_target leveldb_lib leveldb_memenv) + if(TARGET ${_leveldb_target}) + set_target_properties(${_leveldb_target} PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS OFF + ) + endif() +endforeach() + if(NOT TARGET build_leveldb) add_custom_target(build_leveldb DEPENDS leveldb_lib leveldb_memenv) endif() diff --git a/src/allocators.h b/src/allocators.h index b416e4d..0795817 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -182,15 +182,17 @@ private: template struct secure_allocator : public std::allocator { - // MSVC8 default copy constructor is broken + // C++20 removed pointer/reference/etc. member typedefs from std::allocator + // and removed the 2-arg allocate(n, hint). Define what we still need + // directly instead of pulling from base. typedef std::allocator base; - typedef typename base::size_type size_type; - typedef typename base::difference_type difference_type; - typedef typename base::pointer pointer; - typedef typename base::const_pointer const_pointer; - typedef typename base::reference reference; - typedef typename base::const_reference const_reference; - typedef typename base::value_type value_type; + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; secure_allocator() throw() {} secure_allocator(const secure_allocator& a) throw() : base(a) {} template @@ -199,10 +201,9 @@ struct secure_allocator : public std::allocator template struct rebind { typedef secure_allocator<_Other> other; }; - T* allocate(std::size_t n, const void *hint = 0) + T* allocate(std::size_t n) { - T *p; - p = std::allocator::allocate(n, hint); + T* p = std::allocator::allocate(n); if (p != NULL) LockedPageManager::instance.LockRange(p, sizeof(T) * n); return p; @@ -226,15 +227,16 @@ struct secure_allocator : public std::allocator template struct zero_after_free_allocator : public std::allocator { - // MSVC8 default copy constructor is broken + // C++20 removed pointer/reference/etc. member typedefs from std::allocator. + // Define what we still need directly instead of pulling from base. typedef std::allocator base; - typedef typename base::size_type size_type; - typedef typename base::difference_type difference_type; - typedef typename base::pointer pointer; - typedef typename base::const_pointer const_pointer; - typedef typename base::reference reference; - typedef typename base::const_reference const_reference; - typedef typename base::value_type value_type; + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; zero_after_free_allocator() throw() {} zero_after_free_allocator(const zero_after_free_allocator& a) throw() : base(a) {} template