LeechCraft  0.6.70-11552-gf61ee51c3d
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 #include "void.h"
36 
37 namespace LeechCraft
38 {
39 namespace Util
40 {
54  template<typename T>
56  {
57  using UndefinedTag = void;
58 
69  template<typename F>
70  using FmapResult_t = detail::ImplementationType;
71 
86  template<typename F>
87  static FmapResult_t<F> Apply (const T& functor, const F& function);
88  };
89 
90  namespace detail
91  {
92  template<typename T>
93  constexpr bool IsFunctorImpl (int, typename InstanceFunctor<T>::UndefinedTag* = nullptr)
94  {
95  return false;
96  }
97 
98  template<typename T>
99  constexpr bool IsFunctorImpl (float)
100  {
101  return true;
102  }
103  }
104 
111  template<typename T>
112  constexpr bool IsFunctor ()
113  {
114  return detail::IsFunctorImpl<T> (0);
115  }
116 
124  template<typename T, typename F>
126 
147  template<typename T, typename F, typename = std::enable_if_t<IsFunctor<T> ()>>
148  FmapResult_t<T, F> Fmap (const T& functor, const F& function)
149  {
150  return InstanceFunctor<T>::Apply (functor, function);
151  }
152 
173  template<typename T, typename F>
174  auto operator* (const F& function, const T& functor) -> decltype (Fmap (functor, function))
175  {
176  return Fmap (functor, function);
177  }
178 
199  template<typename T, typename F>
200  auto operator* (const T& functor, const F& function) -> decltype (Fmap (functor, function))
201  {
202  return Fmap (functor, function);
203  }
204 
205  namespace detail
206  {
207  template<typename T>
209  {
210  using Type = T;
211  };
212 
213  template<>
214  struct WrapVoidResult<void>
215  {
216  using Type = Void;
217  };
218 
219  template<typename T>
221  }
222 
233  template<typename T>
234  struct InstanceFunctor<boost::optional<T>>
235  {
236  template<typename F>
237  using FmapResult_t = boost::optional<detail::WrapVoidResult_t<std::decay_t<std::result_of_t<F (T)>>>>;
238 
239  template<typename F>
240  static FmapResult_t<F> Apply (const boost::optional<T>& t, const F& f)
241  {
242  if (!t)
243  return {};
244 
245  if constexpr (std::is_same_v<FmapResult_t<F>, boost::optional<Void>>)
246  {
247  std::invoke (f, *t);
248  return { Void {} };
249  }
250  else
251  return { std::invoke (f, *t) };
252  }
253  };
254 }
255 }
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition: oral.h:892
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.
typename WrapVoidResult< T >::Type WrapVoidResult_t
Definition: functor.h:220
constexpr bool IsFunctorImpl(int, typename InstanceFunctor< T >::UndefinedTag *=nullptr)
Definition: functor.h:93
boost::optional< detail::WrapVoidResult_t< std::decay_t< std::result_of_t< F(T)> >> > FmapResult_t
Definition: functor.h:237
A proper void type, akin to unit (or ()) type in functional languages.
Definition: void.h:41
constexpr bool IsFunctor()
Checks whether the given type has a Functor instance for it.
Definition: functor.h:112
FmapResult_t< T, F > Fmap(const T &functor, const F &function)
Apply the function f to the elements in functor.
Definition: functor.h:148
static FmapResult_t< F > Apply(const boost::optional< T > &t, const F &f)
Definition: functor.h:240
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:125
The Functor class is used for types that can be mapped over.
Definition: functor.h:55
detail::ImplementationType FmapResult_t
The type of the functor after its elements were mapped by the function F.
Definition: functor.h:70