concepts.hpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2014, 2015 Ableton AG, Berlin. All rights reserved.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
21 //
22 
27 #pragma once
28 
30 #include <atria/meta/concept.hpp>
32 
33 namespace atria {
34 namespace xform {
35 
43 {
44  struct any_t
45  {
46  any_t();
47  template <typename T> any_t(T);
48  };
49 
50  template <typename T>
51  auto requires_(T&& t)
52  -> decltype(
54  state_unwrap(t),
55  state_complete(t),
56  bool(state_is_reduced(t)),
57  any_t(state_data(t, constantly(any_t{}))),
59  decltype(state_unwrap(t)),
60  std::is_same<T, boost::mpl::_>,
62 };
63 
68 ABL_CONCEPT_SPEC(Reducing_function)
69 {
70  template <typename R, typename S, typename... Is>
71  auto requires_(R&& r, S&& s, Is&&... is)
72  -> decltype(
74  r(s, is...),
75  r(r(s, is...), is...),
77  std::is_same<
78  decltype(r(s, is...)),
79  decltype(r(r(s, is...), is...))>())>(),
81  State<decltype(r(s, is...))>())>(),
83  State<decltype(r(r(s, is...), is...))>())>()));
84 };
85 
86 namespace detail {
87 
88 template <typename R, typename S, typename I>
89 struct is_reducing_function
90  : std::integral_constant<bool, Reducing_function<R, S, I>()>
91 {};
92 
93 template <typename R, typename S, typename... Is>
94 struct is_reducing_function<R, S, meta::pack<Is...> >
95  : std::integral_constant<bool, Reducing_function<R, S, Is...>()>
96 {};
97 
98 template <typename I>
99 struct decl_reducing_function
100 {
101  template <typename S>
102  auto operator() (S&&, I) -> S&&;
103 };
104 
105 template <typename... Is>
106 struct decl_reducing_function<meta::pack<Is...> >
107 {
108  template <typename S>
109  auto operator() (S&&, Is...) -> S&&;
110 };
111 
112 } // namespace detail
113 
124 ABL_CONCEPT_SPEC(Transducer)
125 {
126  struct foo_t {};
127 
128  template <typename T>
129  using rf_t = detail::decl_reducing_function<T>;
130 
131  template <typename T, typename InputT, typename OutputT>
132  auto requires_(T&& t, InputT, OutputT)
133  -> decltype(
135  t(rf_t<OutputT>{}),
136  meta::require<(
137  detail::is_reducing_function<
138  decltype(t(rf_t<OutputT>{})),
139  foo_t,
140  InputT>())>()));
141 
142  template <typename T, typename InputT>
143  auto requires_(T&& t, InputT&& i)
144  -> decltype(requires_(t, i, i));
145 };
146 
150 ABL_CONCEPT_SPEC(Transparent_transducer)
151 {
152  struct foo_t {};
153  struct bar_t {};
154  struct baz_t {};
155 
156  template <typename T>
157  auto requires_(T&& t)
158  -> decltype(
160  meta::require<(
161  Transducer<T, foo_t>())>(),
162  meta::require<(
163  Transducer<T, meta::pack<bar_t, foo_t> >())>(),
164  meta::require<(
165  Transducer<T, meta::pack<baz_t, bar_t, foo_t> >())>()));
166 };
167 
168 } // namespace xform
169 } // namespace atria
Utility classes for definining and using concepts lite in C++11.
ABL_CONCEPT_SPEC(State)
Concept for a type that can be used as a state of a reducing function.
Definition: concepts.hpp:42
auto state_unwrap(T &&s) -> decltype(state_traits_t< T >::unwrap(std::forward< T >(s)))
Convenience function for calling state_traits::unwrap
auto constantly(T &&value) -> constantly_t< estd::decay_t< T > >
Similar to clojure.core/constantly.
Definition: constantly.hpp:56
estd::enable_if_t< Requirement, int > require
Utility to define concepts in terms of other concepts or other kinds boolean requirements.
Definition: concept.hpp:110
estd::enable_if_t< if_any< T, Mfs... >::type::value, int > require_any
Like require, but based on the semantics of if_any.
Definition: concept.hpp:282
auto state_data(T &&s, D &&d) -> decltype(state_traits_t< T >::data(std::forward< T >(s), std::forward< D >(d)))
Convenience function for calling state_traits::data
MPL-compatible sequence that just holds a vector of types as a paremeter pack.
Definition: pack.hpp:57
void expressions(Ts &&...)
Allows to validate a sequence of expressions in a single decltype.
auto state_complete(T &&s) -> decltype(state_traits_t< T >::complete(std::forward< T >(s)))
Convenience function for calling state_traits::complete
C++ amazing templates and reusable implementations awesomeness.
Definition: _doc.hpp:35
auto state_is_reduced(T &&s) -> bool
Convenience function for calling state_traits::is_reduced
Fork me on GitHub