diff --git a/include/aka_compatibilty_with_cpp_standard.hh b/include/aka_compatibilty_with_cpp_standard.hh index b139159a6..40125f798 100644 --- a/include/aka_compatibilty_with_cpp_standard.hh +++ b/include/aka_compatibilty_with_cpp_standard.hh @@ -1,186 +1,186 @@ /** * @file aka_compatibilty_with_cpp_standard.hh * * @author Nicolas Richart * * @date creation: Fri Jun 18 2010 * @date last modification: Wed Jan 10 2018 * * @brief The content of this file is taken from the possible implementations * on * http://en.cppreference.com * * @section LICENSE * * Copyright (©) 2010-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-iterators 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. + * akantu-iterators 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 . + * along with akantu-iterators. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_static_if.hh" /* -------------------------------------------------------------------------- */ +#include #include #include #include -#include /* -------------------------------------------------------------------------- */ #ifndef AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH #define AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH namespace aka { /* -------------------------------------------------------------------------- */ // Part taken from C++14 #if __cplusplus < 201402L template using enable_if_t = typename enable_if::type; #else template using enable_if_t = std::enable_if_t; #endif /* -------------------------------------------------------------------------- */ // Part taken from C++17 #if __cplusplus < 201703L /* -------------------------------------------------------------------------- */ // bool_constant template using bool_constant = std::integral_constant; namespace { -template constexpr bool bool_constant_v = bool_constant::value; + template constexpr bool bool_constant_v = bool_constant::value; } /* -------------------------------------------------------------------------- */ // conjunction template struct conjunction : std::true_type {}; template struct conjunction : B1 {}; template struct conjunction : std::conditional_t, B1> {}; /* -------------------------------------------------------------------------- */ // disjunction template struct disjunction : std::false_type {}; template struct disjunction : B1 {}; template struct disjunction : std::conditional_t> {}; /* -------------------------------------------------------------------------- */ // negations template struct negation : bool_constant {}; /* -------------------------------------------------------------------------- */ // invoke namespace detail { -template struct is_reference_wrapper : std::false_type {}; -template -struct is_reference_wrapper> : std::true_type {}; - -template -decltype(auto) INVOKE(Type T::*f, T1 &&t1, Args &&... args) { - static_if(std::is_member_function_pointer{}) - .then_([&](auto &&f) { - static_if(std::is_base_of>{}) - .then_([&](auto &&f) { - return (std::forward(t1).*f)(std::forward(args)...); - }) - .elseif(is_reference_wrapper>{})([&](auto &&f) { - return (t1.get().*f)(std::forward(args)...); - }) - .else_([&](auto &&f) { - return ((*std::forward(t1)).*f)(std::forward(args)...); - })(std::forward(f)); - }) - .else_([&](auto &&f) { - static_assert(std::is_member_object_pointer::value, - "f is not a member object"); - static_assert(sizeof...(args) == 0, "f takes arguments"); - static_if(std::is_base_of>{}) - .then_([&](auto &&f) { return std::forward(t1).*f; }) - .elseif(std::is_base_of>{})( - [&](auto &&f) { return t1.get().*f; }) - .else_([&](auto &&f) { return (*std::forward(t1)).*f; })( - std::forward(f)); - })(std::forward(f)); -} + template struct is_reference_wrapper : std::false_type {}; + template + struct is_reference_wrapper> : std::true_type {}; + + template + decltype(auto) INVOKE(Type T::*f, T1 && t1, Args &&... args) { + static_if(std::is_member_function_pointer{}) + .then_([&](auto && f) { + static_if(std::is_base_of>{}) + .then_([&](auto && f) { + return (std::forward(t1).*f)(std::forward(args)...); + }) + .elseif(is_reference_wrapper>{})([&](auto && f) { + return (t1.get().*f)(std::forward(args)...); + }) + .else_([&](auto && f) { + return ((*std::forward(t1)).* + f)(std::forward(args)...); + })(std::forward(f)); + }) + .else_([&](auto && f) { + static_assert(std::is_member_object_pointer::value, + "f is not a member object"); + static_assert(sizeof...(args) == 0, "f takes arguments"); + static_if(std::is_base_of>{}) + .then_([&](auto && f) { return std::forward(t1).*f; }) + .elseif(std::is_base_of>{})( + [&](auto && f) { return t1.get().*f; }) + .else_([&](auto && f) { return (*std::forward(t1)).*f; })( + std::forward(f)); + })(std::forward(f)); + } -template -decltype(auto) INVOKE(F &&f, Args &&... args) { - return std::forward(f)(std::forward(args)...); -} + template + decltype(auto) INVOKE(F && f, Args &&... args) { + return std::forward(f)(std::forward(args)...); + } } // namespace detail template -decltype(auto) invoke(F &&f, Args &&... args) { +decltype(auto) invoke(F && f, Args &&... args) { return detail::INVOKE(std::forward(f), std::forward(args)...); } /* -------------------------------------------------------------------------- */ // apply namespace detail { template constexpr decltype(auto) apply_impl(F && f, Tuple && t, std::index_sequence /*unused*/) { return invoke(std::forward(f), std::get(std::forward(t))...); } } // namespace detail /* -------------------------------------------------------------------------- */ template -constexpr decltype(auto) apply(F &&f, Tuple &&t) { +constexpr decltype(auto) apply(F && f, Tuple && t) { return detail::apply_impl( std::forward(f), std::forward(t), std::make_index_sequence>::value>{}); } /* -------------------------------------------------------------------------- */ // count_if template typename std::iterator_traits::difference_type count_if(InputIt first, InputIt last, UnaryPredicate p) { typename std::iterator_traits::difference_type ret = 0; for (; first != last; ++first) { if (p(*first)) { ret++; } } return ret; } #else template using bool_constant = std::bool_constant; template using bool_constant_v = std::bool_constant_v; template using conjunction = std::conjunction; template using disjunction = std::disjunction; template using negation = std::negation; using invoke = std::invoke; using apply = std::apply; using count_if = std::count_if; #endif - template using is_iterator_category_at_least = - std::is_same, cat2>; + std::is_same, cat2>; } // namespace aka #endif /* AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH */ diff --git a/include/aka_iterators.hh b/include/aka_iterators.hh index b66fecd35..f843b32b0 100644 --- a/include/aka_iterators.hh +++ b/include/aka_iterators.hh @@ -1,37 +1,37 @@ /** * @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-iterators 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. + * akantu-iterators 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 . + * along with akantu-iterators. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "iterators/aka_arange_iterator.hh" #include "iterators/aka_enumerate_iterator.hh" #include "iterators/aka_filter_iterator.hh" #include "iterators/aka_transform_iterator.hh" #include "iterators/aka_zip_iterator.hh" /* -------------------------------------------------------------------------- */ diff --git a/include/aka_tuple_tools.hh b/include/aka_tuple_tools.hh index 44d017f33..8f0f14b38 100644 --- a/include/aka_tuple_tools.hh +++ b/include/aka_tuple_tools.hh @@ -1,336 +1,338 @@ /** * @file aka_tuple_tools.hh * * @author Nicolas Richart * * @date creation: Fri Aug 11 2017 * @date last modification: Mon Jan 29 2018 * * @brief iterator interfaces * * @section LICENSE * * Copyright 2019 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_str_hash.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #ifndef AKANTU_AKA_TUPLE_TOOLS_HH #define AKANTU_AKA_TUPLE_TOOLS_HH #ifndef AKANTU_ITERATORS_NAMESPACE #define AKANTU_ITERATORS_NAMESPACE akantu #endif namespace AKANTU_ITERATORS_NAMESPACE { namespace tuple { /* ---------------------------------------------------------------------- */ template struct named_tag { using _tag = tag; ///< key using _type = type; ///< value type template < typename T, std::enable_if_t::value> * = nullptr> explicit named_tag(T && value) // NOLINT : _value(std::forward(value)) {} type _value; }; namespace details { /* ---------------------------------------------------------------------- */ #if (defined(__GNUC__) || defined(__GNUG__)) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #endif template struct named_tag_proxy { using _tag = tag; template decltype(auto) operator=(T && value) { return named_tag<_tag, T>{std::forward(value)}; } }; #if (defined(__GNUC__) || defined(__GNUG__)) #pragma GCC diagnostic pop #endif } // namespace details /* ---------------------------------------------------------------------- */ template struct is_named_tag : public std::false_type {}; template struct is_named_tag> : public std::true_type {}; template struct is_named_tag> : public std::true_type {}; /* ---------------------------------------------------------------------- */ template struct named_tuple : public std::tuple { using Names_t = std::tuple; using parent = std::tuple; named_tuple(Params &&... params) : parent(std::forward(params._value)...) {} named_tuple(typename Params::_type &&... args) : parent(std::forward(args)...) {} private: template * = nullptr> static constexpr std::size_t get_element_index() noexcept { return -1; } template * = nullptr> static constexpr std::size_t get_element_index() noexcept { using _tag = std::tuple_element_t; return (std::is_same<_tag, tag>::value) ? Idx : get_element_index(); } public: template ::value> * = nullptr> constexpr decltype(auto) get(NT && /*unused*/) noexcept { const auto index = get_element_index(); static_assert((index != -1), "wrong named_tag"); return (std::get(*this)); } template ::value> * = nullptr> constexpr decltype(auto) get(NT && /*unused*/) const noexcept { const auto index = get_element_index(); static_assert((index != -1), "wrong named_tag"); return std::get(*this); } }; /* ---------------------------------------------------------------------- */ template struct is_named_tuple : public std::false_type {}; template struct is_named_tuple> : public std::true_type {}; /* ---------------------------------------------------------------------- */ template constexpr decltype(auto) make_named_tuple(Params &&... params) noexcept { return named_tuple(std::forward(params)...); } template constexpr decltype(auto) make_named_tag() noexcept { return details::named_tag_proxy{}; } template constexpr decltype(auto) get() { return make_named_tag>(); } template constexpr decltype(auto) get(Tuple && tuple) { return tuple.get(get()); } template ::value> * = nullptr> constexpr decltype(auto) get(Tuple && tuple) noexcept { return tuple.template get(); } #if defined(__INTEL_COMPILER) // intel warnings here #elif defined(__clang__) // clang warnings here #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template" #elif (defined(__GNUC__) || defined(__GNUG__)) // gcc warnings here #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #endif /// this is a GNU exstension /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3599.html template constexpr decltype(auto) operator"" _n() { return make_named_tag::hash>>(); } #if defined(__INTEL_COMPILER) #elif defined(__clang__) #pragma clang diagnostic pop #elif (defined(__GNUC__) || defined(__GNUG__)) #pragma GCC diagnostic pop #endif /* ------------------------------------------------------------------------ */ namespace details { template struct Foreach { template static inline bool not_equal(Tuple && a, Tuple && b) { if (std::get(std::forward(a)) == std::get(std::forward(b))) { return false; } return Foreach::not_equal(std::forward(a), std::forward(b)); } }; /* ---------------------------------------------------------------------- */ template <> struct Foreach<0> { template static inline bool not_equal(Tuple && a, Tuple && b) { return std::get<0>(std::forward(a)) != std::get<0>(std::forward(b)); } }; template decltype(auto) make_tuple_no_decay(Ts &&... args) { return std::tuple(std::forward(args)...); } template - decltype(auto) make_named_tuple_no_decay(std::tuple /*unused*/, Ts &&... args) { + decltype(auto) make_named_tuple_no_decay(std::tuple /*unused*/, + Ts &&... args) { return named_tuple...>(std::forward(args)...); } template void foreach_impl(F && func, Tuple && tuple, std::index_sequence && /*unused*/) { (void)std::initializer_list{ (std::forward(func)(std::get(std::forward(tuple))), 0)...}; } template decltype(auto) transform_impl(F && func, Tuple && tuple, std::index_sequence && /*unused*/) { return make_tuple_no_decay( std::forward(func)(std::get(std::forward(tuple)))...); } template decltype(auto) transform_named_impl(F && func, Tuple && tuple, std::index_sequence && /*unused*/) { - return make_named_tuple_no_decay(typename std::decay_t::Names_t{}, + return make_named_tuple_no_decay( + typename std::decay_t::Names_t{}, std::forward(func)(std::get(std::forward(tuple)))...); } } // namespace details /* ------------------------------------------------------------------------ */ template >::value> * = nullptr> bool are_not_equal(Tuple && a, Tuple && b) { return details::Foreach>::value>:: not_equal(std::forward(a), std::forward(b)); } template < class Tuple, std::enable_if_t>::value> * = nullptr> bool are_not_equal(Tuple && a, Tuple && b) { return details::Foreach< std::tuple_size::parent>::value>:: not_equal(std::forward(a), std::forward(b)); } template >::value> * = nullptr> void foreach (F && func, Tuple && tuple) { return details::foreach_impl( std::forward(func), std::forward(tuple), std::make_index_sequence< std::tuple_size>::value>{}); } template < class F, class Tuple, std::enable_if_t>::value> * = nullptr> void foreach (F && func, Tuple && tuple) { return details::foreach_impl( std::forward(func), std::forward(tuple), std::make_index_sequence< std::tuple_size::parent>::value>{}); } template >::value> * = nullptr> decltype(auto) transform(F && func, Tuple && tuple) { return details::transform_impl( std::forward(func), std::forward(tuple), std::make_index_sequence< std::tuple_size>::value>{}); } template < class F, class Tuple, std::enable_if_t>::value> * = nullptr> decltype(auto) transform(F && func, Tuple && tuple) { return details::transform_named_impl( std::forward(func), std::forward(tuple), std::make_index_sequence< std::tuple_size::parent>::value>{}); } namespace details { template decltype(auto) flatten(Tuple && tuples, std::index_sequence /*unused*/) { return std::tuple_cat(std::get(tuples)...); } } // namespace details template decltype(auto) flatten(Tuple && tuples) { return details::flatten(std::forward(tuples), std::make_index_sequence< std::tuple_size>::value>()); } } // namespace tuple } // namespace AKANTU_ITERATORS_NAMESPACE /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ namespace std { template struct iterator_traits< ::AKANTU_ITERATORS_NAMESPACE::tuple::named_tag> { using iterator_category = typename type::iterator_category; using value_type = typename type::value_type; using difference_type = typename type::difference_type; using pointer = typename type::pointer; using reference = typename type::reference; }; } // namespace std #endif /* AKANTU_AKA_TUPLE_TOOLS_HH */ diff --git a/include/iterators/aka_arange_iterator.hh b/include/iterators/aka_arange_iterator.hh index fc02ecbbd..a2b2ec16c 100644 --- a/include/iterators/aka_arange_iterator.hh +++ b/include/iterators/aka_arange_iterator.hh @@ -1,177 +1,177 @@ /** * @file aka_arange_iterator.hh * * @author Nicolas Richart * * @date creation jeu déc 12 2019 * * @brief implementation of arange * * @section LICENSE * * Copyright (©) 2010-2011 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-iterators 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. + * akantu-iterators 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 . + * along with akantu-iterators. If not, see . * */ /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ #ifndef AKA_ARANGE_ITERATOR_HH #define AKA_ARANGE_ITERATOR_HH #ifndef AKANTU_ITERATORS_NAMESPACE #define AKANTU_ITERATORS_NAMESPACE akantu #endif namespace AKANTU_ITERATORS_NAMESPACE { namespace 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) 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[](std::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 AKANTU_ITERATORS_NAMESPACE namespace std { template struct iterator_traits< ::AKANTU_ITERATORS_NAMESPACE::iterators::ArangeIterator> { private: using iterator_type = typename ::AKANTU_ITERATORS_NAMESPACE::iterators::ArangeIterator; public: using iterator_category = typename iterator_type::iterator_category; using value_type = typename iterator_type::value_type; using difference_type = typename iterator_type::difference_type; using pointer = typename iterator_type::pointer; using reference = typename iterator_type::reference; }; } // namespace std #endif /* AKA_ARANGE_ITERATOR_HH */ diff --git a/include/iterators/aka_enumerate_iterator.hh b/include/iterators/aka_enumerate_iterator.hh index d4ca5b94b..55789f28b 100644 --- a/include/iterators/aka_enumerate_iterator.hh +++ b/include/iterators/aka_enumerate_iterator.hh @@ -1,155 +1,155 @@ /** * @file aka_enumerate_iterator.hh * * @author Nicolas Richart * * @date creation jeu déc 12 2019 * * @brief implementation of enumerate. * * @section LICENSE * * Copyright (©) 2010-2011 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-iterators 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. + * akantu-iterators 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 . + * along with akantu-iterators. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "iterators/aka_zip_iterator.hh" /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ #ifndef AKA_ENUMERATE_ITERATOR_HH #define AKA_ENUMERATE_ITERATOR_HH #ifndef AKANTU_ITERATORS_NAMESPACE #define AKANTU_ITERATORS_NAMESPACE akantu #endif namespace AKANTU_ITERATORS_NAMESPACE { /* -------------------------------------------------------------------------- */ namespace iterators { template class EnumerateIterator { public: using value_type = std::tuple::value_type>; using difference_type = std::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 AKANTU_ITERATORS_NAMESPACE namespace std { template struct iterator_traits< ::AKANTU_ITERATORS_NAMESPACE::iterators::EnumerateIterator> { private: using iterator_type = typename ::AKANTU_ITERATORS_NAMESPACE::iterators::EnumerateIterator< Iterator>; public: using iterator_category = typename iterator_type::iterator_category; using value_type = typename iterator_type::value_type; using difference_type = typename iterator_type::difference_type; using pointer = typename iterator_type::pointer; using reference = typename iterator_type::reference; }; } // namespace std #endif /* AKA_ENUMERATE_ITERATOR_HH */ diff --git a/include/iterators/aka_zip_iterator.hh b/include/iterators/aka_zip_iterator.hh index 9b8e7b589..95c78c007 100644 --- a/include/iterators/aka_zip_iterator.hh +++ b/include/iterators/aka_zip_iterator.hh @@ -1,304 +1,304 @@ /** * @file aka_zip_iterator.hh * * @author Nicolas Richart * * @date creation jeu déc 12 2019 * * @brief A Documented file. * * @section LICENSE * * Copyright (©) 2010-2011 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-iterators 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. + * akantu-iterators 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 . + * along with akantu-iterators. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_compatibilty_with_cpp_standard.hh" #include "aka_tuple_tools.hh" /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ #ifndef AKA_ZIP_ITERATOR_HH #define AKA_ZIP_ITERATOR_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; }; } // namespace details /* ------------------------------------------------------------------------ */ template