diff DEPENDENCIES/generic/include/boost/proto/transform/env.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/proto/transform/env.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,515 @@
+///////////////////////////////////////////////////////////////////////////////
+// env.hpp
+// Helpers for producing and consuming tranform env variables.
+//
+//  Copyright 2012 Eric Niebler. 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_PROTO_TRANSFORM_ENV_HPP_EAN_18_07_2012
+#define BOOST_PROTO_TRANSFORM_ENV_HPP_EAN_18_07_2012
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/ref.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/transform/impl.hpp>
+#include <boost/proto/detail/poly_function.hpp>
+#include <boost/proto/detail/is_noncopyable.hpp>
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4180) // qualifier applied to function type has no meaning; ignored
+#endif
+
+namespace boost
+{
+    namespace proto
+    {
+        namespace detail
+        {
+            template<typename T>
+            struct value_type
+            {
+                typedef typename remove_const<T>::type value;
+                typedef typename add_reference<T>::type reference;
+                typedef typename mpl::if_c<is_noncopyable<T>::value, reference, value>::type type;
+            };
+
+            template<typename T>
+            struct value_type<T &>
+            {
+                typedef T &value;
+                typedef T &reference;
+                typedef T &type;
+            };
+        }
+
+    #define BOOST_PROTO_DEFINE_ENV_VAR(TAG, NAME)                                                   \
+        struct TAG                                                                                  \
+        {                                                                                           \
+            template<typename Value>                                                                \
+            boost::proto::env<TAG, Value &> const                                                   \
+                operator =(boost::reference_wrapper<Value> &value) const                            \
+            {                                                                                       \
+                return boost::proto::env<TAG, Value &>(value.get());                                \
+            }                                                                                       \
+            template<typename Value>                                                                \
+            boost::proto::env<TAG, Value &> const                                                   \
+                operator =(boost::reference_wrapper<Value> const &value) const                      \
+            {                                                                                       \
+                return boost::proto::env<TAG, Value &>(value.get());                                \
+            }                                                                                       \
+            template<typename Value>                                                                \
+            typename boost::disable_if_c<                                                           \
+                boost::is_const<Value>::value                                                       \
+              , boost::proto::env<TAG, typename boost::proto::detail::value_type<Value>::type>      \
+            >::type const operator =(Value &value) const                                            \
+            {                                                                                       \
+                return boost::proto::env<TAG, typename boost::proto::detail::value_type<Value>::type>(value); \
+            }                                                                                       \
+            template<typename Value>                                                                \
+            boost::proto::env<TAG, typename boost::proto::detail::value_type<Value const>::type> const \
+                operator =(Value const &value) const                                                \
+            {                                                                                       \
+                return boost::proto::env<TAG, typename boost::proto::detail::value_type<Value const>::type>(value); \
+            }                                                                                       \
+        };                                                                                          \
+                                                                                                    \
+        TAG const NAME = {}                                                                         \
+        /**/
+
+        namespace envns_
+        {
+            ////////////////////////////////////////////////////////////////////////////////////////////
+            // env
+            // A transform env is a slot-based storage mechanism, accessible by tag.
+            template<typename Key, typename Value, typename Base /*= empty_env*/>
+            struct env
+              : private Base
+            {
+            private:
+                Value value_;
+
+            public:
+                typedef Value value_type;
+                typedef typename add_reference<Value>::type reference;
+                typedef typename add_reference<typename add_const<Value>::type>::type const_reference;
+                typedef void proto_environment_; ///< INTERNAL ONLY
+
+                explicit env(const_reference value, Base const &base = Base())
+                  : Base(base)
+                  , value_(value)
+                {}
+
+                #if BOOST_WORKAROUND(__GNUC__, == 3) || (BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ <= 2)
+                /// INTERNAL ONLY
+                struct found
+                {
+                    typedef Value type;
+                    typedef typename add_reference<typename add_const<Value>::type>::type const_reference;
+                };
+
+                template<typename OtherKey, typename OtherValue = key_not_found>
+                struct lookup
+                  : mpl::if_c<
+                        is_same<OtherKey, Key>::value
+                      , found
+                      , typename Base::template lookup<OtherKey, OtherValue>
+                    >::type
+                {};
+                #else
+                /// INTERNAL ONLY
+                template<typename OtherKey, typename OtherValue = key_not_found>
+                struct lookup
+                  : Base::template lookup<OtherKey, OtherValue>
+                {};
+
+                /// INTERNAL ONLY
+                template<typename OtherValue>
+                struct lookup<Key, OtherValue>
+                {
+                    typedef Value type;
+                    typedef typename add_reference<typename add_const<Value>::type>::type const_reference;
+                };
+                #endif
+
+                // For key-based lookups not intended to fail
+                using Base::operator[];
+                const_reference operator[](Key) const
+                {
+                    return this->value_;
+                }
+
+                // For key-based lookups that can fail, use the default if key not found.
+                using Base::at;
+                template<typename T>
+                const_reference at(Key, T const &) const
+                {
+                    return this->value_;
+                }
+            };
+
+            // define proto::data_type type and proto::data global
+            BOOST_PROTO_DEFINE_ENV_VAR(data_type, data);
+        }
+
+        using envns_::data;
+
+        namespace functional
+        {
+            ////////////////////////////////////////////////////////////////////////////////////////
+            // as_env
+            struct as_env
+            {
+                BOOST_PROTO_CALLABLE()
+                BOOST_PROTO_POLY_FUNCTION()
+
+                /// INTERNAL ONLY
+                template<typename T, bool B = is_env<T>::value>
+                struct impl
+                {
+                    typedef env<data_type, typename detail::value_type<T>::type> result_type;
+
+                    result_type const operator()(detail::arg<T> t) const
+                    {
+                        return result_type(t());
+                    }
+                };
+
+                /// INTERNAL ONLY
+                template<typename T>
+                struct impl<T, true>
+                {
+                    typedef T result_type;
+
+                    typename add_const<T>::type operator()(detail::arg<T> t) const
+                    {
+                        return t();
+                    }
+                };
+
+                template<typename Sig>
+                struct result;
+
+                template<typename This, typename T>
+                struct result<This(T)>
+                {
+                    typedef typename impl<typename detail::normalize_arg<T>::type>::result_type type;
+                };
+
+                template<typename T>
+                typename impl<typename detail::normalize_arg<T &>::type>::result_type const
+                    operator()(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T)) const
+                {
+                    return impl<typename detail::normalize_arg<T &>::type>()(
+                        static_cast<typename detail::normalize_arg<T &>::reference>(t)
+                    );
+                }
+
+                template<typename T>
+                typename impl<typename detail::normalize_arg<T const &>::type>::result_type const
+                    operator()(T const &t) const
+                {
+                    return impl<typename detail::normalize_arg<T const &>::type>()(
+                        static_cast<typename detail::normalize_arg<T const &>::reference>(t)
+                    );
+                }
+            };
+
+            ////////////////////////////////////////////////////////////////////////////////////////
+            // has_env_var
+            template<typename Key>
+            struct has_env_var
+              : detail::poly_function<has_env_var<Key> >
+            {
+                BOOST_PROTO_CALLABLE()
+
+                template<typename Env, bool IsEnv = is_env<Env>::value>
+                struct impl
+                {
+                    typedef
+                        mpl::not_<
+                            is_same<
+                                typename remove_reference<Env>::type::template lookup<Key>::type
+                              , key_not_found
+                            >
+                        >
+                    result_type;
+
+                    result_type operator()(detail::arg<Env>) const
+                    {
+                        return result_type();
+                    }
+                };
+
+                template<typename Env>
+                struct impl<Env, false>
+                {
+                    typedef mpl::false_ result_type;
+
+                    result_type operator()(detail::arg<Env>) const
+                    {
+                        return result_type();
+                    }
+                };
+            };
+
+            template<>
+            struct has_env_var<data_type>
+              : detail::poly_function<has_env_var<data_type> >
+            {
+                BOOST_PROTO_CALLABLE()
+
+                template<typename Env, bool IsEnv = is_env<Env>::value>
+                struct impl
+                {
+                    typedef
+                        mpl::not_<
+                            is_same<
+                                typename remove_reference<Env>::type::template lookup<data_type>::type
+                              , key_not_found
+                            >
+                        >
+                    result_type;
+
+                    result_type operator()(detail::arg<Env>) const
+                    {
+                        return result_type();
+                    }
+                };
+
+                template<typename Env>
+                struct impl<Env, false>
+                {
+                    typedef mpl::true_ result_type;
+
+                    result_type operator()(detail::arg<Env>) const
+                    {
+                        return result_type();
+                    }
+                };
+            };
+
+            ////////////////////////////////////////////////////////////////////////////////////////
+            // env_var
+            template<typename Key>
+            struct env_var
+              : detail::poly_function<env_var<Key> >
+            {
+                BOOST_PROTO_CALLABLE()
+
+                template<typename Env>
+                struct impl
+                {
+                    typedef
+                        typename remove_reference<Env>::type::template lookup<Key>::type
+                    result_type;
+
+                    result_type operator()(detail::arg<Env> e) const
+                    {
+                        return e()[Key()];
+                    }
+                };
+            };
+
+            template<>
+            struct env_var<data_type>
+              : detail::poly_function<env_var<data_type> >
+            {
+                BOOST_PROTO_CALLABLE()
+
+                template<typename Env, bool B = is_env<Env>::value>
+                struct impl
+                {
+                    typedef Env result_type;
+
+                    result_type operator()(detail::arg<Env> e) const
+                    {
+                        return e();
+                    }
+                };
+
+                template<typename Env>
+                struct impl<Env, true>
+                {
+                    typedef
+                        typename remove_reference<Env>::type::template lookup<data_type>::type
+                    result_type;
+
+                    result_type operator()(detail::arg<Env> e) const
+                    {
+                        return e()[proto::data];
+                    }
+                };
+            };
+        }
+
+        namespace result_of
+        {
+            template<typename T>
+            struct as_env
+              : BOOST_PROTO_RESULT_OF<functional::as_env(T)>
+            {};
+
+            template<typename Env, typename Key>
+            struct has_env_var
+              : BOOST_PROTO_RESULT_OF<functional::has_env_var<Key>(Env)>::type
+            {};
+
+            template<typename Env, typename Key>
+            struct env_var
+              : BOOST_PROTO_RESULT_OF<functional::env_var<Key>(Env)>
+            {};
+        }
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // as_env
+        template<typename T>
+        typename proto::result_of::as_env<T &>::type const as_env(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T))
+        {
+            return proto::functional::as_env()(t);
+        }
+
+        template<typename T>
+        typename proto::result_of::as_env<T const &>::type const as_env(T const &t)
+        {
+            return proto::functional::as_env()(t);
+        }
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // has_env_var
+        template<typename Key, typename Env>
+        typename proto::result_of::has_env_var<Env &, Key>::type has_env_var(Env &e BOOST_PROTO_DISABLE_IF_IS_CONST(Env))
+        {
+            return functional::has_env_var<Key>()(e);
+        }
+
+        template<typename Key, typename Env>
+        typename proto::result_of::has_env_var<Env const &, Key>::type has_env_var(Env const &e)
+        {
+            return functional::has_env_var<Key>()(e);
+        }
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // env_var
+        template<typename Key, typename Env>
+        typename proto::result_of::env_var<Env &, Key>::type env_var(Env &e BOOST_PROTO_DISABLE_IF_IS_CONST(Env))
+        {
+            return functional::env_var<Key>()(e);
+        }
+
+        template<typename Key, typename Env>
+        typename proto::result_of::env_var<Env const &, Key>::type env_var(Env const &e)
+        {
+            return functional::env_var<Key>()(e);
+        }
+
+        namespace envns_
+        {
+            ////////////////////////////////////////////////////////////////////////////////////////
+            // env operator,
+            template<typename T, typename T1, typename V1>
+            inline typename disable_if_c<
+                is_const<T>::value
+              , env<T1, V1, BOOST_PROTO_UNCVREF(typename result_of::as_env<T &>::type)>
+            >::type const operator,(T &t, env<T1, V1> const &head)
+            {
+                return env<T1, V1, BOOST_PROTO_UNCVREF(typename result_of::as_env<T &>::type)>(
+                    head[T1()]
+                  , proto::as_env(t)
+                );
+            }
+
+            template<typename T, typename T1, typename V1>
+            inline env<T1, V1, BOOST_PROTO_UNCVREF(typename result_of::as_env<T const &>::type)> const
+                operator,(T const &t, env<T1, V1> const &head)
+            {
+                return env<T1, V1, BOOST_PROTO_UNCVREF(typename result_of::as_env<T const &>::type)>(
+                    head[T1()]
+                  , proto::as_env(t)
+                );
+            }
+        }
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // _env_var
+        template<typename Key>
+        struct _env_var
+          : proto::transform<_env_var<Key> >
+        {
+            template<typename Expr, typename State, typename Data>
+            struct impl
+              : transform_impl<Expr, State, Data>
+            {
+                typedef typename impl::data::template lookup<Key>::type result_type;
+                BOOST_MPL_ASSERT_NOT((is_same<result_type, key_not_found>)); // lookup failed
+
+                BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::data::template lookup<Key>::const_reference)
+                operator ()(
+                    typename impl::expr_param
+                  , typename impl::state_param
+                  , typename impl::data_param d
+                ) const
+                {
+                    return d[Key()];
+                }
+            };
+        };
+
+        struct _env
+          : transform<_env>
+        {
+            template<typename Expr, typename State, typename Data>
+            struct impl
+              : transform_impl<Expr, State, Data>
+            {
+                typedef Data result_type;
+
+                BOOST_PROTO_RETURN_TYPE_STRICT_LOOSE(result_type, typename impl::data_param)
+                operator ()(
+                    typename impl::expr_param
+                  , typename impl::state_param
+                  , typename impl::data_param d
+                ) const
+                {
+                    return d;
+                }
+            };
+        };
+
+        /// INTERNAL ONLY
+        template<typename Key>
+        struct is_callable<_env_var<Key> >
+          : mpl::true_
+        {};
+
+        /// INTERNAL ONLY
+        template<typename Key>
+        struct is_callable<functional::has_env_var<Key> >
+          : mpl::true_
+        {};
+
+        /// INTERNAL ONLY
+        template<typename Key>
+        struct is_callable<functional::env_var<Key> >
+          : mpl::true_
+        {};
+    }
+}
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+#endif