LeechCraft 0.6.70-17609-g3dde4097dd
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
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 * Distributed under the Boost Software License, Version 1.0.
6 * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7 **********************************************************************/
8
9#pragma once
10
11#include <functional>
12#include <optional>
13#include "typeclassutil.h"
14#include "void.h"
15#include "either.h"
16
17namespace LC
18{
19namespace Util
20{
34 template<typename T>
36 {
37 using UndefinedTag = void;
38
49 template<typename F>
50 using FmapResult_t = detail::ImplementationType;
51
66 template<typename F>
67 static FmapResult_t<F> Apply (const T& functor, const F& function);
68 };
69
70 namespace detail
71 {
72 template<typename T>
73 constexpr bool IsFunctorImpl (int, typename InstanceFunctor<T>::UndefinedTag* = nullptr)
74 {
75 return false;
76 }
77
78 template<typename T>
79 constexpr bool IsFunctorImpl (float)
80 {
81 return true;
82 }
83 }
84
91 template<typename T>
92 constexpr bool IsFunctor ()
93 {
94 return detail::IsFunctorImpl<T> (0);
95 }
96
104 template<typename T, typename F>
106
127 template<typename T, typename F, typename = std::enable_if_t<IsFunctor<T> ()>>
128 FmapResult_t<T, F> Fmap (const T& functor, const F& function)
129 {
130 return InstanceFunctor<T>::Apply (functor, function);
131 }
132
153 template<typename T, typename F>
154 auto operator* (const F& function, const T& functor) -> decltype (Fmap (functor, function))
155 {
156 return Fmap (functor, function);
157 }
158
179 template<typename T, typename F>
180 auto operator* (const T& functor, const F& function) -> decltype (Fmap (functor, function))
181 {
182 return Fmap (functor, function);
183 }
184
185 namespace detail
186 {
187 template<typename T>
189 {
190 using Type = T;
191 };
192
193 template<>
194 struct WrapVoidResult<void>
195 {
196 using Type = Void;
197 };
198
199 template<typename T>
201 }
202
213 template<typename T>
214 struct InstanceFunctor<std::optional<T>>
215 {
216 template<typename F>
217 using FmapResult_t = std::optional<detail::WrapVoidResult_t<std::decay_t<std::invoke_result_t<F, T>>>>;
218
219 template<typename F>
220 static FmapResult_t<F> Apply (const std::optional<T>& t, const F& f)
221 {
222 if (!t)
223 return {};
224
225 if constexpr (std::is_same_v<FmapResult_t<F>, std::optional<Void>>)
226 {
227 std::invoke (f, *t);
228 return { Void {} };
229 }
230 else
231 return { std::invoke (f, *t) };
232 }
233 };
234
235 template<typename L, typename R>
237 {
238 template<typename F>
240
241 template<typename F>
242 static FmapResult_t<F> Apply (const Either<L, R>& either, const F& f)
243 {
244 if (either.IsLeft ())
245 return FmapResult_t<F>::Left (either.GetLeft ());
246
247 return FmapResult_t<F>::Right (f (either.GetRight ()));
248 }
249 };
250}
251}
const L & GetLeft() const
Definition either.h:93
bool IsLeft() const
Definition either.h:83
const R & GetRight() const
Definition either.h:100
typename WrapVoidResult< T >::Type WrapVoidResult_t
Definition functor.h:200
constexpr bool IsFunctorImpl(int, typename InstanceFunctor< T >::UndefinedTag *=nullptr)
Definition functor.h:73
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:105
constexpr bool IsFunctor()
Checks whether the given type has a Functor instance for it.
Definition functor.h:92
FmapResult_t< T, F > Fmap(const T &functor, const F &function)
Apply the function f to the elements in functor.
Definition functor.h:128
auto operator*(const F &function, const T &functor) -> decltype(Fmap(functor, function))
An operator-style alias for Fmap().
Definition functor.h:154
Definition constants.h:15
static FmapResult_t< F > Apply(const Either< L, R > &either, const F &f)
Definition functor.h:242
Either< L, std::invoke_result_t< F, R > > FmapResult_t
Definition functor.h:239
static FmapResult_t< F > Apply(const std::optional< T > &t, const F &f)
Definition functor.h:220
std::optional< detail::WrapVoidResult_t< std::decay_t< std::invoke_result_t< F, T > > > > FmapResult_t
Definition functor.h:217
The Functor class is used for types that can be mapped over.
Definition functor.h:36
detail::ImplementationType FmapResult_t
The type of the functor after its elements were mapped by the function F.
Definition functor.h:50
static FmapResult_t< F > Apply(const T &functor, const F &function)
Applies the function to the each of the elements inside the functor.
A proper void type, akin to unit (or ()) type in functional languages.
Definition void.h:21