diff --git a/.gitignore b/.gitignore index 6de7b0de6..8b2e638bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,18 @@ build* .dir-locals.el TAGS third-party/*/ !third-party/cmake/* !third-party/akantu-iterators !third-party/iohelper *~ release .*.swp *.tar.gz *.tgz *.tbz *.tar.bz2 .idea __pycache__ .mailmap +compile_commands.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 53923e9d5..f81656fd3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,82 +1,84 @@ stages: - configure - build - build_tests - test .configure: stage: configure except: - tags variables: BLA_VENDOR: 'OpenBLAS' script: - cmake -E make_directory build - cd build - cmake -DAKANTU_COHESIVE_ELEMENT:BOOL=TRUE -DAKANTU_IMPLICIT:BOOL=TRUE -DAKANTU_PARALLEL:BOOL=TRUE -DAKANTU_STRUCTURAL_MECHANICS:BOOL=TRUE -DAKANTU_HEAT_TRANSFER:BOOL=TRUE -DAKANTU_DAMAGE_NON_LOCAL:BOOL=TRUE -DAKANTU_PYTHON_INTERFACE:BOOL=TRUE -DAKANTU_EXAMPLES:BOOL=TRUE -DAKANTU_BUILD_ALL_EXAMPLES:BOOL=TRUE -DAKANTU_TEST_EXAMPLES:BOOL=FALSE -DAKANTU_TESTS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DAKANTU_RUN_IN_DOCKER:BOOL=TRUE .. .build: stage: build script: - cmake --build build/ .tests: stage: test variables: OMPI_MCA_plm: 'isolated' OMPI_MCA_btl: 'tcp,self' script: - cd build - - ctest -T test --no-compress-output --timeout 120 || true + - ctest -T test --no-compress-output --timeout 300 + after_script: + - cd build - tag=$(head -n 1 < Testing/TAG) - if [ -e Testing/${tag}/Test.xml ]; then - xsltproc -o ./juint.xml ${CI_PROJECT_DIR}/test/ci/ctest2junit.xsl Testing/${tag}/Test.xml; - fi artifacts: when: always paths: - build/juint.xml reports: junit: - build/juint.xml .image_debian_testing_gcc: cache: key: debian_testing_gcc_${CI_COMMIT_SHORT_SHA} paths: - build - third-party/google-test - third-party/pybind11 image: registry.gitlab.com/akantu/akantu:debian-testing configure:debian_testing_gcc: extends: - .configure - .image_debian_testing_gcc build:debian_testing_gcc: extends: - .build - .image_debian_testing_gcc dependencies: - configure:debian_testing_gcc test:debian_testing_gcc: extends: - .tests - .image_debian_testing_gcc dependencies: - build:debian_testing_gcc diff --git a/third-party/akantu_iterators/include/aka_iterators.hh b/third-party/akantu_iterators/include/aka_iterators.hh index e18d836ba..c74fadb48 100644 --- a/third-party/akantu_iterators/include/aka_iterators.hh +++ b/third-party/akantu_iterators/include/aka_iterators.hh @@ -1,691 +1,691 @@ /** * @file aka_iterators.hh * * @author Nicolas Richart * * @date creation: Fri Aug 11 2017 * @date last modification: Mon Jan 29 2018 * * @brief iterator interfaces * * @section LICENSE * * Copyright (©) 2016-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_compatibilty_with_cpp_standard.hh" #include "aka_tuple_tools.hh" /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ #ifndef AKANTU_AKA_ITERATORS_HH #define AKANTU_AKA_ITERATORS_HH #ifndef AKANTU_ITERATORS_NAMESPACE #define AKANTU_ITERATORS_NAMESPACE akantu #endif namespace AKANTU_ITERATORS_NAMESPACE { /* -------------------------------------------------------------------------- */ namespace iterators { namespace details { template struct CopyAssignmentEnabler {}; template <> struct CopyAssignmentEnabler { CopyAssignmentEnabler() = default; CopyAssignmentEnabler(const CopyAssignmentEnabler &) = default; CopyAssignmentEnabler(CopyAssignmentEnabler &&) = default; CopyAssignmentEnabler & operator=(const CopyAssignmentEnabler &) = delete; CopyAssignmentEnabler & operator=(CopyAssignmentEnabler &&) = default; }; template struct MoveAssignmentEnabler {}; template <> struct MoveAssignmentEnabler { MoveAssignmentEnabler() = default; MoveAssignmentEnabler(const MoveAssignmentEnabler &) = default; MoveAssignmentEnabler(MoveAssignmentEnabler &&) = default; MoveAssignmentEnabler & operator=(const MoveAssignmentEnabler &) = delete; MoveAssignmentEnabler & operator=(MoveAssignmentEnabler &&) = default; }; template using is_iterator_category_at_least = std::is_same, cat2>; } // namespace details template class ZipIterator : public details::CopyAssignmentEnabler< aka::conjunction..., std::is_copy_constructible...>::value>, public details::MoveAssignmentEnabler< aka::conjunction..., std::is_move_constructible...>::value> { private: using tuple_t = std::tuple; public: using value_type = std::tuple::value_type...>; using difference_type = std::common_type_t< typename std::iterator_traits::difference_type...>; using pointer = std::tuple::pointer...>; using reference = std::tuple::reference...>; using iterator_category = // std::input_iterator_tag; std::common_type_t< typename std::iterator_traits::iterator_category...>; using nb_iterators = std::tuple_size; public: explicit ZipIterator(tuple_t iterators) : iterators(std::move(iterators)) {} /* ---------------------------------------------------------------------- */ template ::value> * = nullptr> ZipIterator & operator--() { tuple::foreach ([](auto && it) { --it; }, iterators); return *this; } template ::value> * = nullptr> ZipIterator operator--(int) { auto cpy = *this; this->operator--(); return cpy; } // input iterator ++it ZipIterator & operator++() { tuple::foreach ([](auto && it) { ++it; }, iterators); return *this; } // input iterator it++ ZipIterator operator++(int) { auto cpy = *this; this->operator++(); return cpy; } // input iterator it != other_it bool operator!=(const ZipIterator & other) const { // return tuple::are_not_equal(iterators, other.iterators); return std::get<0>(iterators) != std::get<0>(other.iterators); // helps the compiler to optimize } // input iterator dereference *it decltype(auto) operator*() { return tuple::transform([](auto && it) -> decltype(auto) { return *it; }, iterators); } template ::value> * = nullptr> difference_type operator-(const ZipIterator & other) { return std::get<0>(this->iterators) - std::get<0>(other.iterators); } // random iterator it[idx] template ::value> * = nullptr> decltype(auto) operator[](std::size_t idx) { return tuple::transform( [idx](auto && it) -> decltype(auto) { return it[idx]; }, iterators); } // random iterator it + n template ::value> * = nullptr> decltype(auto) operator+(std::size_t n) { return ZipIterator(std::forward(tuple::transform( [n](auto && it) -> decltype(auto) { return it + n; }, iterators))); } // random iterator it - n template ::value> * = nullptr> decltype(auto) operator-(std::size_t n) { return ZipIterator(std::forward(tuple::transform( [n](auto && it) -> decltype(auto) { return it - n; }, iterators))); } template < class iterator_category_ = iterator_category, std::enable_if_t::value> * = nullptr> bool operator==(const ZipIterator & other) const { return not tuple::are_not_equal(iterators, other.iterators); } private: tuple_t iterators; }; } // namespace iterators /* -------------------------------------------------------------------------- */ template decltype(auto) zip_iterator(std::tuple && iterators_tuple) { auto zip = iterators::ZipIterator( std::forward(iterators_tuple)); return zip; } /* -------------------------------------------------------------------------- */ namespace containers { template class ZipContainer { using containers_t = std::tuple; public: explicit ZipContainer(Containers &&... containers) : containers(std::forward(containers)...) {} decltype(auto) begin() const { return zip_iterator( tuple::transform([](auto && c) { return c.begin(); }, std::forward(containers))); } decltype(auto) end() const { return zip_iterator( tuple::transform([](auto && c) { return c.end(); }, std::forward(containers))); } decltype(auto) begin() { return zip_iterator( tuple::transform([](auto && c) { return c.begin(); }, std::forward(containers))); } decltype(auto) end() { return zip_iterator( tuple::transform([](auto && c) { return c.end(); }, std::forward(containers))); } // template , // std::enable_if_t().size())>::value> * = nullptr> // decltype(auto) size() { // return std::forward(std::get<0>(containers)).size(); // } private: containers_t containers; }; template class Range { public: using iterator = Iterator; // ugly trick using const_iterator = Iterator; explicit Range(Iterator && it1, Iterator && it2) : iterators(std::forward(it1), std::forward(it2)) {} decltype(auto) begin() const { return std::get<0>(iterators); } decltype(auto) begin() { return std::get<0>(iterators); } decltype(auto) end() const { return std::get<1>(iterators); } decltype(auto) end() { return std::get<1>(iterators); } private: std::tuple iterators; }; } // namespace containers /* -------------------------------------------------------------------------- */ template decltype(auto) zip(Containers &&... conts) { return containers::ZipContainer( std::forward(conts)...); } template decltype(auto) range(Iterator && it1, Iterator && it2) { return containers::Range(std::forward(it1), std::forward(it2)); } /* -------------------------------------------------------------------------- */ /* Arange */ /* -------------------------------------------------------------------------- */ namespace iterators { template class ArangeIterator { public: using value_type = T; using pointer = T *; using reference = T &; using difference_type = size_t; using iterator_category = std::forward_iterator_tag; constexpr ArangeIterator(T value, T step) : value(value), step(step) {} constexpr ArangeIterator(const ArangeIterator &) = default; constexpr ArangeIterator & operator++() { value += step; return *this; } constexpr T operator*() const { return value; } constexpr bool operator==(const ArangeIterator & other) const { return (value == other.value) and (step == other.step); } constexpr bool operator!=(const ArangeIterator & other) const { return not operator==(other); } private: T value{0}; const T step{1}; }; } // namespace iterators namespace containers { template class ArangeContainer { public: using iterator = iterators::ArangeIterator; using const_iterator = iterators::ArangeIterator; constexpr ArangeContainer(T start, T stop, T step = 1) : start(start), stop((stop - start) % step == 0 ? stop : start + (1 + (stop - start) / step) * step), step(step) {} explicit constexpr ArangeContainer(T stop) : ArangeContainer(0, stop, 1) {} constexpr T operator[](size_t i) { T val = start + i * step; assert(val < stop && "i is out of range"); return val; } constexpr T size() { return (stop - start) / step; } constexpr iterator begin() { return iterator(start, step); } constexpr iterator end() { return iterator(stop, step); } private: const T start{0}, stop{0}, step{1}; }; } // namespace containers template >::value>> inline decltype(auto) arange(const T & stop) { return containers::ArangeContainer(stop); } template >::value>> inline constexpr decltype(auto) arange(const T1 & start, const T2 & stop) { return containers::ArangeContainer>(start, stop); } template >::value>> inline constexpr decltype(auto) arange(const T1 & start, const T2 & stop, const T3 & step) { return containers::ArangeContainer>( start, stop, step); } /* -------------------------------------------------------------------------- */ namespace iterators { template class EnumerateIterator { public: using value_type = std::tuple::value_type>; using difference_type = size_t; using pointer = std::tuple::pointer>; using reference = std::tuple::reference>; using iterator_category = std::input_iterator_tag; public: explicit EnumerateIterator(Iterator && iterator) : iterator(iterator) {} // input iterator ++it EnumerateIterator & operator++() { ++iterator; ++index; return *this; } // input iterator it++ EnumerateIterator operator++(int) { auto cpy = *this; this->operator++(); return cpy; } // input iterator it != other_it bool operator!=(const EnumerateIterator & other) const { return iterator != other.iterator; } // input iterator dereference *it decltype(auto) operator*() { return std::tuple_cat(std::make_tuple(index), *iterator); } bool operator==(const EnumerateIterator & other) const { return not this->operator!=(other); } private: Iterator iterator; size_t index{0}; }; template inline constexpr decltype(auto) enumerate(Iterator && iterator) { return EnumerateIterator(std::forward(iterator)); } } // namespace iterators namespace containers { template class EnumerateContainer { public: explicit EnumerateContainer(Containers &&... containers) : zip_container(std::forward(containers)...) {} decltype(auto) begin() { return iterators::enumerate(zip_container.begin()); } decltype(auto) begin() const { return iterators::enumerate(zip_container.begin()); } decltype(auto) end() { return iterators::enumerate(zip_container.end()); } decltype(auto) end() const { return iterators::enumerate(zip_container.end()); } private: ZipContainer zip_container; }; } // namespace containers template inline constexpr decltype(auto) enumerate(Container &&... container) { return containers::EnumerateContainer( std::forward(container)...); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ namespace iterators { template class transform_adaptor_iterator { public: using value_type = decltype(std::declval()( std::declval())); using difference_type = typename iterator_t::difference_type; using pointer = std::decay_t *; using reference = value_type &; using iterator_category = typename iterator_t::iterator_category; transform_adaptor_iterator(iterator_t it, operator_t op) : it(std::move(it)), op(op) {} transform_adaptor_iterator(const transform_adaptor_iterator &) = default; transform_adaptor_iterator & operator++() { ++it; return *this; } decltype(auto) operator*() { return op(std::forward(*it)); } bool operator==(const transform_adaptor_iterator & other) const { return (it == other.it); } bool operator!=(const transform_adaptor_iterator & other) const { return not operator==(other); } template ::value> * = nullptr> difference_type operator-(const transform_adaptor_iterator & other) { return other - *this; } private: iterator_t it; operator_t op; }; template decltype(auto) make_transform_adaptor_iterator(iterator_t it, operator_t op) { return transform_adaptor_iterator( it, std::forward(op)); } } // namespace iterators namespace containers { template class TransformIteratorAdaptor { public: // using const_iterator = typename // std::decay_t::const_iterator; using iterator = typename // std::decay_t::iterator; TransformIteratorAdaptor(container_t && cont, operator_t op) : cont(std::forward(cont)), op(std::forward(op)) {} decltype(auto) begin() const { return iterators::make_transform_adaptor_iterator(cont.begin(), op); } decltype(auto) begin() { return iterators::make_transform_adaptor_iterator(cont.begin(), op); } decltype(auto) end() const { return iterators::make_transform_adaptor_iterator(cont.end(), op); } decltype(auto) end() { return iterators::make_transform_adaptor_iterator(cont.end(), op); } private: container_t cont; operator_t op; }; } // namespace containers template decltype(auto) make_transform_adaptor(container_t && cont, operator_t && op) { return containers::TransformIteratorAdaptor( std::forward(cont), std::forward(op)); } template decltype(auto) make_keys_adaptor(container_t && cont) { return make_transform_adaptor( std::forward(cont), [](auto && pair) -> const auto & { return pair.first; }); } template decltype(auto) make_values_adaptor(container_t && cont) { return make_transform_adaptor( std::forward(cont), [](auto && pair) -> auto & { return pair.second; }); } template decltype(auto) make_dereference_adaptor(container_t && cont) { return make_transform_adaptor( std::forward(cont), [](auto && value) -> decltype(*value) { return *value; }); } template decltype(auto) make_zip_cat(zip_container_t &&... cont) { return make_transform_adaptor( zip(std::forward(cont)...), [](auto && value) { return tuple::flatten(value); }); } /* -------------------------------------------------------------------------- */ namespace iterators { template class FilterIterator { public: using value_type = decltype(std::declval().operator[](0)); using difference_type = typename filter_iterator_t::difference_type; using pointer = std::decay_t *; using reference = value_type &; using iterator_category = typename filter_iterator_t::iterator_category; FilterIterator(filter_iterator_t filter_it, container_iterator_t container_begin) : filter_it(std::move(filter_it)), container_begin(std::move(container_begin)) {} FilterIterator(const FilterIterator &) = default; FilterIterator & operator++() { ++filter_it; return *this; } decltype(auto) operator*() { auto container_it = this->container_begin + *this->filter_it; return *container_it; } decltype(auto) operator*() const { auto container_it = this->container_begin + *this->filter_it; return *container_it; } bool operator==(const FilterIterator & other) const { return (filter_it == other.filter_it) and (container_begin == other.container_begin); } bool operator!=(const FilterIterator & other) const { return filter_it != other.filter_it; } private: filter_iterator_t filter_it; container_iterator_t container_begin; }; template decltype(auto) make_filter_iterator(filter_iterator_t && filter_it, container_iterator_t && container_begin) { return FilterIterator( std::forward(filter_it), std::forward(container_begin)); } } // namespace iterators namespace containers { template class FilterAdaptor { public: FilterAdaptor(filter_t && filter, Container && container) : filter(std::forward(filter)), container(std::forward(container)) { static_assert( std::is_same::value, - "Containers must all have random iterators"); + "Containers must have random iterators"); } decltype(auto) begin() const { return iterators::make_filter_iterator(filter.begin(), container.begin()); } decltype(auto) begin() { return iterators::make_filter_iterator(filter.begin(), container.begin()); } decltype(auto) end() const { return iterators::make_filter_iterator(filter.end(), container.begin()); } decltype(auto) end() { return iterators::make_filter_iterator(filter.end(), container.begin()); } private: filter_t filter; Container container; }; } // namespace containers template decltype(auto) filter(filter_t && filter, Container && container) { return containers::FilterAdaptor( std::forward(filter), std::forward(container)); } } // namespace AKANTU_ITERATORS_NAMESPACE namespace std { template struct iterator_traits<::AKANTU_ITERATORS_NAMESPACE::iterators::ZipIterator> { using iterator_category = forward_iterator_tag; using value_type = typename ::AKANTU_ITERATORS_NAMESPACE::iterators::ZipIterator::value_type; using difference_type = typename ::AKANTU_ITERATORS_NAMESPACE::iterators::ZipIterator::difference_type; using pointer = typename ::AKANTU_ITERATORS_NAMESPACE::iterators::ZipIterator::pointer; using reference = typename ::AKANTU_ITERATORS_NAMESPACE::iterators::ZipIterator::reference; }; } // namespace std #endif /* AKANTU_AKA_ITERATORS_HH */ diff --git a/third-party/akantu_iterators/test/CMakeLists.txt b/third-party/akantu_iterators/test/CMakeLists.txt index f6887166b..2bfaba215 100644 --- a/third-party/akantu_iterators/test/CMakeLists.txt +++ b/third-party/akantu_iterators/test/CMakeLists.txt @@ -1,19 +1,25 @@ enable_testing() add_executable(test_akantu_iterators test_gtest_main.cc test_tuples.cc test_str.cc test_iterators.cc) target_link_libraries(test_akantu_iterators PRIVATE akantu_iterators GTest::GTest) target_compile_definitions(test_akantu_iterators PRIVATE -DAKANTU_ITERATORS_NAMESPACE=aka) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(test_akantu_iterators PRIVATE -Wall -Wextra -pedantic -Weffc++) endif() if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "5.2") OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(test_akantu_iterators PRIVATE -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-omit-frame-pointer) target_link_options(test_akantu_iterators PRIVATE -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-omit-frame-pointer) endif() +if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "5.2") OR + CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_options(test_iterators PRIVATE -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-omit-frame-pointer) + target_link_options(test_iterators PRIVATE -fsanitize=address -fsanitize=leak -fsanitize=undefined -fno-omit-frame-pointer) +endif() + include(GoogleTest) gtest_discover_tests(test_akantu_iterators)