LeechCraft  0.6.70-10870-g558588d6ec
Modular cross-platform feature rich live environment.
functor.h
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2014 Georg Rudoy
4  *
5  * Boost Software License - Version 1.0 - August 17th, 2003
6  *
7  * Permission is hereby granted, free of charge, to any person or organization
8  * obtaining a copy of the software and accompanying documentation covered by
9  * this license (the "Software") to use, reproduce, display, distribute,
10  * execute, and transmit the Software, and to prepare derivative works of the
11  * Software, and to permit third-parties to whom the Software is furnished to
12  * do so, all subject to the following:
13  *
14  * The copyright notices in the Software and this entire statement, including
15  * the above license grant, this restriction and the following disclaimer,
16  * must be included in all copies of the Software, in whole or in part, and
17  * all derivative works of the Software, unless such copies or derivative
18  * works are solely in the form of machine-executable object code generated by
19  * a source language processor.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
24  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
25  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  **********************************************************************/
29 
30 #pragma once
31 
32 #include <functional>
33 #include <boost/optional.hpp>
34 #include "typeclassutil.h"
35 
36 namespace LeechCraft
37 {
38 namespace Util
39 {
53  template<typename T>
55  {
56  using UndefinedTag = void;
57 
68  template<typename F>
69  using FmapResult_t = detail::ImplementationType;
70 
85  template<typename F>
86  static FmapResult_t<F> Apply (const T& functor, const F& function);
87  };
88 
89  namespace detail
90  {
91  template<typename T>
92  constexpr bool IsFunctorImpl (int, typename InstanceFunctor<T>::UndefinedTag* = nullptr)
93  {
94  return false;
95  }
96 
97  template<typename T>
98  constexpr bool IsFunctorImpl (float)
99  {
100  return true;
101  }
102  }
103 
110  template<typename T>
111  constexpr bool IsFunctor ()
112  {
113  return detail::IsFunctorImpl<T> (0);
114  }
115 
123  template<typename T, typename F>
125 
146  template<typename T, typename F, typename = std::enable_if_t<IsFunctor<T> ()>>
147  FmapResult_t<T, F> Fmap (const T& functor, const F& function)
148  {
149  return InstanceFunctor<T>::Apply (functor, function);
150  }
151 
172  template<typename T, typename F>
173  auto operator* (const F& function, const T& functor) -> decltype (Fmap (functor, function))
174  {
175  return Fmap (functor, function);
176  }
177 
198  template<typename T, typename F>
199  auto operator* (const T& functor, const F& function) -> decltype (Fmap (functor, function))
200  {
201  return Fmap (functor, function);
202  }
203 
214  template<typename T>
215  struct InstanceFunctor<boost::optional<T>>
216  {
217  template<typename F>
218  using FmapResult_t = boost::optional<std::decay_t<std::result_of_t<F (T)>>>;
219 
220  template<typename F>
221  static FmapResult_t<F> Apply (const boost::optional<T>& t, const F& f)
222  {
223  if (!t)
224  return {};
225 
226  return { std::invoke (f, *t) };
227  }
228  };
229 }
230 }
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition: oral.h:931
Definition: prelude.h:39
auto operator*(const AF &af, const AV &av) -> decltype(GSL(af, av))
Definition: applicative.h:63
static FmapResult_t< F > Apply(const T &functor, const F &function)
Applies the function to the each of the elements inside the functor.
boost::optional< std::decay_t< std::result_of_t< F(T)> >> FmapResult_t
Definition: functor.h:218
constexpr bool IsFunctorImpl(int, typename InstanceFunctor< T >::UndefinedTag *=nullptr)
Definition: functor.h:92
constexpr bool IsFunctor()
Checks whether the given type has a Functor instance for it.
Definition: functor.h:111
FmapResult_t< T, F > Fmap(const T &functor, const F &function)
Apply the function f to the elements in functor.
Definition: functor.h:147
static FmapResult_t< F > Apply(const boost::optional< T > &t, const F &f)
Definition: functor.h:221
typename InstanceFunctor< T >::template FmapResult_t< F > FmapResult_t
The result type of the contents of the functor T mapped by function F.
Definition: functor.h:124
The Functor class is used for types that can be mapped over.
Definition: functor.h:54
detail::ImplementationType FmapResult_t
The type of the functor after its elements were mapped by the function F.
Definition: functor.h:69