1/*=============================================================================
2 Copyright (c) 2020 Nikita Kniazev
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6=============================================================================*/
7#ifndef BOOST_SPIRIT_X3_SUPPORT_TRAITS_ATTRIBUTE_OF_BINARY
8#define BOOST_SPIRIT_X3_SUPPORT_TRAITS_ATTRIBUTE_OF_BINARY
9
10#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
11#include <boost/spirit/home/x3/support/unused.hpp>
12#include <boost/type_traits/type_identity.hpp>
13
14namespace boost { namespace spirit { namespace x3 { namespace detail
15{
16 template <typename... T>
17 struct type_sequence
18 {
19 using type = type_sequence;
20
21 static const int size = sizeof...(T);
22
23 template <typename... U>
24 using append = type_sequence<T..., U...>;
25
26 template <typename... U>
27 using prepend = type_sequence<U..., T...>;
28
29 template <typename U>
30 using extend = typename U::template prepend<T...>;
31
32 template <template <typename...> class U>
33 using transfer_to = U<T...>;
34 };
35
36 template <typename Attribute>
37 struct types_of_binary_init : type_sequence<Attribute> {};
38 template <>
39 struct types_of_binary_init<unused_type> : type_sequence<> {};
40 template <>
41 struct types_of_binary_init<unused_type const> : type_sequence<> {};
42
43 template <template <typename, typename> class B, typename P, typename C>
44 struct get_types_of_binary
45 : types_of_binary_init<typename traits::attribute_of<P, C>::type> {};
46 template <template <typename, typename> class B, typename L, typename R, typename C>
47 struct get_types_of_binary<B, B<L, R>, C>
48 : get_types_of_binary<B, L, C>::template extend<get_types_of_binary<B, R, C>> {};
49
50 template <template <typename...> class A, typename T, int = T::size>
51 struct type_sequence_to_attribute { using type = typename T::template transfer_to<A>; };
52 template <template <typename...> class A, typename T>
53 struct type_sequence_to_attribute<A, T, 1> : T::template transfer_to<type_identity> {};
54 template <template <typename...> class A, typename T>
55 struct type_sequence_to_attribute<A, T, 0> { using type = unused_type; };
56
57 template <template <typename...> class A, template <typename, typename> class B,
58 typename L, typename R, typename C>
59 using attribute_of_binary = type_sequence_to_attribute<A,
60 typename get_types_of_binary<B, B<L, R>, C>::type>;
61}}}}
62#endif
63

source code of boost/libs/spirit/include/boost/spirit/home/x3/support/traits/attribute_of_binary.hpp