From 8ddc8accb3213e96cd3fdb56570b6c158342b1a9 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 21 Apr 2005 13:47:43 -0400 Subject: COMP: Added KWSys try-compiles KWSYS_STL_HAS_ALLOCATOR_TEMPLATE and KWSYS_STL_HAS_ALLOCATOR_OBJECTS. Needed for more old-stl support in the hashtable. --- Source/kwsys/CMakeLists.txt | 19 ++-- Source/kwsys/Configure.hxx.in | 8 ++ Source/kwsys/hashtable.hxx.in | 175 ++++++++++++++++++++++++++------- Source/kwsys/kwsysPlatformCxxTests.cxx | 27 +++++ bootstrap | 32 +++++- 5 files changed, 211 insertions(+), 50 deletions(-) diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 2a9c4fa..ad49997 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -200,17 +200,22 @@ ELSE(KWSYS_STL_HAS_ITERATOR_TRAITS) "Checking whether stl has internal __iterator_category" DIRECT) ENDIF(KWSYS_STL_HAS_ITERATOR_CATEGORY) ENDIF(KWSYS_STL_HAS_ITERATOR_TRAITS) -KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE - "Checking whether stl has old non-template allocator" DIRECT) -IF(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE) - SET(KWSYS_STL_HAS_ALLOCATOR_REBIND 0) - SET(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT 0) -ELSE(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE) +KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE + "Checking whether stl has standard template allocator" DIRECT) +IF(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE) + SET(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE 0) KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_REBIND "Checking for rebind member of stl allocator" DIRECT) KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT "Checking for non-standard argument to stl allocator<>::max_size" DIRECT) -ENDIF(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE) +ELSE(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE) + KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE + "Checking whether stl has old non-template allocator" DIRECT) + SET(KWSYS_STL_HAS_ALLOCATOR_REBIND 0) + SET(KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT 0) +ENDIF(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE) +KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_OBJECTS + "Checking whether stl containers support allocator objects." DIRECT) IF(KWSYS_IOS_USE_ANSI) # ANSI streams always have string operators. SET(KWSYS_STL_STRING_HAVE_OSTREAM 1) diff --git a/Source/kwsys/Configure.hxx.in b/Source/kwsys/Configure.hxx.in index b599388..af47f1a 100644 --- a/Source/kwsys/Configure.hxx.in +++ b/Source/kwsys/Configure.hxx.in @@ -108,6 +108,9 @@ /* Whether the stl has __iterator_category. */ #define @KWSYS_NAMESPACE@_STL_HAS___ITERATOR_CATEGORY @KWSYS_STL_HAS___ITERATOR_CATEGORY@ +/* Whether the stl allocator is the standard template. */ +#define @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_TEMPLATE @KWSYS_STL_HAS_ALLOCATOR_TEMPLATE@ + /* Whether the stl allocator is not a template. */ #define @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE @KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE@ @@ -117,6 +120,9 @@ /* Whether the stl allocator has a size argument for max_size. */ #define @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT @KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT@ +/* Whether the stl containers support allocator objects. */ +#define @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS @KWSYS_STL_HAS_ALLOCATOR_OBJECTS@ + /* Whether struct stat has the st_mtim member for high resolution times. */ #define @KWSYS_NAMESPACE@_STAT_HAS_ST_MTIM @KWSYS_STAT_HAS_ST_MTIM@ @@ -151,7 +157,9 @@ # define KWSYS_STL_HAS_ITERATOR_TRAITS @KWSYS_NAMESPACE@_STL_HAS_ITERATOR_TRAITS # define KWSYS_STL_HAS_ITERATOR_CATEGORY @KWSYS_NAMESPACE@_STL_HAS_ITERATOR_CATEGORY # define KWSYS_STL_HAS___ITERATOR_CATEGORY @KWSYS_NAMESPACE@_STL_HAS___ITERATOR_CATEGORY +# define KWSYS_STL_HAS_ALLOCATOR_TEMPLATE @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_TEMPLATE # define KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE +# define KWSYS_STL_HAS_ALLOCATOR_OBJECTS @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS #endif #endif diff --git a/Source/kwsys/hashtable.hxx.in b/Source/kwsys/hashtable.hxx.in index af0ec5f..7761e06 100644 --- a/Source/kwsys/hashtable.hxx.in +++ b/Source/kwsys/hashtable.hxx.in @@ -55,10 +55,20 @@ # pragma warning (disable:4786) #endif -#if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE +#if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_TEMPLATE +# define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::allocator< T > +#elif @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE # define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::allocator #else -# define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::allocator< T > +# define @KWSYS_NAMESPACE@_HASH_DEFAULT_ALLOCATOR(T) @KWSYS_NAMESPACE@_stl::alloc +#endif + +#if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS +# define @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a) _M_buckets(__a) +# define @KWSYS_NAMESPACE@_HASH_BUCKETS_GET_ALLOCATOR(__b) , __b.get_allocator() +#else +# define @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a) _M_buckets() +# define @KWSYS_NAMESPACE@_HASH_BUCKETS_GET_ALLOCATOR(__b) #endif namespace @KWSYS_NAMESPACE@ @@ -68,30 +78,131 @@ namespace @KWSYS_NAMESPACE@ // Define an allocator adaptor for platforms that do not provide an // allocator with the rebind member. #if !@KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_REBIND + +// Utility functions to convert item counts. +inline size_t hash_sizeof(void*) { return sizeof(char); } +inline size_t hash_sizeof(const void*) { return sizeof(char); } +template inline size_t hash_sizeof(TPtr p) { return sizeof(p); } +template +inline TSize hash_allocator_n(POut out, PIn in, TSize n) +{ + return n*(hash_sizeof(out)/hash_sizeof(in) + + (hash_sizeof(out)%hash_sizeof(in)>0)); +} + +// Define an allocation method to use the native allocator with +// the proper signature. The following signatures of the allocate +// method are used on various STL implementations: +// pointer allocate(size_type, const void* hint) +// pointer allocate(size_type) +// static pointer allocate(size_type, const void* hint) +// static pointer allocate(size_type) +// Where pointer might be a real type or void*. +// This set of overloads decodes the signature for a particular STL. +// The extra three int/long arguments will favor certain signatures +// over others in the case that multiple are present to avoid +// ambiguity errors. +template +inline void hash_allocate(TAlloc* a, PIn (TAlloc::*allocate)(TSize, THint), + TSize n_out, const void* hint, POut& out, + int, int, int) +{ + TSize n_in = hash_allocator_n(POut(), PIn(), n_out); + void* vout = (a->*allocate)(n_in, const_cast(hint)); + out = static_cast(vout); +} + +template +inline void hash_allocate(TAlloc* a, PIn (TAlloc::*allocate)(TSize), + TSize n_out, const void*, POut& out, + int, int, long) +{ + TSize n_in = hash_allocator_n(POut(), PIn(), n_out); + void* vout = (a->*allocate)(n_in); + out = static_cast(vout); +} + +template +inline void hash_allocate(void*, PIn (*allocate)(TSize, THint), + TSize n_out, const void* hint, POut& out, + int, long, long) +{ + TSize n_in = hash_allocator_n(POut(), PIn(), n_out); + void* vout = allocate(n_in, const_cast(hint)); + out = static_cast(vout); +} + +template +inline void hash_allocate(void*, PIn (*allocate)(TSize), + TSize n_out, const void*, POut& out, + long, long, long) +{ + TSize n_in = hash_allocator_n(POut(), PIn(), n_out); + void* vout = allocate(n_in); + out = static_cast(vout); +} + +// Define a deallocation method to use the native allocator with +// the proper signature. The following signatures of the deallocate +// method are used on various STL implementations: +// void deallocate(pointer, size_type) +// void deallocate(pointer) +// static void deallocate(pointer, size_type) +// static void deallocate(pointer) +// Where pointer might be a real type or void*. +// This set of overloads decodes the signature for a particular STL. +// The extra three int/long arguments will favor certain signatures +// over others in the case that multiple are present to avoid +// ambiguity errors. +template +inline void hash_deallocate(TAlloc* a, void (TAlloc::*deallocate)(PIn, TSize), + void* p, TSize n, int, int, int) +{ + (a->*deallocate)(static_cast(p), n); +} + +template +inline void hash_deallocate(TAlloc* a, void (TAlloc::*deallocate)(PIn), + void* p, TSize, int, int, long) +{ + (a->*deallocate)(static_cast(p)); +} + +template +inline void hash_deallocate(void*, void (*deallocate)(PIn, TSize), + void* p, TSize n, int, long, long) +{ + deallocate(static_cast(p), n); +} + +template +inline void hash_deallocate(void*, void (*deallocate)(PIn), + void* p, TSize, long, long, long) +{ + deallocate(static_cast(p)); +} + +// Define the comparison operators in terms of a base type to avoid +// needing templated versions. class hash_allocator_base {}; bool operator==(const hash_allocator_base&, const hash_allocator_base&) throw() { return true; } bool operator!=(const hash_allocator_base&, const hash_allocator_base&) throw() { return false; } + +// Define the allocator template. template class hash_allocator: public hash_allocator_base { private: // Store the real allocator privately. typedef Alloc alloc_type; -#if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE - typedef char alloc_value_type; - typedef void* alloc_pointer; -#else - typedef typename alloc_type::value_type alloc_value_type; - typedef typename alloc_type::pointer alloc_pointer; -#endif alloc_type alloc_; public: // Standard allocator interface. - typedef typename alloc_type::size_type size_type; - typedef typename alloc_type::difference_type difference_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; @@ -109,21 +220,15 @@ public: # endif pointer address(reference x) const { return &x; } const_pointer address(const_reference x) const { return &x; } -#if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE typedef void* void_pointer; typedef const void* const_void_pointer; -#else - typedef @KWSYS_NAMESPACE@_stl::allocator::pointer void_pointer; - typedef @KWSYS_NAMESPACE@_stl::allocator::const_pointer const_void_pointer; -#endif pointer allocate(size_type n=1, const_void_pointer hint = 0) { if(n) { - return - static_cast( - static_cast( - alloc_.allocate(n*chunk(), const_cast(hint)))); + pointer p; + hash_allocate(&alloc_, &alloc_type::allocate, n, hint, p, 1, 1, 1); + return p; } else { @@ -134,12 +239,7 @@ public: { if(n) { -#if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_NONTEMPLATE - alloc_.deallocate(static_cast(static_cast(p))); -#else - alloc_.deallocate(static_cast(static_cast(p)), - n*chunk()); -#endif + hash_deallocate(&alloc_, &alloc_type::deallocate, p, n, 1, 1, 1); } } #if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT @@ -150,18 +250,12 @@ public: #else size_type max_size() const throw() { - size_type n = alloc_.max_size() / chunk(); + size_type n = alloc_.max_size() / sizeof(value_type); return n>0? n:1; } #endif void construct(pointer p, const value_type& val) { new (p) value_type(val); } void destroy(pointer p) { (void)p; p->~value_type(); } -private: - // Returns the number of the real allocator's allocation units - // needed to allocate one unit for this allocator. - static size_type chunk() - { return (sizeof(value_type)/sizeof(alloc_value_type)+ - (sizeof(value_type)%sizeof(alloc_value_type)>0)); } }; #endif @@ -334,7 +428,11 @@ public: allocator_type get_allocator() const { return allocator_type(); } private: typedef hash_allocator<_Node, _Alloc> _M_node_allocator_type; +# if @KWSYS_NAMESPACE@_STL_HAS_ALLOCATOR_OBJECTS typedef hash_allocator<_Node*, _Alloc> _M_node_ptr_allocator_type; +# else + typedef _Alloc _M_node_ptr_allocator_type; +# endif typedef @KWSYS_NAMESPACE@_stl::vector<_Node*,_M_node_ptr_allocator_type> _M_buckets_type; #endif @@ -371,7 +469,7 @@ public: _M_hash(__hf), _M_equals(__eql), _M_get_key(__ext), - _M_buckets(__a), + @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a), _M_num_elements(0) { _M_initialize_buckets(__n); @@ -385,7 +483,7 @@ public: _M_hash(__hf), _M_equals(__eql), _M_get_key(_ExtractKey()), - _M_buckets(__a), + @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__a), _M_num_elements(0) { _M_initialize_buckets(__n); @@ -396,7 +494,7 @@ public: _M_hash(__ht._M_hash), _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key), - _M_buckets(__ht.get_allocator()), + @KWSYS_NAMESPACE@_HASH_BUCKETS_INIT(__ht.get_allocator()), _M_num_elements(0) { _M_copy_from(__ht); @@ -1010,8 +1108,9 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All> if (__num_elements_hint > __old_n) { const size_type __n = _M_next_size(__num_elements_hint); if (__n > __old_n) { - _M_buckets_type __tmp(__n, (_Node*)(0), - _M_buckets.get_allocator()); + _M_buckets_type __tmp( + __n, (_Node*)(0) + @KWSYS_NAMESPACE@_HASH_BUCKETS_GET_ALLOCATOR(_M_buckets)); try { for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) { _Node* __first = _M_buckets[__bucket]; diff --git a/Source/kwsys/kwsysPlatformCxxTests.cxx b/Source/kwsys/kwsysPlatformCxxTests.cxx index 8d24867..8a45edd 100644 --- a/Source/kwsys/kwsysPlatformCxxTests.cxx +++ b/Source/kwsys/kwsysPlatformCxxTests.cxx @@ -149,6 +149,20 @@ void f(kwsys_stl::list::iterator x) { kwsys_stl::__iterator_category(x); } int main() { return 0; } #endif +#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_TEMPLATE +#include +template +void f(const Alloc&) +{ + typedef typename Alloc::size_type alloc_size_type; +}; +int main() +{ + f(kwsys_stl::allocator()); + return 0; +} +#endif + #ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE #include void f(kwsys_stl::allocator::size_type const&) {} @@ -182,6 +196,19 @@ int main() } #endif +#ifdef TEST_KWSYS_STL_HAS_ALLOCATOR_OBJECTS +#include +void f(kwsys_stl::vector const& v1) +{ + kwsys_stl::vector(1, 1, v1.get_allocator()); +}; +int main() +{ + f(kwsys_stl::vector()); + return 0; +} +#endif + #ifdef TEST_KWSYS_STAT_HAS_ST_MTIM #include #include diff --git a/bootstrap b/bootstrap index 5289ceb..cb32a26 100755 --- a/bootstrap +++ b/bootstrap @@ -206,9 +206,11 @@ cmake_kwsys_config_replace_string () s/@KWSYS_STL_HAS_ITERATOR_TRAITS@/${KWSYS_STL_HAS_ITERATOR_TRAITS}/g; s/@KWSYS_STL_HAS_ITERATOR_CATEGORY@/${KWSYS_STL_HAS_ITERATOR_CATEGORY}/g; s/@KWSYS_STL_HAS___ITERATOR_CATEGORY@/${KWSYS_STL_HAS___ITERATOR_CATEGORY}/g; + s/@KWSYS_STL_HAS_ALLOCATOR_TEMPLATE@/${KWSYS_STL_HAS_ALLOCATOR_TEMPLATE}/g; s/@KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE@/${KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE}/g; s/@KWSYS_STL_HAS_ALLOCATOR_REBIND@/${KWSYS_STL_HAS_ALLOCATOR_REBIND}/g; s/@KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT@/${KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT}/g; + s/@KWSYS_STL_HAS_ALLOCATOR_OBJECTS@/${KWSYS_STL_HAS_ALLOCATOR_OBJECTS}/g; s/@KWSYS_CXX_HAS_CSTDDEF@/${KWSYS_CXX_HAS_CSTDDEF}/g; s/@KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS@/${KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS}/g; s/@KWSYS_CXX_HAS_MEMBER_TEMPLATES@/${KWSYS_CXX_HAS_MEMBER_TEMPLATES}/g; @@ -725,9 +727,11 @@ KWSYS_STL_STRING_HAVE_NEQ_CHAR=0 KWSYS_STL_HAS_ITERATOR_TRAITS=0 KWSYS_STL_HAS_ITERATOR_CATEGORY=0 KWSYS_STL_HAS___ITERATOR_CATEGORY=0 +KWSYS_STL_HAS_ALLOCATOR_TEMPLATE=0 KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE=0 KWSYS_STL_HAS_ALLOCATOR_REBIND=0 KWSYS_STL_HAS_ALLOCATOR_MAX_SIZE_ARGUMENT=0 +KWSYS_STL_HAS_ALLOCATOR_OBJECTS=0 KWSYS_CXX_HAS_CSTDDEF=0 KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS=0 KWSYS_CXX_HAS_MEMBER_TEMPLATES=0 @@ -836,15 +840,15 @@ if [ "x${KWSYS_STL_HAS_ITERATOR_TRAITS}" = "x0" ]; then fi if cmake_try_run "${cmake_cxx_compiler}" \ - "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \ + "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_TEMPLATE -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \ "${cmake_source_dir}/Source/kwsys/kwsysPlatformCxxTests.cxx" >> cmake_bootstrap.log 2>&1; then - KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE=1 - echo "${cmake_cxx_compiler} has old non-template allocator" + KWSYS_STL_HAS_ALLOCATOR_TEMPLATE=1 + echo "${cmake_cxx_compiler} has standard template allocator" else - echo "${cmake_cxx_compiler} does not have old non-template allocator" + echo "${cmake_cxx_compiler} does not have standard template allocator" fi -if [ "x${KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE}" = "x0" ]; then +if [ "x${KWSYS_STL_HAS_ALLOCATOR_TEMPLATE}" = "x1" ]; then if cmake_try_run "${cmake_cxx_compiler}" \ "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_REBIND -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \ "${cmake_source_dir}/Source/kwsys/kwsysPlatformCxxTests.cxx" >> cmake_bootstrap.log 2>&1; then @@ -862,6 +866,24 @@ if [ "x${KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE}" = "x0" ]; then else echo "${cmake_cxx_compiler} does not have non-standard allocator<>::max_size argument" fi +else + if cmake_try_run "${cmake_cxx_compiler}" \ + "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \ + "${cmake_source_dir}/Source/kwsys/kwsysPlatformCxxTests.cxx" >> cmake_bootstrap.log 2>&1; then + KWSYS_STL_HAS_ALLOCATOR_NONTEMPLATE=1 + echo "${cmake_cxx_compiler} has old non-template allocator" + else + echo "${cmake_cxx_compiler} does not have old non-template allocator" + fi +fi + +if cmake_try_run "${cmake_cxx_compiler}" \ + "${cmake_cxx_flags} -DTEST_KWSYS_STL_HAS_ALLOCATOR_OBJECTS -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD}" \ + "${cmake_source_dir}/Source/kwsys/kwsysPlatformCxxTests.cxx" >> cmake_bootstrap.log 2>&1; then + KWSYS_STL_HAS_ALLOCATOR_OBJECTS=1 + echo "${cmake_cxx_compiler} has stl containers supporting allocator objects" +else + echo "${cmake_cxx_compiler} does not have stl containers supporting allocator objects" fi if cmake_try_run "${cmake_cxx_compiler}" \ -- cgit v0.12