diff --git a/.github/workflows/libcxx.yml b/.github/workflows/libcxx.yml index 95796753..8dd569b4 100644 --- a/.github/workflows/libcxx.yml +++ b/.github/workflows/libcxx.yml @@ -69,8 +69,6 @@ jobs: - {std: 14, cxx: clang++-10 , bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} - {std: 11, cxx: clang++-10 , bt: Debug , os: ubuntu-18.04, bitlinks: shared64 static32} - {std: 11, cxx: clang++-10 , bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} - - {std: 20, cxx: clang++-6.0, bt: Debug , os: ubuntu-18.04, bitlinks: shared64 static32} - - {std: 20, cxx: clang++-6.0, bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} - {std: 17, cxx: clang++-6.0, bt: Debug , os: ubuntu-18.04, bitlinks: shared64 static32} - {std: 17, cxx: clang++-6.0, bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} - {std: 14, cxx: clang++-6.0, bt: Debug , os: ubuntu-18.04, bitlinks: shared64 static32} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 03cd5246..50d78a50 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -81,12 +81,12 @@ jobs: - name: Download vars.sh uses: actions/download-artifact@v1 with: {name: vars.sh, path: ./} - - name: Install requirements - run: | - sudo -E pip install git-archive-all - name: Install python 3.9 uses: actions/setup-python@v2 with: { python-version: 3.9 } + - name: Install requirements + run: | + sudo -E pip install git-archive-all - name: Create source packages run: | pwd @@ -94,9 +94,9 @@ jobs: source vars.sh echo SRC_TAG=$SRC_TAG echo SRC_VERSION=$SRC_VERSION - mkdir -p assets id=${PROJ_PKG_NAME}${SRC_VERSION} name=${id}-src + mkdir -p assets git-archive-all --prefix $name assets/$name.tgz git-archive-all --prefix $name assets/$name.zip python --version diff --git a/.github/workflows/test_install.yml b/.github/workflows/test_install.yml index 1f202d42..fb9645ac 100644 --- a/.github/workflows/test_install.yml +++ b/.github/workflows/test_install.yml @@ -38,8 +38,8 @@ jobs: include: - {name: find_package/linux , sdir: test/test_install , os: ubuntu-18.04, cxx: g++-10 , gen: "-DCMAKE_CXX_COMPILER=g++-10" , tgt: all , bt: Release, vars: "-Dc4core_DIR=$GITHUB_WORKSPACE/$PDIR/lib/cmake/c4core -DC4CORE_TEST_INSTALL_PACKAGE_MODE=ON", commonvars: } - {name: find_package/linux , sdir: test/test_install , os: ubuntu-18.04, cxx: g++-10 , gen: "-DCMAKE_CXX_COMPILER=g++-10" , tgt: all , bt: Debug , vars: "-Dc4core_DIR=$GITHUB_WORKSPACE/$PDIR/lib/cmake/c4core -DC4CORE_TEST_INSTALL_PACKAGE_MODE=ON", commonvars: } - - {name: find_package/linux/libc++, sdir: test/test_install , os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Release, vars: "-Dc4core_DIR=$GITHUB_WORKSPACE/$PDIR/lib/cmake/c4core -DC4CORE_TEST_INSTALL_PACKAGE_MODE=ON", commonvars: "-DC4CORE_USE_LIBCXX=ON"} - - {name: find_package/linux/libc++, sdir: test/test_install , os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Debug , vars: "-Dc4core_DIR=$GITHUB_WORKSPACE/$PDIR/lib/cmake/c4core -DC4CORE_TEST_INSTALL_PACKAGE_MODE=ON", commonvars: "-DC4CORE_USE_LIBCXX=ON"} + - {name: find_package/linux/libcxx, sdir: test/test_install , os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Release, vars: "-Dc4core_DIR=$GITHUB_WORKSPACE/$PDIR/lib/cmake/c4core -DC4CORE_TEST_INSTALL_PACKAGE_MODE=ON", commonvars: "-DC4CORE_USE_LIBCXX=ON"} + - {name: find_package/linux/libcxx, sdir: test/test_install , os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Debug , vars: "-Dc4core_DIR=$GITHUB_WORKSPACE/$PDIR/lib/cmake/c4core -DC4CORE_TEST_INSTALL_PACKAGE_MODE=ON", commonvars: "-DC4CORE_USE_LIBCXX=ON"} - {name: find_package/macos , sdir: test/test_install , os: macos-11.0 , cxx: xcode , gen: "-G Xcode -DCMAKE_OSX_ARCHITECTURES=x86_64", tgt: ALL_BUILD, bt: Release, vars: "-Dc4core_DIR=$GITHUB_WORKSPACE/$PDIR/lib/cmake/c4core -DC4CORE_TEST_INSTALL_PACKAGE_MODE=ON", commonvars: } - {name: find_package/macos , sdir: test/test_install , os: macos-11.0 , cxx: xcode , gen: "-G Xcode -DCMAKE_OSX_ARCHITECTURES=x86_64", tgt: ALL_BUILD, bt: Debug , vars: "-Dc4core_DIR=$GITHUB_WORKSPACE/$PDIR/lib/cmake/c4core -DC4CORE_TEST_INSTALL_PACKAGE_MODE=ON", commonvars: } - {name: find_package/win , sdir: test/test_install , os: windows-2019, cxx: vs2019 , gen: "-G 'Visual Studio 16 2019' -A x64" , tgt: ALL_BUILD, bt: Release, vars: "-Dc4core_DIR=$GITHUB_WORKSPACE/$PDIR/cmake -DC4CORE_TEST_INSTALL_PACKAGE_MODE=ON", commonvars: } @@ -47,8 +47,8 @@ jobs: # - {name: find_library/linux , sdir: test/test_install , os: ubuntu-18.04, cxx: g++-10 , gen: "-DCMAKE_CXX_COMPILER=g++-10" , tgt: all , bt: Release, vars: "-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/$PDIR -DC4CORE_TEST_INSTALL_PACKAGE_MODE=OFF", commonvars: } - {name: find_library/linux , sdir: test/test_install , os: ubuntu-18.04, cxx: g++-10 , gen: "-DCMAKE_CXX_COMPILER=g++-10" , tgt: all , bt: Debug , vars: "-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/$PDIR -DC4CORE_TEST_INSTALL_PACKAGE_MODE=OFF", commonvars: } - - {name: find_library/linux/libc++, sdir: test/test_install , os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Release, vars: "-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/$PDIR -DC4CORE_TEST_INSTALL_PACKAGE_MODE=OFF", commonvars: "-DC4CORE_USE_LIBCXX=ON"} - - {name: find_library/linux/libc++, sdir: test/test_install , os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Debug , vars: "-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/$PDIR -DC4CORE_TEST_INSTALL_PACKAGE_MODE=OFF", commonvars: "-DC4CORE_USE_LIBCXX=ON"} + - {name: find_library/linux/libcxx, sdir: test/test_install , os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Release, vars: "-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/$PDIR -DC4CORE_TEST_INSTALL_PACKAGE_MODE=OFF", commonvars: "-DC4CORE_USE_LIBCXX=ON"} + - {name: find_library/linux/libcxx, sdir: test/test_install , os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Debug , vars: "-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/$PDIR -DC4CORE_TEST_INSTALL_PACKAGE_MODE=OFF", commonvars: "-DC4CORE_USE_LIBCXX=ON"} - {name: find_library/macos , sdir: test/test_install , os: macos-11.0 , cxx: xcode , gen: "-G Xcode -DCMAKE_OSX_ARCHITECTURES=x86_64", tgt: ALL_BUILD, bt: Release, vars: "-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/$PDIR -DC4CORE_TEST_INSTALL_PACKAGE_MODE=OFF", commonvars: } - {name: find_library/macos , sdir: test/test_install , os: macos-11.0 , cxx: xcode , gen: "-G Xcode -DCMAKE_OSX_ARCHITECTURES=x86_64", tgt: ALL_BUILD, bt: Debug , vars: "-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/$PDIR -DC4CORE_TEST_INSTALL_PACKAGE_MODE=OFF", commonvars: } - {name: find_library/win , sdir: test/test_install , os: windows-2019, cxx: vs2019 , gen: "-G 'Visual Studio 16 2019' -A x64" , tgt: ALL_BUILD, bt: Release, vars: "-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/$PDIR -DC4CORE_TEST_INSTALL_PACKAGE_MODE=OFF", commonvars: } @@ -56,8 +56,8 @@ jobs: # - {name: singleheader/linux , sdir: test/test_singleheader, os: ubuntu-18.04, cxx: g++-10 , gen: "-DCMAKE_CXX_COMPILER=g++-10" , tgt: all , bt: Release, vars: , commonvars: } - {name: singleheader/linux , sdir: test/test_singleheader, os: ubuntu-18.04, cxx: g++-10 , gen: "-DCMAKE_CXX_COMPILER=g++-10" , tgt: all , bt: Debug , vars: , commonvars: } - - {name: singleheader/linux/libc++, sdir: test/test_singleheader, os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Release, vars: , commonvars: "-DC4CORE_USE_LIBCXX=ON"} - - {name: singleheader/linux/libc++, sdir: test/test_singleheader, os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Debug , vars: , commonvars: "-DC4CORE_USE_LIBCXX=ON"} + - {name: singleheader/linux/libcxx, sdir: test/test_singleheader, os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Release, vars: , commonvars: "-DC4CORE_USE_LIBCXX=ON"} + - {name: singleheader/linux/libcxx, sdir: test/test_singleheader, os: ubuntu-18.04, cxx: clang++-9, gen: "-DCMAKE_CXX_COMPILER=clang++-9" , tgt: all , bt: Debug , vars: , commonvars: "-DC4CORE_USE_LIBCXX=ON"} - {name: singleheader/macos , sdir: test/test_singleheader, os: macos-11.0 , cxx: xcode , gen: "-G Xcode -DCMAKE_OSX_ARCHITECTURES=x86_64", tgt: ALL_BUILD, bt: Release, vars: , commonvars: } - {name: singleheader/macos , sdir: test/test_singleheader, os: macos-11.0 , cxx: xcode , gen: "-G Xcode -DCMAKE_OSX_ARCHITECTURES=x86_64", tgt: ALL_BUILD, bt: Debug , vars: , commonvars: } - {name: singleheader/win , sdir: test/test_singleheader, os: windows-2019, cxx: vs2019 , gen: "-G 'Visual Studio 16 2019' -A x64" , tgt: ALL_BUILD, bt: Release, vars: , commonvars: } diff --git a/.gitignore b/.gitignore index fb351bbd..9c258ea3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .clangd/ .cache/ .cquery_cached_index/ +__pycache__/ # Visual Studio files .vs/ diff --git a/changelog/current.md b/changelog/current.md index 4b91af80..db77aaf9 100644 --- a/changelog/current.md +++ b/changelog/current.md @@ -37,6 +37,7 @@ - Change order of headers, notably in `windows_push.hpp` ([PR #47](https://github.com/biojppm/c4core/pull/47)). - In `c4/charconv.hpp`: do not use C4_ASSERT in `to_c_fmt()`, which is `constexpr`. - Fix [#53](https://github.com/biojppm/c4core/issues/53): cmake install targets were missing call to `export()` ([PR #55](https://github.com/biojppm/c4core/pull/55)). +- Fix linking of subprojects with libc++: flags should be forwarded through `CMAKE_***_FLAGS` instead of being set explicitly per-target ([PR #54](https://github.com/biojppm/c4core/pull/54)). ### Thanks diff --git a/cmake b/cmake index 5704607e..9416f297 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 5704607e901f5c8991c141300385d9b4ca9bbaf8 +Subproject commit 9416f297430bc358eea48f8cf65aa0d602029629 diff --git a/src/c4/allocator.hpp b/src/c4/allocator.hpp index 7c2e9b00..d221341c 100644 --- a/src/c4/allocator.hpp +++ b/src/c4/allocator.hpp @@ -5,6 +5,7 @@ #include "c4/ctor_dtor.hpp" #include // std::allocator_traits +#include /** @file allocator.hpp Contains classes to make typeful allocations (note * that memory resources are typeless) */ @@ -69,90 +70,95 @@ class MemResGlobal //----------------------------------------------------------------------------- namespace detail { -template< class MemRes > +template struct _AllocatorUtil; + +template +struct has_no_alloc + : public std::integral_constant::value) + && std::is_constructible::value> {}; + +// std::uses_allocator_v && std::is_constructible +// ie can construct(std::allocator_arg_t, MemoryResource*, Args...) +template +struct has_alloc_arg + : public std::integral_constant::value + && std::is_constructible::value> {}; +// std::uses_allocator && std::is_constructible +// ie, can construct(Args..., MemoryResource*) +template +struct has_alloc + : public std::integral_constant::value + && std::is_constructible::value> {}; + } // namespace detail -template< class MemRes > +template struct detail::_AllocatorUtil : public MemRes { -// utility macros, undefined at the end of the class -/** SFINAE: enable the function with a void return type when a condition is verified */ -#define _c4_void_if(cond) C4_ALWAYS_INLINE typename std::enable_if< cond, void >::type -/** @see http://en.cppreference.com/w/cpp/memory/uses_allocator */ -#define _c4_uses_allocator(U) std::uses_allocator< U, MemoryResource* >::value -/** @see http://en.cppreference.com/w/cpp/types/is_constructible */ -#define _c4_is_constructible(...) std::is_constructible< __VA_ARGS__ >::value - -public: - using MemRes::MemRes; -public: - /** for construct: * @see http://en.cppreference.com/w/cpp/experimental/polymorphic_allocator/construct */ // 1. types with no allocators - template< class U, class... Args > - _c4_void_if( ! _c4_uses_allocator(U) && _c4_is_constructible(U, Args...) ) - construct(U* ptr, Args&&... args) + template + C4_ALWAYS_INLINE typename std::enable_if::value, void>::type + construct(U *ptr, Args &&...args) { - c4::construct(ptr, std::forward< Args >(args)...); + c4::construct(ptr, std::forward(args)...); } - template< class U, class I, class... Args > - _c4_void_if( ! _c4_uses_allocator(U) && _c4_is_constructible(U, Args...) ) + template + C4_ALWAYS_INLINE typename std::enable_if::value, void>::type construct_n(U* ptr, I n, Args&&... args) { - c4::construct_n(ptr, n, std::forward< Args >(args)...); + c4::construct_n(ptr, n, std::forward(args)...); } // 2. types using allocators (ie, containers) // 2.1. can construct(std::allocator_arg_t, MemoryResource*, Args...) - template< class U, class... Args > - _c4_void_if(_c4_uses_allocator(U) && _c4_is_constructible(U, std::allocator_arg_t, MemoryResource*, Args...)) + template + C4_ALWAYS_INLINE typename std::enable_if::value, void>::type construct(U* ptr, Args&&... args) { - c4::construct(ptr, std::allocator_arg, this->resource(), std::forward< Args >(args)...); + c4::construct(ptr, std::allocator_arg, this->resource(), std::forward(args)...); } - template< class U, class I, class... Args > - _c4_void_if(_c4_uses_allocator(U) && _c4_is_constructible(U, std::allocator_arg_t, MemoryResource*, Args...)) + template + C4_ALWAYS_INLINE typename std::enable_if::value, void>::type construct_n(U* ptr, I n, Args&&... args) { - c4::construct_n(ptr, n, std::allocator_arg, this->resource(), std::forward< Args >(args)...); + c4::construct_n(ptr, n, std::allocator_arg, this->resource(), std::forward(args)...); } // 2.2. can construct(Args..., MemoryResource*) - template< class U, class... Args > - _c4_void_if(_c4_uses_allocator(U) && _c4_is_constructible(U, Args..., MemoryResource*)) + template + C4_ALWAYS_INLINE typename std::enable_if::value, void>::type construct(U* ptr, Args&&... args) { - c4::construct(ptr, std::forward< Args >(args)..., this->resource()); + c4::construct(ptr, std::forward(args)..., this->resource()); } - template< class U, class I, class... Args > - _c4_void_if(_c4_uses_allocator(U) && _c4_is_constructible(U, Args..., MemoryResource*)) + template + C4_ALWAYS_INLINE typename std::enable_if::value, void>::type construct_n(U* ptr, I n, Args&&... args) { - c4::construct_n(ptr, n, std::forward< Args >(args)..., this->resource()); + c4::construct_n(ptr, n, std::forward(args)..., this->resource()); } - template< class U > + template static C4_ALWAYS_INLINE void destroy(U* ptr) { c4::destroy(ptr); } - template< class U, class I > + template static C4_ALWAYS_INLINE void destroy_n(U* ptr, I n) { c4::destroy_n(ptr, n); } - -#undef _c4_void_if -#undef _c4_is_constructible -#undef _c4_uses_allocator - }; @@ -164,12 +170,12 @@ struct detail::_AllocatorUtil : public MemRes * @param T * @param MemResProvider * @ingroup allocators */ -template< class T, class MemResProvider=MemResGlobal > -class Allocator : public detail::_AllocatorUtil< MemResProvider > +template +class Allocator : public detail::_AllocatorUtil { public: - using impl_type = detail::_AllocatorUtil< MemResProvider >; + using impl_type = detail::_AllocatorUtil; using value_type = T; using pointer = T*; @@ -182,12 +188,12 @@ class Allocator : public detail::_AllocatorUtil< MemResProvider > public: - template< class U, class MRProv > + template bool operator== (Allocator const& that) const { return this->resource() == that.resource(); } - template< class U, class MRProv > + template bool operator!= (Allocator const& that) const { return this->resource() != that.resource(); @@ -195,13 +201,13 @@ class Allocator : public detail::_AllocatorUtil< MemResProvider > public: - template< class U, class MRProv > friend class Allocator; - template< class U > + template friend class Allocator; + template struct rebind { - using other = Allocator< U, MemResProvider >; + using other = Allocator; }; - template< class U > + template typename rebind::other rebound() { return typename rebind::other(*this); @@ -212,7 +218,7 @@ class Allocator : public detail::_AllocatorUtil< MemResProvider > using impl_type::impl_type; Allocator() : impl_type() {} // VS demands this - template< class U > Allocator(Allocator const& that) : impl_type(that.resource()) {} + template Allocator(Allocator const& that) : impl_type(that.resource()) {} Allocator(Allocator const&) = default; Allocator(Allocator &&) = default; @@ -229,14 +235,14 @@ class Allocator : public detail::_AllocatorUtil< MemResProvider > C4_ASSERT(this->resource() != nullptr); C4_ASSERT(alignment >= alignof(T)); void* vmem = this->resource()->allocate(detail::size_for(num_objs), alignment); - T* mem = static_cast< T* >(vmem); + T* mem = static_cast(vmem); return mem; } void deallocate(T * ptr, size_t num_objs, size_t alignment=alignof(T)) { C4_ASSERT(this->resource() != nullptr); - C4_ASSERT(alignment >= alignof(T)); + C4_ASSERT(alignment>= alignof(T)); this->resource()->deallocate(ptr, detail::size_for(num_objs), alignment); } @@ -245,7 +251,7 @@ class Allocator : public detail::_AllocatorUtil< MemResProvider > C4_ASSERT(this->resource() != nullptr); C4_ASSERT(alignment >= alignof(T)); void* vmem = this->resource()->reallocate(ptr, detail::size_for(oldnum), detail::size_for(newnum), alignment); - T* mem = static_cast< T* >(vmem); + T* mem = static_cast(vmem); return mem; } @@ -256,12 +262,12 @@ class Allocator : public detail::_AllocatorUtil< MemResProvider > //----------------------------------------------------------------------------- /** @ingroup allocators */ -template< class T, size_t N=16, size_t Alignment=alignof(T), class MemResProvider=MemResGlobal > -class SmallAllocator : public detail::_AllocatorUtil< MemResProvider > +template +class SmallAllocator : public detail::_AllocatorUtil { static_assert(Alignment >= alignof(T), "invalid alignment"); - using impl_type = detail::_AllocatorUtil< MemResProvider >; + using impl_type = detail::_AllocatorUtil; alignas(Alignment) char m_arr[N * sizeof(T)]; size_t m_num{0}; @@ -277,12 +283,12 @@ class SmallAllocator : public detail::_AllocatorUtil< MemResProvider > using difference_type = std::ptrdiff_t; using propagate_on_container_move_assigment = std::true_type; - template< class U > + template bool operator== (SmallAllocator const&) const { return false; } - template< class U > + template bool operator!= (SmallAllocator const&) const { return true; @@ -290,13 +296,13 @@ class SmallAllocator : public detail::_AllocatorUtil< MemResProvider > public: - template< class U, size_t, size_t, class > friend class SmallAllocator; - template< class U > + template friend class SmallAllocator; + template struct rebind { - using other = SmallAllocator< U, N, alignof(U), MemResProvider >; + using other = SmallAllocator; }; - template< class U > + template typename rebind::other rebound() { return typename rebind::other(*this); @@ -307,7 +313,7 @@ class SmallAllocator : public detail::_AllocatorUtil< MemResProvider > using impl_type::impl_type; SmallAllocator() : impl_type() {} // VS demands this - template< class U, size_t N2, size_t A2, class MP2 > + template SmallAllocator(SmallAllocator const& that) : impl_type(that.resource()) { C4_ASSERT(that.m_num == 0); @@ -337,7 +343,7 @@ class SmallAllocator : public detail::_AllocatorUtil< MemResProvider > vmem = this->resource()->allocate(num_objs * sizeof(T), alignment); } m_num += num_objs; - T *mem = static_cast< T* >(vmem); + T *mem = static_cast(vmem); return mem; } @@ -372,7 +378,7 @@ class SmallAllocator : public detail::_AllocatorUtil< MemResProvider > return m_arr; } void* vmem = this->resource()->reallocate(ptr, oldnum * sizeof(T), newnum * sizeof(T), alignment); - T* mem = static_cast< T* >(vmem); + T* mem = static_cast(vmem); return mem; } @@ -384,15 +390,15 @@ class SmallAllocator : public detail::_AllocatorUtil< MemResProvider > /** An allocator making use of the global memory resource. * @ingroup allocators */ -template< class T > using allocator = Allocator< T, MemResGlobal >; +template using allocator = Allocator; /** An allocator with a per-instance memory resource * @ingroup allocators */ -template< class T > using allocator_mr = Allocator< T, MemRes >; +template using allocator_mr = Allocator; /** @ingroup allocators */ -template< class T, size_t N=16, size_t Alignment=alignof(T) > using small_allocator = SmallAllocator< T, N, Alignment, MemResGlobal >; +template using small_allocator = SmallAllocator; /** @ingroup allocators */ -template< class T, size_t N=16, size_t Alignment=alignof(T) > using small_allocator_mr = SmallAllocator< T, N, Alignment, MemRes >; +template using small_allocator_mr = SmallAllocator; } // namespace c4 diff --git a/src/c4/memory_resource.hpp b/src/c4/memory_resource.hpp index 78024817..0818f587 100644 --- a/src/c4/memory_resource.hpp +++ b/src/c4/memory_resource.hpp @@ -57,12 +57,12 @@ void* arealloc(void* ptr, size_t oldsz, size_t newsz, size_t alignment); /** Function pointer type for aligned allocation * @see set_aalloc() * @ingroup raw_memory_alloc */ -using aalloc_pfn = void* (*)(size_t size, size_t alignment); +using aalloc_pfn = void* (*)(size_t size, size_t alignment); /** Function pointer type for aligned deallocation * @see set_afree() * @ingroup raw_memory_alloc */ -using afree_pfn = void (*)(void *ptr); +using afree_pfn = void (*)(void *ptr); /** Function pointer type for aligned reallocation * @see set_arealloc() @@ -76,13 +76,13 @@ using arealloc_pfn = void* (*)(void *ptr, size_t oldsz, size_t newsz, size_t ali * @see aalloc() * @see get_aalloc() * @ingroup raw_memory_alloc */ -void set_aalloc (aalloc_pfn fn); +void set_aalloc(aalloc_pfn fn); /** Set the global aligned deallocation function. * @see afree() * @see get_afree() * @ingroup raw_memory_alloc */ -void set_afree (afree_pfn fn); +void set_afree(afree_pfn fn); /** Set the global aligned reallocation function. * @see arealloc() @@ -94,12 +94,12 @@ void set_arealloc(arealloc_pfn fn); /** Get the global aligned reallocation function. * @see arealloc() * @ingroup raw_memory_alloc */ -aalloc_pfn get_aalloc(); +aalloc_pfn get_aalloc(); /** Get the global aligned deallocation function. * @see afree() * @ingroup raw_memory_alloc */ -afree_pfn get_afree(); +afree_pfn get_afree(); /** Get the global aligned reallocation function. * @see arealloc() @@ -133,7 +133,7 @@ struct MemoryResource return mem; } - void deallocate(void* ptr, size_t sz, size_t alignment = alignof(max_align_t)) + void deallocate(void* ptr, size_t sz, size_t alignment=alignof(max_align_t)) { this->do_deallocate(ptr, sz, alignment); } diff --git a/src/c4/std/string_fwd.hpp b/src/c4/std/string_fwd.hpp index e957132c..7e1ca3b6 100644 --- a/src/c4/std/string_fwd.hpp +++ b/src/c4/std/string_fwd.hpp @@ -13,10 +13,9 @@ // forward declarations for std::string #if defined(__GLIBCXX__) || defined(__GLIBCPP__) -// use the fwd header in stdlibc++ -#include +#include // use the fwd header in glibcxx #elif defined(_LIBCPP_VERSION) || defined(__APPLE_CC__) -#include +#include // use the fwd header in stdlibc++ #elif defined(_MSC_VER) //! @todo is there a fwd header in msvc? namespace std { diff --git a/src/c4/std/vector_fwd.hpp b/src/c4/std/vector_fwd.hpp index f61995a5..18a5c4c5 100644 --- a/src/c4/std/vector_fwd.hpp +++ b/src/c4/std/vector_fwd.hpp @@ -16,11 +16,13 @@ namespace std { template class allocator; #if defined(__EMSCRIPTEN__) inline namespace __2 { +template class vector; +} // namespace __2 #else inline namespace __1 { -#endif template class vector; } // namespace __1 +#endif } // namespace std #else #error "unknown standard library" diff --git a/tbump.toml b/tbump.toml index 12e4ec8b..d2ac895c 100644 --- a/tbump.toml +++ b/tbump.toml @@ -25,6 +25,13 @@ tag_template = "v{new_version}" # tbump.toml location. [[file]] src = "CMakeLists.txt" +search = "c4_project\\(VERSION {current_version}" +[[file]] +src = "test/test_install/CMakeLists.txt" +search = "c4_project\\(VERSION {current_version}" +[[file]] +src = "test/test_singleheader/CMakeLists.txt" +search = "c4_project\\(VERSION {current_version}" # You can specify a list of commands to # run after the files have been patched diff --git a/test/test_singleheader/CMakeLists.txt b/test/test_singleheader/CMakeLists.txt index df5796bf..af49bbd8 100644 --- a/test/test_singleheader/CMakeLists.txt +++ b/test/test_singleheader/CMakeLists.txt @@ -7,28 +7,31 @@ include(../../cmake/c4Project.cmake) c4_project(VERSION 0.1.7 AUTHOR "Joao Paulo Magalhaes ") -set(c4coredir "${CMAKE_CURRENT_LIST_DIR}/../..") -set(singleheaderdir "${c4coredir}/src_singleheader") -set(singleheader "${singleheaderdir}/c4/c4core_all.hpp") -if(NOT (EXISTS "${singleheader}")) - # try generating a header - set(cmd python "${c4coredir}/tools/amalgamate.py" "${singleheader}") - message(STATUS "single header not found, attempting to generate... ${cmd}") - execute_process(COMMAND ${cmd} - COMMMAND_ECHO STDOUT - RESULT_VARIABLE status) - if((NOT (status EQUAL "0")) OR NOT (EXISTS "${singleheader}")) - message(FATAL_ERROR "cannot find or generate single header for c4core: ${singleheader}") - endif() - message(STATUS "single header successfully generated: ${singleheader}") -endif() +# amalgamate c4core to get the single header +function(amalgamate_c4core header_dir header_file) + set(c4coredir "${CMAKE_CURRENT_LIST_DIR}/../..") + set(singleheaderdir "${c4coredir}/src_singleheader") + set(singleheader "${singleheaderdir}/c4/c4core_all.hpp") + set(amscript "${c4coredir}/tools/amalgamate.py") + file(GLOB_RECURSE srcfiles + LIST_DIRECTORIES FALSE + CONFIGURE_DEPENDS + "${c4coredir}/src") + add_custom_command(OUTPUT "${singleheader}" + COMMAND python "${amscript}" "${singleheader}" + COMMENT "python ${amscript} ${singleheader}" + DEPENDS ${srcfiles} "${amscript}" "${c4coredir}/cmake/amalgamate_utils.py") + set(${header_dir} "${singleheaderdir}" PARENT_SCOPE) + set(${header_file} "${singleheader}" PARENT_SCOPE) +endfunction() +amalgamate_c4core(HEADER_DIR HEADER_FILE) c4_add_library(c4core INC_DIRS - $ $ - SOURCE_ROOT ${singleheaderdir} + $ $ + SOURCE_ROOT ${HEADER_DIR} SOURCES - ${singleheader} + ${HEADER_FILE} ${CMAKE_CURRENT_LIST_DIR}/libc4core_singleheader.cpp) target_compile_definitions(c4core PUBLIC -DC4CORE_SINGLE_HEADER) diff --git a/tools/amalgamate.py b/tools/amalgamate.py index 332ec410..4242586d 100644 --- a/tools/amalgamate.py +++ b/tools/amalgamate.py @@ -1,27 +1,33 @@ import re -import os from os.path import abspath, dirname import sys import subprocess projdir = abspath(dirname(dirname(__file__))) sys.path.insert(0, f"{projdir}/cmake") -from amalgamate_utils import * +import amalgamate_utils as am -fastfloatdir = f"{projdir}/src/c4/ext/fast_float" -subprocess.run([ - sys.executable, - f"{fastfloatdir}/script/amalgamate.py", - "--license", "MIT", - "--output", f"{fastfloatdir}/../fast_float_all.h" -], cwd=fastfloatdir).check_returncode() +def amalgamate_fastfloat(): + fastfloatdir = f"{projdir}/src/c4/ext/fast_float" + subprocess.run([ + sys.executable, + f"{fastfloatdir}/script/amalgamate.py", + "--license", "MIT", + "--output", f"{fastfloatdir}/../fast_float_all.h" + ], cwd=fastfloatdir).check_returncode() -repo = "https://github.com/biojppm/c4core" -defmacro = "C4CORE_SINGLE_HDR_DEFINE_NOW" -headers = [ - cmttext(f""" + +def amalgamate_c4core(filename: str, + with_stl: bool=True, + with_fastfloat: bool=True): + if with_fastfloat: + amalgamate_fastfloat() + repo = "https://github.com/biojppm/c4core" + defmacro = "C4CORE_SINGLE_HDR_DEFINE_NOW" + srcblocks = [ + am.cmttext(f""" c4core - C++ utilities {repo} @@ -31,83 +37,90 @@ INSTRUCTIONS: - Include at will in any header of your project - - In one (and only one) of your project source files, #define - {defmacro} and then include this header. This will enable the - function and class definitions in the header file. + - In one (and only one) of your project source files, + #define {defmacro} and then include this header. + This will enable the function and class definitions in + the header file. """), - cmtfile("LICENSE.txt"), - "src/c4/export.hpp", - "src/c4/preprocessor.hpp", - "src/c4/platform.hpp", - "src/c4/cpu.hpp", - "src/c4/compiler.hpp", - "src/c4/language.hpp", - "src/c4/types.hpp", - "src/c4/config.hpp", - hdrfile("src/c4/ext/debugbreak/debugbreak.h", "c4/ext/debugbreak/debugbreak.h", "DEBUG_BREAK_H"), - "src/c4/error.hpp", - "src/c4/memory_util.hpp", - "src/c4/memory_resource.hpp", - "src/c4/ctor_dtor.hpp", - "src/c4/allocator.hpp", - "src/c4/char_traits.hpp", - "src/c4/hash.hpp", - "src/c4/szconv.hpp", - "src/c4/blob.hpp", - "src/c4/substr_fwd.hpp", - "src/c4/substr.hpp", - injfile("src/c4/ext/fast_float_all.h", "c4/ext/fast_float_all.h"), - "src/c4/ext/fast_float.hpp", - "src/c4/std/vector_fwd.hpp", - "src/c4/std/string_fwd.hpp", - "src/c4/std/std_fwd.hpp", - "src/c4/charconv.hpp", - "src/c4/format.hpp", - "src/c4/enum.hpp", - "src/c4/bitmask.hpp", - "src/c4/span.hpp", - "src/c4/type_name.hpp", - "src/c4/base64.hpp", - ignfile("src/c4/std/std.hpp"), # this is an umbrella include - "src/c4/std/string.hpp", - "src/c4/std/vector.hpp", - "src/c4/std/tuple.hpp", - "src/c4/time.hpp", - "src/c4/ext/rng/rng.hpp", - "src/c4/ext/sg14/inplace_function.h", - ignfile("src/c4/common.hpp"), - ignfile("src/c4/c4_push.hpp"), - ignfile("src/c4/c4_pop.hpp"), - ignfile("src/c4/restrict.hpp"), - ignfile("src/c4/unrestrict.hpp"), - "src/c4/language.cpp", - "src/c4/format.cpp", - "src/c4/memory_util.cpp", - "src/c4/char_traits.cpp", - "src/c4/memory_resource.cpp", - "src/c4/base64.cpp", - injcode("#define C4_WINDOWS_POP_HPP_"), - "src/c4/windows_push.hpp", - "src/c4/windows.hpp", - "src/c4/windows_pop.hpp", # do NOT include this before windows.hpp - "src/c4/time.cpp", - "src/c4/error.cpp", -] + am.cmtfile("LICENSE.txt"), + "src/c4/export.hpp", + "src/c4/preprocessor.hpp", + "src/c4/platform.hpp", + "src/c4/cpu.hpp", + "src/c4/compiler.hpp", + "src/c4/language.hpp", + "src/c4/types.hpp", + "src/c4/config.hpp", + am.hdrfile("src/c4/ext/debugbreak/debugbreak.h", "c4/ext/debugbreak/debugbreak.h", "DEBUG_BREAK_H"), + "src/c4/error.hpp", + "src/c4/memory_util.hpp", + "src/c4/memory_resource.hpp", + "src/c4/ctor_dtor.hpp", + "src/c4/allocator.hpp", + "src/c4/char_traits.hpp", + "src/c4/hash.hpp", + "src/c4/szconv.hpp", + "src/c4/blob.hpp", + "src/c4/substr_fwd.hpp", + "src/c4/substr.hpp", + am.onlyif(with_fastfloat, am.injfile("src/c4/ext/fast_float_all.h", "c4/ext/fast_float_all.h")), + am.onlyif(with_fastfloat, "src/c4/ext/fast_float.hpp"), + "src/c4/std/vector_fwd.hpp", + "src/c4/std/string_fwd.hpp", + "src/c4/std/std_fwd.hpp", + "src/c4/charconv.hpp", + "src/c4/format.hpp", + "src/c4/enum.hpp", + "src/c4/bitmask.hpp", + "src/c4/span.hpp", + "src/c4/type_name.hpp", + "src/c4/base64.hpp", + am.onlyif(with_stl, am.ignfile("src/c4/std/std.hpp")), # this is an umbrella include + am.onlyif(with_stl, "src/c4/std/string.hpp"), + am.onlyif(with_stl, "src/c4/std/vector.hpp"), + am.onlyif(with_stl, "src/c4/std/tuple.hpp"), + "src/c4/time.hpp", + "src/c4/ext/rng/rng.hpp", + "src/c4/ext/sg14/inplace_function.h", + am.ignfile("src/c4/common.hpp"), + am.ignfile("src/c4/c4_push.hpp"), + am.ignfile("src/c4/c4_pop.hpp"), + am.ignfile("src/c4/restrict.hpp"), + am.ignfile("src/c4/unrestrict.hpp"), + "src/c4/language.cpp", + "src/c4/format.cpp", + "src/c4/memory_util.cpp", + "src/c4/char_traits.cpp", + "src/c4/memory_resource.cpp", + "src/c4/base64.cpp", + am.injcode("#define C4_WINDOWS_POP_HPP_"), + "src/c4/windows_push.hpp", + "src/c4/windows.hpp", + "src/c4/windows_pop.hpp", # do NOT include this before windows.hpp + "src/c4/time.cpp", + "src/c4/error.cpp", + ] + result = am.catfiles(srcblocks, + projdir, + # comment out lines with these patterns: + include_regexes=[ + re.compile(r'^\s*#\s*include "(c4/.*)".*$'), + re.compile(r'^\s*#\s*include <(c4/.*)>.*$'), + ], + definition_macro=defmacro, + repo=repo, + result_incguard="_C4CORE_SINGLE_HEADER_AMALGAMATED_HPP_") + result_with_only_first_includes = am.include_only_first(result) + am.file_put_contents(filename, result_with_only_first_includes) + -result = catfiles(headers, - projdir, - # comment out lines with these patterns: - include_regexes=[ - re.compile(r'^\s*#\s*include "(c4/.*)".*$'), - re.compile(r'^\s*#\s*include <(c4/.*)>.*$'), - ], - definition_macro=defmacro, - repo=repo, - result_incguard="_C4CORE_SINGLE_HEADER_AMALGAMATED_HPP_") +def mkparser(): + return am.mkparser(fastfloat=(True, "enable fastfloat library"), + stl=(True, "enable stl interop")) -result_with_only_first_includes = include_only_first(result) -output_name = sys.argv[1] # FIXME -os.makedirs(os.path.dirname(output_name), exist_ok=True) -with open(output_name, "w") as output: - output.write(result_with_only_first_includes) +if __name__ == "__main__": + args = mkparser().parse_args() + amalgamate_c4core(filename=args.output, + with_fastfloat=args.fastfloat, + with_stl=args.stl)