123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- // Copyright (C) 2016-2018 T. Zachary Laine
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_YAP_ALGORITHM_FWD_HPP_INCLUDED
- #define BOOST_YAP_ALGORITHM_FWD_HPP_INCLUDED
- #include <boost/yap/config.hpp>
- #include <boost/hana/integral_constant.hpp>
- #include <boost/hana/tuple.hpp>
- #include <boost/hana/core/is_a.hpp>
- namespace boost { namespace yap {
- /** The enumeration representing all the kinds of expressions supported in
- YAP.
- */
- enum class expr_kind {
- expr_ref =
- 0, ///< A (possibly \c const) reference to another expression.
- terminal = 1, ///< A terminal expression.
- // unary
- unary_plus = 2, ///< \c +
- negate = 3, ///< \c -
- dereference = 4, ///< \c *
- complement = 5, ///< \c ~
- address_of = 6, ///< \c &
- logical_not = 7, ///< \c !
- pre_inc = 8, ///< \c ++
- pre_dec = 9, ///< \c \-\-
- post_inc = 10, ///< \c ++(int)
- post_dec = 11, ///< \c \-\-(int)
- // binary
- shift_left = 12, ///< \c <<
- shift_right = 13, ///< \c >>
- multiplies = 14, ///< \c *
- divides = 15, ///< \c /
- modulus = 16, ///< \c %
- plus = 17, ///< \c +
- minus = 18, ///< \c -
- less = 19, ///< \c <
- greater = 20, ///< \c >
- less_equal = 21, ///< \c <=
- greater_equal = 22, ///< \c >=
- equal_to = 23, ///< \c ==
- not_equal_to = 24, ///< \c !=
- logical_or = 25, ///< \c ||
- logical_and = 26, ///< \c &&
- bitwise_and = 27, ///< \c &
- bitwise_or = 28, ///< \c |
- bitwise_xor = 29, ///< \c ^
- comma = 30, ///< \c ,
- mem_ptr = 31, ///< \c ->*
- assign = 32, ///< \c =
- shift_left_assign = 33, ///< \c <<=
- shift_right_assign = 34, ///< \c >>=
- multiplies_assign = 35, ///< \c *=
- divides_assign = 36, ///< \c /=
- modulus_assign = 37, ///< \c %=
- plus_assign = 38, ///< \c +=
- minus_assign = 39, ///< \c -=
- bitwise_and_assign = 40, ///< \c &=
- bitwise_or_assign = 41, ///< \c |=
- bitwise_xor_assign = 42, ///< \c ^=
- subscript = 43, ///< \c []
- // ternary
- if_else = 44, ///< Analogous to \c ?: .
- // n-ary
- call = 45 ///< \c ()
- };
- /** The type used to represent the index of a placeholder terminal. */
- template<long long I>
- struct placeholder : hana::llong<I>
- {
- };
- #ifdef BOOST_YAP_DOXYGEN
- /** A metafunction that evaluates to std::true_type if \a Expr is an
- Expression, and std::false_type otherwise. */
- template<typename Expr>
- struct is_expr;
- #else
- template<expr_kind Kind, typename Tuple>
- struct expression;
- namespace detail {
- // void_t
- template<class...>
- using void_t = void;
- // remove_cv_ref
- template<typename T>
- struct remove_cv_ref : std::remove_cv<std::remove_reference_t<T>>
- {
- };
- template<typename T>
- using remove_cv_ref_t = typename remove_cv_ref<T>::type;
- }
- template<
- typename Expr,
- typename = detail::void_t<>,
- typename = detail::void_t<>>
- struct is_expr : std::false_type
- {
- };
- template<typename Expr>
- struct is_expr<
- Expr,
- detail::void_t<decltype(detail::remove_cv_ref_t<Expr>::kind)>,
- detail::void_t<decltype(std::declval<Expr>().elements)>>
- : std::integral_constant<
- bool,
- std::is_same<
- std::remove_cv_t<decltype(
- detail::remove_cv_ref_t<Expr>::kind)>,
- expr_kind>::value &&
- hana::is_a<
- hana::tuple_tag,
- decltype(std::declval<Expr>().elements)>>
- {
- };
- #endif // BOOST_YAP_DOXYGEN
- /** A convenience alias for a terminal expression holding a \a T,
- instantiated from expression template \a expr_template. */
- template<template<expr_kind, class> class expr_template, typename T>
- using terminal = expr_template<expr_kind::terminal, hana::tuple<T>>;
- /** A convenience alias for a reference expression holding an expression
- \a T, instantiated from expression template \a expr_template. */
- template<template<expr_kind, class> class expr_template, typename T>
- using expression_ref = expr_template<
- expr_kind::expr_ref,
- hana::tuple<std::remove_reference_t<T> *>>;
- #ifndef BOOST_YAP_DOXYGEN
- template<typename Expr, typename... T>
- constexpr decltype(auto) evaluate(Expr && expr, T &&... t);
- template<typename Expr, typename Transform, typename... Transforms>
- constexpr decltype(auto) transform(
- Expr && expr, Transform && transform, Transforms &&... transforms);
- template<typename Expr, typename Transform, typename... Transforms>
- constexpr decltype(auto) transform_strict(
- Expr && expr, Transform && transform, Transforms &&... transforms);
- template<typename T>
- constexpr decltype(auto) deref(T && x);
- template<typename Expr>
- constexpr decltype(auto) value(Expr && expr);
- #endif // BOOST_YAP_DOXYGEN
- namespace literals {
- /** Creates literal placeholders. Placeholder indices are 1-based. */
- template<char... c>
- constexpr auto operator"" _p()
- {
- using i = hana::llong<hana::ic_detail::parse<sizeof...(c)>({c...})>;
- static_assert(1 <= i::value, "Placeholders must be >= 1.");
- return expression<
- expr_kind::terminal,
- hana::tuple<placeholder<i::value>>>{};
- }
- }
- /** Used as the tag-type passed to a transform function written in the
- tag-transform form. */
- template<expr_kind Kind>
- struct expr_tag
- {
- static const expr_kind kind = Kind;
- };
- /** Used as the expression template returned by some operations inside YAP
- when YAP does not have an expression template it was told to use. For
- instance, if transform() creates a new expression by transforming an
- existing expression's elements, it will attempt to create the new
- expression using the existing one's expression template. If no such
- template exists because the existing expression was not made from an
- expression template, minimal_expr is used. */
- template<expr_kind Kind, typename Tuple>
- struct minimal_expr
- {
- static expr_kind const kind = Kind;
- Tuple elements;
- };
- }}
- #endif
|