diff options
author | Kevin Smith <git@kismith.co.uk> | 2013-01-12 18:41:34 (GMT) |
---|---|---|
committer | Swift Review <review@swift.im> | 2013-01-13 10:36:26 (GMT) |
commit | f3bc816af1b0d61452de973963e453bf3b3f95a2 (patch) | |
tree | e895f8afa3580e6cff6f5ad2017d45bf147a17c2 /3rdParty/Boost/src/boost/spirit/home/phoenix/detail | |
parent | 188fc285c6555eadd3c9d50ab8a94adcade78d89 (diff) | |
download | swift-f3bc816af1b0d61452de973963e453bf3b3f95a2.zip swift-f3bc816af1b0d61452de973963e453bf3b3f95a2.tar.bz2 |
Adding in the spirit Boost stuff
Change-Id: I4f127ce61667243b64081b0aa309028d5077045f
Diffstat (limited to '3rdParty/Boost/src/boost/spirit/home/phoenix/detail')
-rw-r--r-- | 3rdParty/Boost/src/boost/spirit/home/phoenix/detail/local_reference.hpp | 44 | ||||
-rw-r--r-- | 3rdParty/Boost/src/boost/spirit/home/phoenix/detail/type_deduction.hpp | 497 |
2 files changed, 541 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/spirit/home/phoenix/detail/local_reference.hpp b/3rdParty/Boost/src/boost/spirit/home/phoenix/detail/local_reference.hpp new file mode 100644 index 0000000..ad1fdb4 --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/phoenix/detail/local_reference.hpp @@ -0,0 +1,44 @@ +/*============================================================================= + Copyright (c) 2005-2007 Joel de Guzman + + 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 PHOENIX_DETAIL_LOCAL_REFERENCE_HPP +#define PHOENIX_DETAIL_LOCAL_REFERENCE_HPP + +#include <boost/utility/addressof.hpp> + +namespace boost { namespace phoenix { namespace detail +{ + template <typename T> + struct local_reference + { + typedef T type; + + explicit local_reference(T& t): t_(boost::addressof(t)) {} + operator T& () const { return *t_; } + local_reference& operator=(T const& x) { *t_ = x; return *this; } + local_reference const& operator=(T const& x) const { *t_ = x; return *this; } + T& get() const { return *t_; } + T* get_pointer() const { return t_; } + + private: + + T* t_; + }; + + template <typename T> + struct unwrap_local_reference + { + typedef T type; // T should be a reference + }; + + template <typename T> + struct unwrap_local_reference<local_reference<T> > + { + typedef T type; // unwrap the reference; T is a value + }; +}}} + +#endif diff --git a/3rdParty/Boost/src/boost/spirit/home/phoenix/detail/type_deduction.hpp b/3rdParty/Boost/src/boost/spirit/home/phoenix/detail/type_deduction.hpp new file mode 100644 index 0000000..b99ea1e --- /dev/null +++ b/3rdParty/Boost/src/boost/spirit/home/phoenix/detail/type_deduction.hpp @@ -0,0 +1,497 @@ +/*============================================================================= + Copyright (c) 2001-2007 Joel de Guzman + + 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 PHOENIX_DETAIL_TYPE_DEDUCTION_HPP +#define PHOENIX_DETAIL_TYPE_DEDUCTION_HPP + +/*============================================================================= + + Return Type Deduction + [JDG Sept. 15, 2003] + + Before C++ adopts the typeof, there is currently no way to deduce the + result type of an expression such as x + y. This deficiency is a major + problem with template metaprogramming; for example, when writing + forwarding functions that attempt to capture the essence of an + expression inside a function. Consider the std::plus<T>: + + template <typename T> + struct plus : public binary_function<T, T, T> + { + T operator()(T const& x, T const& y) const + { + return x + y; + } + }; + + What's wrong with this? Well, this functor does not accurately capture + the behavior of the plus operator. 1) It does not handle the case where + x and y are of different types (e.g. x is short and y is int). 2) It + assumes that the arguments and return type are the same (i.e. when + adding a short and an int, the return type ought to be an int). Due to + these shortcomings, std::plus<T>(x, y) is a poor substitute for x + y. + + The case where x is short and y is int does not really expose the + problem. We can simply use std::plus<int> and be happy that the + operands x and y will simply be converted to an int. The problem + becomes evident when an operand is a user defined type such as bigint. + Here, the conversion to bigint is simply not acceptable. Even if the + unnecessary conversion is tolerable, in generic code, it is not always + possible to choose the right T type that can accomodate both x and y + operands. + + To truly model the plus operator, what we need is a polymorphic functor + that can take arbitrary x and y operands. Here's a rough schematic: + + struct plus + { + template <typename X, typename Y> + unspecified-type + operator()(X const& x, Y const& y) const + { + return x + y; + } + }; + + Now, we can handle the case where X and Y are arbitrary types. We've + solved the first problem. To solve the second problem, we need some + form of return type deduction mechanism. If we had the typeof, it would + be something like: + + template <typename X, typename Y> + typeof(X() + Y()) + operator()(X const& x, Y const& y) const + { + return x + y; + } + + Without the typeof facility, it is only possible to wrap an expression + such as x + y in a function or functor if we are given a hint that + tells us what the actual result type of such an expression is. Such a + hint can be in the form of a metaprogram, that, given the types of the + arguments, will return the result type. Example: + + template <typename X, typename Y> + struct result_of_plus + { + typedef unspecified-type type; + }; + + Given a result_of_plus metaprogram, we can complete our polymorphic + plus functor: + + struct plus + { + template <typename X, typename Y> + typename result_of_plus<X, Y>::type + operator()(X const& x, Y const& y) const + { + return x + y; + } + }; + + The process is not automatic. We have to specialize the metaprogram for + specific argument types. Examples: + + template <> + struct result_of_plus<short, int> + { + typedef int type; + }; + + template <typename T> + struct result_of_plus<std::complex<T>, std::complex<T> > + { + typedef std::complex<T> type; + }; + + To make it easier for the user, specializations are provided for common + types such as primitive c++ types (e.g. int, char, double, etc.), and + standard types (e.g. std::complex, iostream, std containers and + iterators). + + To further improve the ease of use, for user defined classes, we can + supply a few more basic specializations through metaprogramming using + heuristics based on canonical operator rules (Such heuristics can be + found in the LL and Phoenix, for example). For example, it is rather + common that the result of x += y is X& or the result of x || y is a + bool. The client is out of luck if her classes do not follow the + canonical rules. She'll then have to supply her own specialization. + + The type deduction mechanism demostrated below approaches the problem + not through specialization and heuristics, but through a limited form + of typeof mechanism. The code does not use heuristics, hence, no + guessing games. The code takes advantage of the fact that, in general, + the result type of an expression is related to one its arguments' type. + For example, x + y, where x has type int and y has type double, has the + result type double (the second operand type). Another example, x[y] + where x is a vector<T> and y is a std::size_t, has the result type + vector<T>::reference (the vector<T>'s reference type type). + + The limited form of type deduction presented can detect common + relations if the result of a binary or unary operation, given arguments + x and y with types X and Y (respectively), is X, Y, X&, Y&, X*, Y*, X + const*, Y const*, bool, int, unsigned, double, container and iterator + elements (e.g the T, where X is: T[N], T*, vector<T>, map<T>, + vector<T>::iterator). More arguments/return type relationships can be + established if needed. + + A set of overloaded test(T) functions capture these argument related + types. Each test(T) function returns a distinct type that can be used + to determine the exact type of an expression. + + Consider: + + template <typename X, typename Y> + x_value_type + test(X const&); + + template <typename X, typename Y> + y_value_type + test(Y const&); + + Given an expression x + y, where x is int and y is double, the call to: + + test<int, double>(x + y) + + will return a y_value_type. + + Now, if we rig x_value_type and y_value_type such that both have unique + sizes, we can use sizeof(test<X, Y>(x + y)) to determine if the result + type is either X or Y. + + For example, if: + + sizeof(test<X, Y>(x + y)) == sizeof(y_value_type) + + then, we know for sure that the result of x + y has type Y. + + The same basic scheme can be used to detect more argument-dependent + return types where the sizeof the test(T) return type is used to index + through a boost::mpl vector which holds each of the corresponding + result types. + +==============================================================================*/ +#include <boost/mpl/vector/vector20.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/not.hpp> +#include <boost/mpl/or.hpp> +#include <boost/mpl/and.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/type_traits/add_reference.hpp> +#include <boost/type_traits/remove_cv.hpp> +#include <boost/type_traits/is_const.hpp> +#include <boost/type_traits/is_reference.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/is_array.hpp> +#include <boost/type_traits/is_pointer.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/static_assert.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/spirit/home/phoenix/detail/local_reference.hpp> + +namespace boost +{ + struct error_cant_deduce_type {}; +} + +namespace boost { namespace type_deduction_detail +{ + typedef char(&bool_value_type)[1]; + typedef char(&int_value_type)[2]; + typedef char(&uint_value_type)[3]; + typedef char(&double_value_type)[4]; + + typedef char(&bool_reference_type)[5]; + typedef char(&int_reference_type)[6]; + typedef char(&uint_reference_type)[7]; + typedef char(&double_reference_type)[8]; + + typedef char(&x_value_type)[9]; + typedef char(&x_reference_type)[10]; + typedef char(&x_const_pointer_type)[11]; + typedef char(&x_pointer_type)[12]; + + typedef char(&y_value_type)[13]; + typedef char(&y_reference_type)[14]; + typedef char(&y_const_pointer_type)[15]; + typedef char(&y_pointer_type)[16]; + + typedef char(&container_reference_type)[17]; + typedef char(&container_const_reference_type)[18]; + typedef char(&container_mapped_type)[19]; + + typedef char(&cant_deduce_type)[20]; + + template <typename T, typename Plain = typename remove_cv<T>::type> + struct is_basic + : mpl::or_< + is_same<Plain, bool> + , is_same<Plain, int> + , is_same<Plain, unsigned> + , is_same<Plain, double> + > {}; + + template <typename C> + struct reference_type + { + typedef typename C::reference type; + }; + + template <typename T> + struct reference_type<T const> + : reference_type<T> {}; + + template <typename T, std::size_t N> + struct reference_type<T[N]> + { + typedef T& type; + }; + + template <typename T> + struct reference_type<T*> + { + typedef T& type; + }; + + template <typename T> + struct reference_type<T* const> + { + typedef T const& type; + }; + + template <typename C> + struct const_reference_type + { + typedef typename C::const_reference type; + }; + + template <typename C> + struct mapped_type + { + typedef typename C::mapped_type type; + }; + + struct asymmetric; + + template <typename X, typename Y> + cant_deduce_type + test(...); // The black hole !!! + + template <typename X, typename Y> + bool_value_type + test(bool const&); + + template <typename X, typename Y> + int_value_type + test(int const&); + + template <typename X, typename Y> + uint_value_type + test(unsigned const&); + + template <typename X, typename Y> + double_value_type + test(double const&); + + template <typename X, typename Y> + bool_reference_type + test(bool&); + + template <typename X, typename Y> + int_reference_type + test(int&); + + template <typename X, typename Y> + uint_reference_type + test(unsigned&); + + template <typename X, typename Y> + double_reference_type + test(double&); + + template <typename X, typename Y> + typename disable_if< + mpl::or_<is_basic<X>, is_const<X> > + , x_value_type + >::type + test(X const&); + + template <typename X, typename Y> + typename disable_if< + is_basic<X> + , x_reference_type + >::type + test(X&); + + template <typename X, typename Y> + typename disable_if< + mpl::or_< + is_basic<X> + , is_const<X> + > + , x_const_pointer_type + >::type + test(X const*); + + template <typename X, typename Y> + x_pointer_type + test(X*); + + template <typename X, typename Y> + typename disable_if< + mpl::or_< + is_basic<Y> + , is_same<Y, asymmetric> + , is_const<Y> + , is_same<X, Y> + > + , y_value_type + >::type + test(Y const&); + + template <typename X, typename Y> + typename disable_if< + mpl::or_< + is_basic<Y> + , is_same<Y, asymmetric> + , is_same<X, Y> + > + , y_reference_type + >::type + test(Y&); + + template <typename X, typename Y> + typename disable_if< + mpl::or_< + is_same<Y, asymmetric> + , is_const<Y> + , is_same<X, Y> + > + , y_const_pointer_type + >::type + test(Y const*); + + template <typename X, typename Y> + typename disable_if< + mpl::or_< + is_same<Y, asymmetric> + , is_same<X, Y> + > + , y_pointer_type + >::type + test(Y*); + + template <typename X, typename Y> + typename disable_if< + mpl::or_< + is_basic<typename X::value_type> + , is_same<typename add_reference<X>::type, typename X::reference> + > + , container_reference_type + >::type + test(typename X::reference); + + template <typename X, typename Y, typename Z> + typename enable_if< + mpl::and_< + mpl::or_<is_array<X>, is_pointer<X> > + , mpl::not_<is_basic<Z> > + , mpl::not_<is_same<X, Z> > + > + , container_reference_type + >::type + test(Z&); + + template <typename X, typename Y> + typename disable_if< + mpl::or_< + is_basic<typename X::value_type> + , is_same<typename add_reference<X>::type, typename X::const_reference> + > + , container_const_reference_type + >::type + test(typename X::const_reference); + + template <typename X, typename Y> + typename disable_if< + is_basic<typename X::mapped_type> + , container_mapped_type + >::type + test(typename X::mapped_type); + + template <typename X, typename Y> + struct base_result_of + { + typedef typename phoenix::detail::unwrap_local_reference<X>::type x_type_; + typedef typename phoenix::detail::unwrap_local_reference<Y>::type y_type_; + typedef typename remove_reference<x_type_>::type x_type; + typedef typename remove_reference<y_type_>::type y_type; + + typedef mpl::vector20< + mpl::identity<bool> + , mpl::identity<int> + , mpl::identity<unsigned> + , mpl::identity<double> + , mpl::identity<bool&> + , mpl::identity<int&> + , mpl::identity<unsigned&> + , mpl::identity<double&> + , mpl::identity<x_type> + , mpl::identity<x_type&> + , mpl::identity<x_type const*> + , mpl::identity<x_type*> + , mpl::identity<y_type> + , mpl::identity<y_type&> + , mpl::identity<y_type const*> + , mpl::identity<y_type*> + , reference_type<x_type> + , const_reference_type<x_type> + , mapped_type<x_type> + , mpl::identity<error_cant_deduce_type> + > + types; + }; + +}} // namespace boost::type_deduction_detail + +#define BOOST_RESULT_OF_COMMON(expr, name, Y, SYMMETRY) \ + struct name \ + { \ + typedef type_deduction_detail::base_result_of<X, Y> base_type; \ + static typename base_type::x_type x; \ + static typename base_type::y_type y; \ + \ + BOOST_STATIC_CONSTANT(int, \ + size = sizeof( \ + type_deduction_detail::test< \ + typename base_type::x_type \ + , SYMMETRY \ + >(expr) \ + )); \ + \ + BOOST_STATIC_CONSTANT(int, index = (size / sizeof(char)) - 1); \ + \ + typedef typename mpl::at_c< \ + typename base_type::types, index>::type id; \ + typedef typename id::type type; \ + }; + +#define BOOST_UNARY_RESULT_OF(expr, name) \ + template <typename X> \ + BOOST_RESULT_OF_COMMON(expr, name, \ + type_deduction_detail::asymmetric, type_deduction_detail::asymmetric) + +#define BOOST_BINARY_RESULT_OF(expr, name) \ + template <typename X, typename Y> \ + BOOST_RESULT_OF_COMMON(expr, name, Y, typename base_type::y_type) + +#define BOOST_ASYMMETRIC_BINARY_RESULT_OF(expr, name) \ + template <typename X, typename Y> \ + BOOST_RESULT_OF_COMMON(expr, name, Y, type_deduction_detail::asymmetric) + +#endif |