LeechCraft  0.6.70-15082-g543737046d
Modular cross-platform feature rich live environment.
applicative.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 <optional>
12 #include "either.h"
13 
14 namespace LC
15 {
16 namespace Util
17 {
18  template<typename Applicative>
19  struct InstanceApplicative;
20 
21  template<typename AF, typename AV>
22  using GSLResult_t = typename InstanceApplicative<AF>::template GSLResult<AV>::Type_t;
23 
24  template<template<typename...> class Applicative, typename... Args, typename T>
25  auto Pure (const T& v)
26  {
27  return InstanceApplicative<Applicative<Args..., T>>::Pure (v);
28  }
29 
30  template<typename Applicative, typename T>
31  auto Pure (const T& v) -> decltype (InstanceApplicative<Applicative>::Pure (v))
32  {
34  }
35 
36  template<typename AF, typename AV>
37  GSLResult_t<AF, AV> GSL (const AF& af, const AV& av)
38  {
39  return InstanceApplicative<AF>::GSL (af, av);
40  }
41 
42  template<typename AF, typename AV>
43  auto operator* (const AF& af, const AV& av) -> decltype (GSL (af, av))
44  {
45  return GSL (af, av);
46  }
47 
48  // Implementations
49 
50  template<typename T>
51  struct InstanceApplicative<std::optional<T>>
52  {
53  using Type_t = std::optional<T>;
54 
55  template<typename>
56  struct GSLResult;
57 
58  template<typename V>
59  struct GSLResult<std::optional<V>>
60  {
61  using Type_t = std::optional<std::result_of_t<T (const V&)>>;
62  };
63 
64  template<typename U>
65  static std::optional<U> Pure (const U& v)
66  {
67  return { v };
68  }
69 
70  template<typename AV>
71  static GSLResult_t<Type_t, AV> GSL (const Type_t& f, const AV& v)
72  {
73  if (!f || !v)
74  return {};
75 
76  return { (*f) (*v) };
77  }
78  };
79 
80  template<typename L, typename R>
81  struct InstanceApplicative<Either<L, R>>
82  {
84 
85  template<typename>
86  struct GSLResult;
87 
88  template<typename V>
89  struct GSLResult<Either<L, V>>
90  {
91  using Type_t = Either<L, std::result_of_t<R (const V&)>>;
92  };
93 
94  template<typename RP>
95  static Either<L, RP> Pure (const RP& v)
96  {
97  return Either<L, RP>::Right (v);
98  }
99 
100  template<typename AV>
101  static GSLResult_t<Type_t, AV> GSL (const Type_t& f, const AV& v)
102  {
104 
105  if (f.IsLeft ())
106  return R_t::Left (f.GetLeft ());
107 
108  if (v.IsLeft ())
109  return R_t::Left (v.GetLeft ());
110 
111  return R_t::Right (f.GetRight () (v.GetRight ()));
112  }
113  };
114 
115 }
116 }
LC::Util::Either::Right
static Either Right(const R &r)
Definition: either.h:132
LC::Util::Pure
auto Pure(const T &v)
Definition: applicative.h:37
LC::Util::InstanceApplicative< std::optional< T > >::GSLResult< std::optional< V > >::Type_t
std::optional< std::result_of_t< T(const V &)> > Type_t
Definition: applicative.h:73
LC::Util::Either
Definition: either.h:33
either.h
LC::Util::operator*
auto operator*(const AF &af, const AV &av) -> decltype(GSL(af, av))
Definition: applicative.h:55
LC::Util::InstanceApplicative
Definition: applicative.h:31
LC::Util::InstanceApplicative< std::optional< T > >::Type_t
std::optional< T > Type_t
Definition: applicative.h:65
LC::Util::GSLResult_t
typename InstanceApplicative< AF >::template GSLResult< AV >::Type_t GSLResult_t
Definition: applicative.h:34
LC::Util::Pure
auto Pure(const T &v) -> decltype(InstanceApplicative< Applicative >::Pure(v))
Definition: applicative.h:43
LC
Definition: constants.h:14
LC::Util::oral::sph::f
constexpr detail::ExprTree< detail::ExprType::LeafStaticPlaceholder, detail::MemberPtrs< Ptr > > f
Definition: oral.h:952
LC::Util::GSL
GSLResult_t< AF, AV > GSL(const AF &af, const AV &av)
Definition: applicative.h:49