diff --git a/third-party/akantu_iterators/include/aka_compatibilty_with_cpp_standard.hh b/third-party/akantu_iterators/include/aka_compatibilty_with_cpp_standard.hh index f82a03c0f..ed6f90b0a 100644 --- a/third-party/akantu_iterators/include/aka_compatibilty_with_cpp_standard.hh +++ b/third-party/akantu_iterators/include/aka_compatibilty_with_cpp_standard.hh @@ -1,200 +1,211 @@ /** * @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 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_static_if.hh" /* -------------------------------------------------------------------------- */ #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; } /* -------------------------------------------------------------------------- */ // 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 decltype(auto) INVOKE(F && f, Args &&... args) { return std::forward(f)(std::forward(args)...); } } // namespace detail template 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) { 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) { +auto count_if(InputIt first, InputIt last, UnaryPredicate p) -> + typename std::iterator_traits::difference_type { typename std::iterator_traits::difference_type ret = 0; for (; first != last; ++first) { if (p(*first)) { ret++; } } return ret; } namespace detail { template - constexpr T make_from_tuple_impl(Tuple && t, std::index_sequence) { + constexpr auto make_from_tuple_impl(Tuple && t, + std::index_sequence /*unused*/) + -> T { return T(std::get(std::forward(t))...); } } // namespace detail -template constexpr T make_from_tuple(Tuple && t) { +template +constexpr auto make_from_tuple(Tuple && t) -> T { return detail::make_from_tuple_impl( std::forward(t), std::make_index_sequence< std::tuple_size>::value>{}); } #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>; +template +struct size_type { + using type = typename std::decay_t::size_type; +}; + +template +using size_type_t = typename size_type::type; + } // namespace aka #endif /* AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH */ diff --git a/third-party/akantu_iterators/include/aka_tuple_tools.hh b/third-party/akantu_iterators/include/aka_tuple_tools.hh index c80f1cd01..0a33cf133 100644 --- a/third-party/akantu_iterators/include/aka_tuple_tools.hh +++ b/third-party/akantu_iterators/include/aka_tuple_tools.hh @@ -1,364 +1,544 @@ /** * @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 + 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; + static constexpr std::size_t get_element_index_() noexcept { + return std::size_t(-1); } template * = nullptr> - static constexpr std::size_t get_element_index() noexcept { + 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(); + : get_element_index_(); } public: + template + static constexpr std::size_t get_element_index() noexcept { + return get_element_index_(); + } + + template + static constexpr std::size_t get_element_index(NT && /*unused*/) noexcept { + return get_element_index_(); + } + template ::value> * = nullptr> constexpr decltype(auto) get(NT && /*unused*/) noexcept { - const auto index = get_element_index(); - static_assert((index != -1), "wrong named_tag"); + const auto index = get_element_index(); + static_assert((index != std::size_t(-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); + const auto index = get_element_index(); + static_assert((index != std::size_t(-1)), "wrong named_tag"); + return (std::get(*this)); + } + + template ::value> * = nullptr> + constexpr auto has(NT && /*unused*/) const noexcept -> bool { + const auto index = get_element_index(); + return (index != std::size_t(-1)); } }; /* ---------------------------------------------------------------------- */ 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 constexpr bool has(Tuple && tuple) { + return tuple.has(get()); + } + template ::value> * = nullptr> constexpr decltype(auto) get(Tuple && tuple) noexcept { return tuple.template get(); } + template struct tuple_name_tag { + using type = std::tuple_element_t; + }; + + template + using tuple_name_tag_t = typename tuple_name_tag::type; + + template struct tuple_element { + using type = std::tuple_element_t; + }; + + template + using tuple_element_t = typename tuple_element::type; + #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) { 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{}, std::forward(func)(std::get(std::forward(tuple)))...); } + template + decltype(auto) flatten(Tuple && tuples, + std::index_sequence /*unused*/) { + return std::tuple_cat(std::get(tuples)...); + } + + template + decltype(auto) append_impl(std::index_sequence && /*unused*/, + Tuple && tuple, Vals &&... other_vals) { + return make_tuple_no_decay(std::get(std::forward(tuple))..., + std::forward(other_vals)...); + } + + template + decltype(auto) append_named_impl(std::index_sequence && /*unused*/, + Tuple && tuple, Vals &&... other_vals) { + return make_named_tuple_no_decay( + std::tuple..., Vals...>{}, + std::get(std::forward(tuple))..., + std::forward(other_vals)...); + } + + template + decltype(auto) remove_impl(std::index_sequence && /*unused*/, + std::index_sequence && /*unused*/, + Tuple && tuple) { + return make_tuple_no_decay( + std::get(std::forward(tuple))..., + std::get(std::forward(tuple))...); + } + + template + decltype(auto) + remove_named_impl(std::index_sequence && /*unused*/, + std::index_sequence && /*unused*/, + Tuple && tuple) { + return make_named_tuple_no_decay( + std::tuple>..., + tuple::tuple_name_tag_t>...>{}, + std::get(std::forward(tuple))..., + std::get(std::forward(tuple))...); + } + + template + decltype(auto) replace_impl(std::index_sequence && /*unused*/, + std::index_sequence && /*unused*/, + Tuple && tuple, Value && value) { + return make_tuple_no_decay( + std::get(std::forward(tuple))..., + std::forward(value), + std::get(std::forward(tuple))...); + } + + template + decltype(auto) + replace_named_impl(std::index_sequence && /*unused*/, + std::index_sequence && /*unused*/, + Tuple && tuple, Value && value) { + using tuple_type = std::decay_t; + return make_named_tuple_no_decay( + std::tuple< + tuple::tuple_name_tag_t..., + decltype(get()), + tuple::tuple_name_tag_t...>{}, + std::get(std::forward(tuple))..., + std::forward(value), + 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>()); } + /* ------------------------------------------------------------------------ */ template struct cat { using type = decltype(std::tuple_cat(std::declval()...)); }; template using cat_t = typename cat::type; - /* -------------------------------------------------------------------------- - */ + /* ------------------------------------------------------------------------ */ template