diff --git a/include/aka_compatibilty_with_cpp_standard.hh b/include/aka_compatibilty_with_cpp_standard.hh index 40125f798..dd4112f5f 100644 --- a/include/aka_compatibilty_with_cpp_standard.hh +++ b/include/aka_compatibilty_with_cpp_standard.hh @@ -1,186 +1,194 @@ /** * @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-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-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-iterators. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_static_if.hh" /* -------------------------------------------------------------------------- */ #include #include #include #include +#if __cplusplus >= 201703L +#include +#endif /* -------------------------------------------------------------------------- */ #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) { 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 constexpr bool bool_constant_v = std::bool_constant::value; template using conjunction = std::conjunction; template using disjunction = std::disjunction; template using negation = std::negation; -using invoke = std::invoke; -using apply = std::apply; +template +constexpr decltype(auto) apply(F && f, Tuple && t) { + return std::apply(std::forward(f), std::forward(t)); +} -using count_if = std::count_if; +template +decltype(auto) count_if(InputIt first, InputIt last, UnaryPredicate p) { + return std::count_if(first, last, p); +} #endif template using is_iterator_category_at_least = std::is_same, cat2>; } // namespace aka #endif /* AKANTU_AKA_COMPATIBILTY_WITH_CPP_STANDARD_HH */