annotate DEPENDENCIES/generic/include/boost/proto/transform/make.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 ///////////////////////////////////////////////////////////////////////////////
Chris@16 2 /// \file make.hpp
Chris@16 3 /// Contains definition of the make<> transform.
Chris@16 4 //
Chris@16 5 // Copyright 2008 Eric Niebler. Distributed under the Boost
Chris@16 6 // Software License, Version 1.0. (See accompanying file
Chris@16 7 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8
Chris@16 9 #ifndef BOOST_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007
Chris@16 10 #define BOOST_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007
Chris@16 11
Chris@16 12 #include <boost/detail/workaround.hpp>
Chris@16 13 #include <boost/preprocessor/repetition/enum.hpp>
Chris@16 14 #include <boost/preprocessor/repetition/enum_params.hpp>
Chris@16 15 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
Chris@16 16 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
Chris@16 17 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
Chris@16 18 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
Chris@16 19 #include <boost/preprocessor/facilities/intercept.hpp>
Chris@16 20 #include <boost/preprocessor/cat.hpp>
Chris@16 21 #include <boost/preprocessor/iteration/iterate.hpp>
Chris@16 22 #include <boost/preprocessor/selection/max.hpp>
Chris@16 23 #include <boost/preprocessor/arithmetic/inc.hpp>
Chris@16 24 #include <boost/mpl/and.hpp>
Chris@16 25 #include <boost/mpl/aux_/has_type.hpp>
Chris@16 26 #include <boost/proto/detail/template_arity.hpp>
Chris@16 27 #include <boost/utility/result_of.hpp>
Chris@16 28 #include <boost/proto/proto_fwd.hpp>
Chris@16 29 #include <boost/proto/traits.hpp>
Chris@16 30 #include <boost/proto/args.hpp>
Chris@16 31 #include <boost/proto/transform/impl.hpp>
Chris@16 32 #include <boost/proto/transform/detail/pack.hpp>
Chris@16 33 #include <boost/proto/detail/as_lvalue.hpp>
Chris@16 34 #include <boost/proto/detail/ignore_unused.hpp>
Chris@16 35
Chris@101 36 #if defined(_MSC_VER)
Chris@16 37 # pragma warning(push)
Chris@16 38 # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
Chris@16 39 #endif
Chris@16 40
Chris@16 41 namespace boost { namespace proto
Chris@16 42 {
Chris@16 43 namespace detail
Chris@16 44 {
Chris@16 45 template<typename T>
Chris@16 46 struct is_applyable
Chris@16 47 : mpl::and_<is_callable<T>, is_transform<T> >
Chris@16 48 {};
Chris@16 49
Chris@16 50 template<typename T, bool HasType = mpl::aux::has_type<T>::value>
Chris@16 51 struct nested_type
Chris@16 52 {
Chris@16 53 typedef typename T::type type;
Chris@16 54 };
Chris@16 55
Chris@16 56 template<typename T>
Chris@16 57 struct nested_type<T, false>
Chris@16 58 {
Chris@16 59 typedef T type;
Chris@16 60 };
Chris@16 61
Chris@16 62 template<typename T, bool Applied>
Chris@16 63 struct nested_type_if
Chris@16 64 {
Chris@16 65 typedef T type;
Chris@16 66 static bool const applied = false;
Chris@16 67 };
Chris@16 68
Chris@16 69 template<typename T>
Chris@16 70 struct nested_type_if<T, true>
Chris@16 71 : nested_type<T>
Chris@16 72 {
Chris@16 73 static bool const applied = true;
Chris@16 74 };
Chris@16 75
Chris@16 76 template<
Chris@16 77 typename R
Chris@16 78 , typename Expr, typename State, typename Data
Chris@16 79 BOOST_PROTO_TEMPLATE_ARITY_PARAM(long Arity = detail::template_arity<R>::value)
Chris@16 80 >
Chris@16 81 struct make_
Chris@16 82 {
Chris@16 83 typedef R type;
Chris@16 84 static bool const applied = false;
Chris@16 85 };
Chris@16 86
Chris@16 87 template<
Chris@16 88 typename R
Chris@16 89 , typename Expr, typename State, typename Data
Chris@16 90 , bool IsApplyable = is_applyable<R>::value
Chris@16 91 >
Chris@16 92 struct make_if_
Chris@16 93 : make_<R, Expr, State, Data>
Chris@16 94 {};
Chris@16 95
Chris@16 96 template<typename R, typename Expr, typename State, typename Data>
Chris@16 97 struct make_if_<R, Expr, State, Data, true>
Chris@16 98 : uncvref<typename when<_, R>::template impl<Expr, State, Data>::result_type>
Chris@16 99 {
Chris@16 100 static bool const applied = true;
Chris@16 101 };
Chris@16 102
Chris@16 103 #if BOOST_WORKAROUND(__GNUC__, == 3) || (BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0)
Chris@16 104 // work around GCC bug
Chris@16 105 template<typename Tag, typename Args, long N, typename Expr, typename State, typename Data>
Chris@16 106 struct make_if_<proto::expr<Tag, Args, N>, Expr, State, Data, false>
Chris@16 107 {
Chris@16 108 typedef proto::expr<Tag, Args, N> type;
Chris@16 109 static bool const applied = false;
Chris@16 110 };
Chris@16 111
Chris@16 112 // work around GCC bug
Chris@16 113 template<typename Tag, typename Args, long N, typename Expr, typename State, typename Data>
Chris@16 114 struct make_if_<proto::basic_expr<Tag, Args, N>, Expr, State, Data, false>
Chris@16 115 {
Chris@16 116 typedef proto::basic_expr<Tag, Args, N> type;
Chris@16 117 static bool const applied = false;
Chris@16 118 };
Chris@16 119 #endif
Chris@16 120
Chris@16 121 template<typename Type, bool IsAggregate = detail::is_aggregate_<Type>::value>
Chris@16 122 struct construct_
Chris@16 123 {
Chris@16 124 typedef Type result_type;
Chris@16 125
Chris@16 126 BOOST_FORCEINLINE
Chris@16 127 Type operator ()() const
Chris@16 128 {
Chris@16 129 return Type();
Chris@16 130 }
Chris@16 131
Chris@16 132 // Other overloads generated by the preprocessor
Chris@16 133 #include <boost/proto/transform/detail/construct_funop.hpp>
Chris@16 134 };
Chris@16 135
Chris@16 136 template<typename Type>
Chris@16 137 struct construct_<Type, true>
Chris@16 138 {
Chris@16 139 typedef Type result_type;
Chris@16 140
Chris@16 141 BOOST_FORCEINLINE
Chris@16 142 Type operator ()() const
Chris@16 143 {
Chris@16 144 return Type();
Chris@16 145 }
Chris@16 146
Chris@16 147 // Other overloads generated by the preprocessor
Chris@16 148 #include <boost/proto/transform/detail/construct_pod_funop.hpp>
Chris@16 149 };
Chris@16 150
Chris@16 151 }
Chris@16 152
Chris@16 153 /// \brief A PrimitiveTransform which prevents another PrimitiveTransform
Chris@16 154 /// from being applied in an \c ObjectTransform.
Chris@16 155 ///
Chris@16 156 /// When building higher order transforms with <tt>make\<\></tt> or
Chris@16 157 /// <tt>lazy\<\></tt>, you sometimes would like to build types that
Chris@16 158 /// are parameterized with Proto transforms. In such lambda-style
Chris@16 159 /// transforms, Proto will unhelpfully find all nested transforms
Chris@16 160 /// and apply them, even if you don't want them to be applied. Consider
Chris@16 161 /// the following transform, which will replace the \c _ in
Chris@16 162 /// <tt>Bar<_>()</tt> with <tt>proto::terminal\<int\>::type</tt>:
Chris@16 163 ///
Chris@16 164 /// \code
Chris@16 165 /// template<typename T>
Chris@16 166 /// struct Bar
Chris@16 167 /// {};
Chris@16 168 ///
Chris@16 169 /// struct Foo
Chris@16 170 /// : proto::when<_, Bar<_>() >
Chris@16 171 /// {};
Chris@16 172 ///
Chris@16 173 /// proto::terminal<int>::type i = {0};
Chris@16 174 ///
Chris@16 175 /// int main()
Chris@16 176 /// {
Chris@16 177 /// Foo()(i);
Chris@16 178 /// std::cout << typeid(Foo()(i)).name() << std::endl;
Chris@16 179 /// }
Chris@16 180 /// \endcode
Chris@16 181 ///
Chris@16 182 /// If you actually wanted to default-construct an object of type
Chris@16 183 /// <tt>Bar\<_\></tt>, you would have to protect the \c _ to prevent
Chris@16 184 /// it from being applied. You can use <tt>proto::protect\<\></tt>
Chris@16 185 /// as follows:
Chris@16 186 ///
Chris@16 187 /// \code
Chris@16 188 /// // OK: replace anything with Bar<_>()
Chris@16 189 /// struct Foo
Chris@16 190 /// : proto::when<_, Bar<protect<_> >() >
Chris@16 191 /// {};
Chris@16 192 /// \endcode
Chris@16 193 template<typename PrimitiveTransform>
Chris@16 194 struct protect : transform<protect<PrimitiveTransform> >
Chris@16 195 {
Chris@16 196 template<typename, typename, typename>
Chris@16 197 struct impl
Chris@16 198 {
Chris@16 199 typedef PrimitiveTransform result_type;
Chris@16 200 };
Chris@16 201 };
Chris@16 202
Chris@16 203 /// \brief A PrimitiveTransform which computes a type by evaluating any
Chris@16 204 /// nested transforms and then constructs an object of that type.
Chris@16 205 ///
Chris@16 206 /// The <tt>make\<\></tt> transform checks to see if \c Object is a template.
Chris@16 207 /// If it is, the template type is disassembled to find nested transforms.
Chris@16 208 /// Proto considers the following types to represent transforms:
Chris@16 209 ///
Chris@16 210 /// \li Function types
Chris@16 211 /// \li Function pointer types
Chris@16 212 /// \li Types for which <tt>proto::is_callable\< type \>::value</tt> is \c true
Chris@16 213 ///
Chris@16 214 /// <tt>boost::result_of\<make\<T\<X0,X1,...\> \>(Expr, State, Data)\>::type</tt>
Chris@16 215 /// is evaluated as follows. For each \c X in <tt>X0,X1,...</tt>, do:
Chris@16 216 ///
Chris@16 217 /// \li If \c X is a template like <tt>U\<Y0,Y1,...\></tt>, then let <tt>X'</tt>
Chris@16 218 /// be <tt>boost::result_of\<make\<U\<Y0,Y1,...\> \>(Expr, State, Data)\>::type</tt>
Chris@16 219 /// (which evaluates this procedure recursively). Note whether any
Chris@16 220 /// substitutions took place during this operation.
Chris@16 221 /// \li Otherwise, if \c X is a transform, then let <tt>X'</tt> be
Chris@16 222 /// <tt>boost::result_of\<when\<_, X\>(Expr, State, Data)\>::type</tt>.
Chris@16 223 /// Note that a substitution took place.
Chris@16 224 /// \li Otherwise, let <tt>X'</tt> be \c X, and note that no substitution
Chris@16 225 /// took place.
Chris@16 226 /// \li If any substitutions took place in any of the above steps and
Chris@16 227 /// <tt>T\<X0',X1',...\></tt> has a nested <tt>::type</tt> typedef,
Chris@16 228 /// the result type is <tt>T\<X0',X1',...\>::type</tt>.
Chris@16 229 /// \li Otherwise, the result type is <tt>T\<X0',X1',...\></tt>.
Chris@16 230 ///
Chris@16 231 /// Note that <tt>when\<\></tt> is implemented in terms of <tt>call\<\></tt>
Chris@16 232 /// and <tt>make\<\></tt>, so the above procedure is evaluated recursively.
Chris@16 233 template<typename Object>
Chris@16 234 struct make : transform<make<Object> >
Chris@16 235 {
Chris@16 236 template<typename Expr, typename State, typename Data>
Chris@16 237 struct impl : transform_impl<Expr, State, Data>
Chris@16 238 {
Chris@16 239 typedef typename detail::make_if_<Object, Expr, State, Data>::type result_type;
Chris@16 240
Chris@16 241 /// \return <tt>result_type()</tt>
Chris@16 242 BOOST_FORCEINLINE
Chris@16 243 result_type operator ()(
Chris@16 244 typename impl::expr_param
Chris@16 245 , typename impl::state_param
Chris@16 246 , typename impl::data_param
Chris@16 247 ) const
Chris@16 248 {
Chris@16 249 return result_type();
Chris@16 250 }
Chris@16 251 };
Chris@16 252 };
Chris@16 253
Chris@16 254 /// INTERNAL ONLY
Chris@16 255 template<typename Fun>
Chris@16 256 struct make<detail::msvc_fun_workaround<Fun> >
Chris@16 257 : make<Fun>
Chris@16 258 {};
Chris@16 259
Chris@16 260 // Other specializations generated by the preprocessor.
Chris@16 261 #include <boost/proto/transform/detail/make.hpp>
Chris@16 262 #include <boost/proto/transform/detail/make_gcc_workaround.hpp>
Chris@16 263
Chris@16 264 /// INTERNAL ONLY
Chris@16 265 ///
Chris@16 266 template<typename Object>
Chris@16 267 struct is_callable<make<Object> >
Chris@16 268 : mpl::true_
Chris@16 269 {};
Chris@16 270
Chris@16 271 /// INTERNAL ONLY
Chris@16 272 ///
Chris@16 273 template<typename PrimitiveTransform>
Chris@16 274 struct is_callable<protect<PrimitiveTransform> >
Chris@16 275 : mpl::true_
Chris@16 276 {};
Chris@16 277
Chris@16 278 }}
Chris@16 279
Chris@101 280 #if defined(_MSC_VER)
Chris@16 281 # pragma warning(pop)
Chris@16 282 #endif
Chris@16 283
Chris@16 284 #endif