| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 | /* Copyright 2016-2018 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/poly_collection for library home page. */#ifndef BOOST_POLY_COLLECTION_DETAIL_FUNCTIONAL_HPP#define BOOST_POLY_COLLECTION_DETAIL_FUNCTIONAL_HPP#if defined(_MSC_VER)#pragma once#endif#include <boost/config.hpp>#include <boost/detail/workaround.hpp>#include <boost/mp11/integer_sequence.hpp>#include <tuple>#include <utility>/* Assorted functional utilities. Much of this would be almost trivial with * C++14 generic lambdas.  */#if BOOST_WORKAROUND(BOOST_MSVC,>=1910)/* https://lists.boost.org/Archives/boost/2017/06/235687.php */#define BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(name,f) \struct name                                               \{                                                         \  template<typename... Args>                              \  auto operator()(Args&&... args)const                    \  {                                                       \    return f(std::forward<Args>(args)...);                \  }                                                       \};#else#define BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(name,f) \struct name                                               \{                                                         \  template<typename... Args>                              \  auto operator()(Args&&... args)const->                  \    decltype(f(std::forward<Args>(args)...))              \  {                                                       \    return f(std::forward<Args>(args)...);                \  }                                                       \};#endifnamespace boost{namespace poly_collection{namespace detail{template<typename F,typename... TailArgs>struct tail_closure_class{  tail_closure_class(const F& f,std::tuple<TailArgs...> t):f(f),t(t){}  template<typename... Args>  using return_type=decltype(    std::declval<F>()(std::declval<Args>()...,std::declval<TailArgs>()...));  template<typename... Args,std::size_t... I>  return_type<Args&&...> call(mp11::index_sequence<I...>,Args&&... args)  {    return f(std::forward<Args>(args)...,std::get<I>(t)...);  }  template<typename... Args>  return_type<Args&&...> operator()(Args&&... args)  {    return call(      mp11::make_index_sequence<sizeof...(TailArgs)>{},      std::forward<Args>(args)...);  }    F                       f;  std::tuple<TailArgs...> t; };template<typename F,typename... Args>tail_closure_class<F,Args&&...> tail_closure(const F& f,Args&&... args){  return {f,std::forward_as_tuple(std::forward<Args>(args)...)};}template<typename F,typename... HeadArgs>struct head_closure_class{  head_closure_class(const F& f,std::tuple<HeadArgs...> t):f(f),t(t){}  template<typename... Args>  using return_type=decltype(    std::declval<F>()(std::declval<HeadArgs>()...,std::declval<Args>()...));  template<typename... Args,std::size_t... I>  return_type<Args&&...> call(mp11::index_sequence<I...>,Args&&... args)  {    return f(std::get<I>(t)...,std::forward<Args>(args)...);  }  template<typename... Args>  return_type<Args&&...> operator()(Args&&... args)  {    return call(      mp11::make_index_sequence<sizeof...(HeadArgs)>{},      std::forward<Args>(args)...);  }    F                       f;  std::tuple<HeadArgs...> t; };template<typename F,typename... Args>head_closure_class<F,Args&&...> head_closure(const F& f,Args&&... args){  return {f,std::forward_as_tuple(std::forward<Args>(args)...)};}template<typename ReturnType,typename F>struct cast_return_class{  cast_return_class(const F& f):f(f){}  template<typename... Args>  ReturnType operator()(Args&&... args)const  {    return static_cast<ReturnType>(f(std::forward<Args>(args)...));  }  F f;};template<typename ReturnType,typename F>cast_return_class<ReturnType,F> cast_return(const F& f){  return {f};}template<typename F>struct deref_to_class{  deref_to_class(const F& f):f(f){}  template<typename... Args>  auto operator()(Args&&... args)->decltype(std::declval<F>()(*args...))  {    return f(*args...);  }  F f;};template<typename F>deref_to_class<F> deref_to(const F& f){  return {f};}template<typename F>struct deref_1st_to_class{  deref_1st_to_class(const F& f):f(f){}  template<typename Arg,typename... Args>  auto operator()(Arg&& arg,Args&&... args)    ->decltype(std::declval<F>()(*arg,std::forward<Args>(args)...))  {    return f(*arg,std::forward<Args>(args)...);  }  F f;};template<typename F>deref_1st_to_class<F> deref_1st_to(const F& f){  return {f};}struct transparent_equal_to{  template<typename T,typename U>  auto operator()(T&& x,U&& y)const    noexcept(noexcept(std::forward<T>(x)==std::forward<U>(y)))    ->decltype(std::forward<T>(x)==std::forward<U>(y))  {    return std::forward<T>(x)==std::forward<U>(y);  }};} /* namespace poly_collection::detail */} /* namespace poly_collection */} /* namespace boost */#endif
 |