• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2016-2018 T. Zachary Laine
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_YAP_ALGORITHM_FWD_HPP_INCLUDED
7 #define BOOST_YAP_ALGORITHM_FWD_HPP_INCLUDED
8 
9 #include <boost/yap/config.hpp>
10 
11 #include <boost/hana/integral_constant.hpp>
12 #include <boost/hana/tuple.hpp>
13 #include <boost/hana/core/is_a.hpp>
14 
15 
16 namespace boost { namespace yap {
17 
18     /** The enumeration representing all the kinds of expressions supported in
19         YAP.
20     */
21     enum class expr_kind {
22         expr_ref =
23             0, ///< A (possibly \c const) reference to another expression.
24 
25         terminal = 1, ///< A terminal expression.
26 
27         // unary
28         unary_plus = 2,  ///< \c +
29         negate = 3,      ///< \c -
30         dereference = 4, ///< \c *
31         complement = 5,  ///< \c ~
32         address_of = 6,  ///< \c &
33         logical_not = 7, ///< \c !
34         pre_inc = 8,     ///< \c ++
35         pre_dec = 9,     ///< \c \-\-
36         post_inc = 10,   ///< \c ++(int)
37         post_dec = 11,   ///< \c \-\-(int)
38 
39         // binary
40         shift_left = 12,         ///< \c <<
41         shift_right = 13,        ///< \c >>
42         multiplies = 14,         ///< \c *
43         divides = 15,            ///< \c /
44         modulus = 16,            ///< \c %
45         plus = 17,               ///< \c +
46         minus = 18,              ///< \c -
47         less = 19,               ///< \c <
48         greater = 20,            ///< \c >
49         less_equal = 21,         ///< \c <=
50         greater_equal = 22,      ///< \c >=
51         equal_to = 23,           ///< \c ==
52         not_equal_to = 24,       ///< \c !=
53         logical_or = 25,         ///< \c ||
54         logical_and = 26,        ///< \c &&
55         bitwise_and = 27,        ///< \c &
56         bitwise_or = 28,         ///< \c |
57         bitwise_xor = 29,        ///< \c ^
58         comma = 30,              ///< \c ,
59         mem_ptr = 31,            ///< \c ->*
60         assign = 32,             ///< \c =
61         shift_left_assign = 33,  ///< \c <<=
62         shift_right_assign = 34, ///< \c >>=
63         multiplies_assign = 35,  ///< \c *=
64         divides_assign = 36,     ///< \c /=
65         modulus_assign = 37,     ///< \c %=
66         plus_assign = 38,        ///< \c +=
67         minus_assign = 39,       ///< \c -=
68         bitwise_and_assign = 40, ///< \c &=
69         bitwise_or_assign = 41,  ///< \c |=
70         bitwise_xor_assign = 42, ///< \c ^=
71         subscript = 43,          ///< \c []
72 
73         // ternary
74         if_else = 44, ///< Analogous to \c ?: .
75 
76         // n-ary
77         call = 45 ///< \c ()
78     };
79 
80     /** The type used to represent the index of a placeholder terminal. */
81     template<long long I>
82     struct placeholder : hana::llong<I>
83     {
84     };
85 
86 #ifdef BOOST_YAP_DOXYGEN
87 
88     /** A metafunction that evaluates to std::true_type if \a Expr is an
89         Expression, and std::false_type otherwise. */
90     template<typename Expr>
91     struct is_expr;
92 
93 #else
94 
95     template<expr_kind Kind, typename Tuple>
96     struct expression;
97 
98     namespace detail {
99 
100         // void_t
101 
102         template<class...>
103         using void_t = void;
104 
105         // remove_cv_ref
106 
107         template<typename T>
108         struct remove_cv_ref : std::remove_cv<std::remove_reference_t<T>>
109         {
110         };
111 
112         template<typename T>
113         using remove_cv_ref_t = typename remove_cv_ref<T>::type;
114     }
115 
116     template<
117         typename Expr,
118         typename = detail::void_t<>,
119         typename = detail::void_t<>>
120     struct is_expr : std::false_type
121     {
122     };
123 
124     template<typename Expr>
125     struct is_expr<
126         Expr,
127         detail::void_t<decltype(detail::remove_cv_ref_t<Expr>::kind)>,
128         detail::void_t<decltype(std::declval<Expr>().elements)>>
129         : std::integral_constant<
130               bool,
131               std::is_same<
132                   std::remove_cv_t<decltype(
133                       detail::remove_cv_ref_t<Expr>::kind)>,
134                   expr_kind>::value &&
135                   hana::is_a<
136                       hana::tuple_tag,
137                       decltype(std::declval<Expr>().elements)>>
138     {
139     };
140 
141 #endif // BOOST_YAP_DOXYGEN
142 
143     /** A convenience alias for a terminal expression holding a \a T,
144         instantiated from expression template \a expr_template. */
145     template<template<expr_kind, class> class expr_template, typename T>
146     using terminal = expr_template<expr_kind::terminal, hana::tuple<T>>;
147 
148     /** A convenience alias for a reference expression holding an expression
149         \a T, instantiated from expression template \a expr_template. */
150     template<template<expr_kind, class> class expr_template, typename T>
151     using expression_ref = expr_template<
152         expr_kind::expr_ref,
153         hana::tuple<std::remove_reference_t<T> *>>;
154 
155 #ifndef BOOST_YAP_DOXYGEN
156 
157     template<typename Expr, typename... T>
158     constexpr decltype(auto) evaluate(Expr && expr, T &&... t);
159 
160     template<typename Expr, typename Transform, typename... Transforms>
161     constexpr decltype(auto) transform(
162         Expr && expr, Transform && transform, Transforms &&... transforms);
163 
164     template<typename Expr, typename Transform, typename... Transforms>
165     constexpr decltype(auto) transform_strict(
166         Expr && expr, Transform && transform, Transforms &&... transforms);
167 
168     template<typename T>
169     constexpr decltype(auto) deref(T && x);
170 
171     template<typename Expr>
172     constexpr decltype(auto) value(Expr && expr);
173 
174 #endif // BOOST_YAP_DOXYGEN
175 
176     namespace literals {
177 
178         /** Creates literal placeholders.  Placeholder indices are 1-based. */
179         template<char... c>
operator ""_p()180         constexpr auto operator"" _p()
181         {
182             using i = hana::llong<hana::ic_detail::parse<sizeof...(c)>({c...})>;
183             static_assert(1 <= i::value, "Placeholders must be >= 1.");
184             return expression<
185                 expr_kind::terminal,
186                 hana::tuple<placeholder<i::value>>>{};
187         }
188     }
189 
190     /** Used as the tag-type passed to a transform function written in the
191         tag-transform form. */
192     template<expr_kind Kind>
193     struct expr_tag
194     {
195         static const expr_kind kind = Kind;
196     };
197 
198     /** Used as the expression template returned by some operations inside YAP
199         when YAP does not have an expression template it was told to use.  For
200         instance, if transform() creates a new expression by transforming an
201         existing expression's elements, it will attempt to create the new
202         expression using the existing one's expression template.  If no such
203         template exists because the existing expression was not made from an
204         expression template, minimal_expr is used. */
205     template<expr_kind Kind, typename Tuple>
206     struct minimal_expr
207     {
208         static expr_kind const kind = Kind;
209         Tuple elements;
210     };
211 
212 }}
213 
214 #endif
215