diff --git a/.github/workflows/environment.yaml b/.github/workflows/environment.yaml index a43d545..c33a850 100644 --- a/.github/workflows/environment.yaml +++ b/.github/workflows/environment.yaml @@ -8,7 +8,6 @@ dependencies: - lz4-c - xz - zlib - - boost-cpp>=1.63 - xtensor >=0.24,<0.25 - xtensor-python >=0.26,<0.27 - xsimd >=8,<9 diff --git a/CMakeLists.txt b/CMakeLists.txt index 58f8597..52ab8af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,17 +27,7 @@ message(STATUS "Building z5 v${${PROJECT_NAME}_VERSION}") # C++ Standard ############################## -# check whether we have c++ 17 - -message(STATUS "CXX_FLAGS: ${CMAKE_CXX_FLAGS}") -set(CPP17 "${CMAKE_CXX_FLAGS}" MATCHES "-std=c\\+\\+17" CACHE INTERNAL "") -if (CPP17) - message(STATUS "Using c++ 17") - set(CMAKE_CXX_STANDARD 17) -else() - message(STATUS "Using c++ 14") - set(CMAKE_CXX_STANDARD 14) -endif() +set(CMAKE_CXX_STANDARD 17) # make sure the compiler supports the requested c++ standard set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -53,14 +43,6 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE) -# NOTE whether we need to enable the old ABI depends -# on which ABI boost is compiled with. -# If you get boost linker errors try to enable / disable the old ABI -option(USE_OLD_ABI "Use the old GCC ABI to be compatible with old GLIBC versions" OFF) -if(USE_OLD_ABI) - message(STATUS "Using old GCC ABI") - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) -endif() if(MSVC) add_definitions(/DNOMINMAX) @@ -155,53 +137,11 @@ endif() # find libraries - pthread find_package(Threads) - -############################### -# Boost -############################### - -# If WITH_BOOST_FS is set, we always use the boost filesystem library -# otherwise, we check if we have c++17 support. If so, we use std::filesystem, -# otherwise we fall back to boost filesystem. -if(CPP17) - SET(WITH_BOOST_FS FALSE CACHE BOOL "") -else() - SET(WITH_BOOST_FS TRUE CACHE BOOL "") +# add C++ filesystem +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + SET(FILESYSTEM_LIBRARIES "stdc++fs") endif() -if (MSVC) - SET(BOOST_ROOT "${CMAKE_PREFIX_PATH}/Library") - SET(BOOST_LIBRARYDIR "${CMAKE_PREFIX_PATH}/Library/lib") -else() - SET(BOOST_ROOT "${CMAKE_PREFIX_PATH}") - SET(BOOST_LIBRARYDIR "${CMAKE_PREFIX_PATH}/lib") -endif() -SET(Boost_NO_SYSTEM_PATHS ON) - -if(WITH_BOOST_FS) - message(STATUS "With boost filesystem") - find_package(Boost 1.63.0 COMPONENTS system filesystem REQUIRED) - add_definitions(-DWITH_BOOST_FS) - SET(FILESYSTEM_LIBRARIES "${Boost_FILESYSTEM_LIBRARY};${Boost_SYSTEM_LIBRARY}") -else() - message(STATUS "With std filesystem") - find_package(Boost 1.63.0 REQUIRED) - - # see this issue for discussions about the filesystem lib in CMake - # https://gitlab.kitware.com/cmake/cmake/issues/17834 - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - SET(FILESYSTEM_LIBRARIES "stdc++fs") - endif() - - # on clang, we need to enable libc++experimental, see - # https://stackoverflow.com/a/45332844 - if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - SET(FILESYSTEM_LIBRARIES "c++experimental") - endif() -endif() -include_directories(${Boost_INCLUDE_DIR}) - - ################### # xtensor libraries ################### @@ -318,22 +258,6 @@ if(BUILD_Z5PY) # find pybind11, which is required to build the python bindings # the find package command will find python and set the python variables find_package(pybind11 REQUIRED) - if (CPP17) - message(STATUS "Using c++ 17 for pybind") - if(MSVC) - set(PYBIND11_CPP_STANDARD /std:c++17) - else() - set(PYBIND11_CPP_STANDARD -std=c++17) - endif() - else() - message(STATUS "Using c++ 14 for pybind") - if(MSVC) - set(PYBIND11_CPP_STANDARD /std:c++14) - else() - set(PYBIND11_CPP_STANDARD -std=c++14) - endif() - endif() - # pybind11 does not include numpy, so we must search for it in addition here find_package(NumPy REQUIRED) include_directories(${NUMPY_INCLUDE_DIRS}) diff --git a/include/z5/common.hxx b/include/z5/common.hxx index fefe960..e74466b 100644 --- a/include/z5/common.hxx +++ b/include/z5/common.hxx @@ -1,93 +1,13 @@ #pragma once #include +#include +namespace fs = std::filesystem; + +inline fs::path relativeImpl(const fs::path & from, const fs::path & to){ + return fs::relative(to, from); +} -// helpful summary of compiler versions -// https://blog.kowalczyk.info/article/j/guide-to-predefined-macros-in-c-compilers-gcc-clang-msvc-etc..html - -// include boost::filesystem or std::filesystem header -// and define the namespace fs -#ifdef WITH_BOOST_FS - #ifndef BOOST_FILESYSTEM_NO_DEPRECATED - #define BOOST_FILESYSTEM_NO_DEPRECATED - #endif - #include - #include - namespace fs = boost::filesystem; - - // relative path in boost filesystem behaves unexpectedly, so we use the - // same implementation as below - inline fs::path relativeImpl(const fs::path & from, const fs::path & to) { - fs::path::const_iterator fromIter = from.begin(); - fs::path::const_iterator toIter = to.begin(); - - while (fromIter != from.end() && toIter != to.end() && (*toIter) == (*fromIter)){ - ++toIter; - ++fromIter; - } - - fs::path finalPath; - while (fromIter != from.end()){ - finalPath /= ".."; - ++fromIter; - } - - while (toIter != to.end()){ - finalPath /= *toIter; - ++toIter; - } - - return finalPath; - } -#else - // macos behaves very weird here, I can't get it to build on - // osx < 10.15 right now. For now the workaround is to use boost filesystem ... - // TODO MSVC check ? - #if (defined(__GNUC__) && (__GNUC__ > 7)) || defined(__clang__) || (defined(_MSC_VER) && _MSC_VER > 1900) - #include - namespace fs = std::filesystem; - - // need to be consistent with the other implementations - inline fs::path relativeImpl(const fs::path & from, const fs::path & to){ - return fs::relative(to, from); - } - - #else - #include - namespace fs = std::experimental::filesystem; - - // experimental::filesystem does not have relative yet, so - // we re-implement it following: - // https://stackoverflow.com/questions/10167382/boostfilesystem-get-relative-path/37715252#37715252 - inline fs::path relativeImpl(const fs::path & from, const fs::path & to){ - // Start at the root path and while they are the same then do nothing then when they first - // diverge take the entire from path, swap it with '..' segments, and then append the remainder of the to path. - fs::path::const_iterator fromIter = from.begin(); - fs::path::const_iterator toIter = to.begin(); - - // Loop through both while they are the same to find nearest common directory - while (fromIter != from.end() && toIter != to.end() && (*toIter) == (*fromIter)){ - ++toIter; - ++fromIter; - } - - // Replace from path segments with '..' (from => nearest common directory) - fs::path finalPath; - while (fromIter != from.end()){ - finalPath /= ".."; - ++fromIter; - } - - // Append the remainder of the to path (nearest common directory => to) - while (toIter != to.end()){ - finalPath /= *toIter; - ++toIter; - } - - return finalPath; - } - #endif -#endif namespace z5 { diff --git a/include/z5/factory.hxx b/include/z5/factory.hxx index d32429d..b310335 100644 --- a/include/z5/factory.hxx +++ b/include/z5/factory.hxx @@ -19,12 +19,7 @@ namespace z5 { return; } nlohmann::json j; - - #ifdef WITH_BOOST_FS - fs::ifstream file(path); - #else std::ifstream file(path); - #endif file >> j; file.close(); diff --git a/include/z5/filesystem/attributes.hxx b/include/z5/filesystem/attributes.hxx index 81165f0..cb6329b 100644 --- a/include/z5/filesystem/attributes.hxx +++ b/include/z5/filesystem/attributes.hxx @@ -14,11 +14,7 @@ namespace attrs_detail { if(!fs::exists(path)) { return; } - #ifdef WITH_BOOST_FS - fs::ifstream file(path); - #else std::ifstream file(path); - #endif file >> j; file.close(); } @@ -27,22 +23,14 @@ namespace attrs_detail { nlohmann::json jOut; // if we already have attributes, read them if(fs::exists(path)) { - #ifdef WITH_BOOST_FS - fs::ifstream file(path); - #else std::ifstream file(path); - #endif file >> jOut; file.close(); } for(auto jIt = j.begin(); jIt != j.end(); ++jIt) { jOut[jIt.key()] = jIt.value(); } - #ifdef WITH_BOOST_FS - fs::ofstream file(path); - #else std::ofstream file(path); - #endif file << jOut; file.close(); } @@ -51,11 +39,7 @@ namespace attrs_detail { nlohmann::json jOut; // if we already have attributes, read them if(fs::exists(path)) { - #ifdef WITH_BOOST_FS - fs::ifstream file(path); - #else std::ifstream file(path); - #endif file >> jOut; file.close(); } @@ -63,11 +47,7 @@ namespace attrs_detail { return; } jOut.erase(key); - #ifdef WITH_BOOST_FS - fs::ofstream file(path); - #else std::ofstream file(path); - #endif file << jOut; file.close(); } diff --git a/include/z5/filesystem/dataset.hxx b/include/z5/filesystem/dataset.hxx index 9f43067..c0fc4d2 100644 --- a/include/z5/filesystem/dataset.hxx +++ b/include/z5/filesystem/dataset.hxx @@ -209,22 +209,14 @@ namespace filesystem { private: inline void write(const fs::path & path, const std::vector & buffer) const { - #ifdef WITH_BOOST_FS - fs::ofstream file(path, std::ios::binary); - #else std::ofstream file(path, std::ios::binary); - #endif file.write(&buffer[0], buffer.size()); file.close(); } inline void read(const fs::path & path, std::vector & buffer) const { // open input stream and read the filesize - #ifdef WITH_BOOST_FS - fs::ifstream file(path, std::ios::binary); - #else std::ifstream file(path, std::ios::binary); - #endif file.seekg(0, std::ios::end); const std::size_t file_size = file.tellg(); @@ -256,11 +248,7 @@ namespace filesystem { inline bool read_varlen_from_n5_header(const fs::path & path, std::size_t & chunkSize) const { - #ifdef WITH_BOOST_FS - fs::ifstream file(path, std::ios::binary); - #else std::ifstream file(path, std::ios::binary); - #endif // read the mode uint16_t mode; @@ -291,11 +279,7 @@ namespace filesystem { inline void read_shape_from_n5_header(const fs::path & path, types::ShapeType & chunkShape) const { - #ifdef WITH_BOOST_FS - fs::ifstream file(path, std::ios::binary); - #else std::ifstream file(path, std::ios::binary); - #endif // advance the file by 2 to skip the mode file.seekg(2); diff --git a/include/z5/filesystem/handle.hxx b/include/z5/filesystem/handle.hxx index 0e82ce7..a275eb2 100644 --- a/include/z5/filesystem/handle.hxx +++ b/include/z5/filesystem/handle.hxx @@ -310,7 +310,7 @@ namespace handle { // get z5::filesystem::handle::File from char pointer corresponding // to the file on filesystem inline File getFileHandle(const char * path) { - fs::path path_(std::string(path)); + fs::path path_{std::string(path)}; File ret(path); return ret; } diff --git a/include/z5/filesystem/metadata.hxx b/include/z5/filesystem/metadata.hxx index 49f7f39..8ab076a 100644 --- a/include/z5/filesystem/metadata.hxx +++ b/include/z5/filesystem/metadata.hxx @@ -9,21 +9,13 @@ namespace filesystem { namespace metadata_detail { inline void writeMetadata(const fs::path & path, const nlohmann::json & j) { - #ifdef WITH_BOOST_FS - fs::ofstream file(path); - #else std::ofstream file(path); - #endif file << std::setw(4) << j << std::endl; file.close(); } inline void readMetadata(const fs::path & path, nlohmann::json & j) { - #ifdef WITH_BOOST_FS - fs::ifstream file(path); - #else std::ifstream file(path); - #endif file >> j; file.close(); } diff --git a/include/z5/util/threadpool.hxx b/include/z5/util/threadpool.hxx index 5e22d6e..78ad6f2 100644 --- a/include/z5/util/threadpool.hxx +++ b/include/z5/util/threadpool.hxx @@ -9,10 +9,7 @@ #include #include #include - -#include -#include - +#include /* * Copied and slightly adapted from @@ -353,13 +350,13 @@ inline void parallel_foreach_impl( const std::ptrdiff_t chunkedWorkPerThread = (std::max)(int(workPerThread/3.0f + 0.5f), 1); std::vector > futures; - for( ;iter(0); - auto endIter = boost::counting_iterator(nItems); + std::vector indices(nItems); + std::iota(indices.begin(), indices.end(), 0); + + parallel_foreach(nThreads, indices.begin(), indices.end(), std::forward(f), nItems); - parallel_foreach(nThreads, beginIter, endIter, f, nItems); } @@ -630,11 +633,10 @@ inline void parallel_foreach( std::ptrdiff_t nItems, F && f) { + std::vector indices(nItems); + std::iota(indices.begin(), indices.end(), 0); - auto beginIter = boost::counting_iterator(0); - auto endIter = boost::counting_iterator(nItems); - - parallel_foreach(threadpool, beginIter, endIter, f, nItems); + parallel_foreach(threadpool, indices.begin(), indices.end(), std::forward(f), nItems); } //@} diff --git a/src/python/lib/variant_cast.hxx b/src/python/lib/variant_cast.hxx index f5f9e22..ad4cdee 100644 --- a/src/python/lib/variant_cast.hxx +++ b/src/python/lib/variant_cast.hxx @@ -1,23 +1,12 @@ #include #include -#include +#include // this does not work for MSVC14, as specified here: // see https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html#c-17-library-containers namespace pybind11 { namespace detail { - template - struct type_caster> : variant_caster> {}; - - // Specifies the function used to visit the variant -- `apply_visitor` instead of `visit` - template <> - struct visit_helper { - template - static auto call(Args &&...args) -> decltype(boost::apply_visitor(args...)) { - return boost::apply_visitor(args...); - } - }; - + struct type_caster> : variant_caster> {}; } } diff --git a/src/test/test_metadata.cxx b/src/test/test_metadata.cxx index 8f86e4f..845fe94 100644 --- a/src/test/test_metadata.cxx +++ b/src/test/test_metadata.cxx @@ -28,11 +28,7 @@ namespace z5 { dsZarr.create(); auto mdata = dsZarr.path(); mdata /= ".zarray"; - #ifdef WITH_BOOST_FS - fs::ofstream file(mdata); - #else std::ofstream file(mdata); - #endif file << jZarr; file.close(); @@ -41,11 +37,7 @@ namespace z5 { dsN5.create(); auto mdataN5 = dsN5.path(); mdataN5 /= "attributes.json"; - #ifdef WITH_BOOST_FS - fs::ofstream fileN5(mdataN5); - #else std::ofstream fileN5(mdataN5); - #endif fileN5 << jN5; fileN5.close(); }