From a993802fcf439e088a6acffabc32b79965c38c6a Mon Sep 17 00:00:00 2001 From: Tobias Schwinger Date: Thu, 27 Nov 2008 15:14:40 +0000 Subject: [PATCH 01/82] introduces functional/ forward & factory [SVN r49956] --- include/boost/functional/factory.hpp | 163 ++++++ include/boost/functional/forward_adapter.hpp | 473 ++++++++++++++++++ .../lightweight_forward_adapter.hpp | 258 ++++++++++ include/boost/functional/value_factory.hpp | 70 +++ 4 files changed, 964 insertions(+) create mode 100644 include/boost/functional/factory.hpp create mode 100644 include/boost/functional/forward_adapter.hpp create mode 100644 include/boost/functional/lightweight_forward_adapter.hpp create mode 100644 include/boost/functional/value_factory.hpp diff --git a/include/boost/functional/factory.hpp b/include/boost/functional/factory.hpp new file mode 100644 index 0000000..d97fea5 --- /dev/null +++ b/include/boost/functional/factory.hpp @@ -0,0 +1,163 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are subject to 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_FUNCTIONAL_FACTORY_HPP_INCLUDED +# ifndef BOOST_PP_IS_ITERATING + +# include +# include +# include + +# include +# include +# include +# include +# include +# include + +# ifndef BOOST_FUNCTIONAL_FACTORY_MAX_ARITY +# define BOOST_FUNCTIONAL_FACTORY_MAX_ARITY 10 +# elif BOOST_FUNCTIONAL_FACTORY_MAX_ARITY < 3 +# undef BOOST_FUNCTIONAL_FACTORY_MAX_ARITY +# define BOOST_FUNCTIONAL_FACTORY_MAX_ARITY 3 +# endif + +namespace boost +{ + enum factory_alloc_propagation + { + factory_alloc_for_pointee_and_deleter, + factory_passes_alloc_to_smart_pointer + }; + + template< typename Pointer, class Allocator = boost::none_t, + factory_alloc_propagation AP = factory_alloc_for_pointee_and_deleter > + class factory; + + //----- ---- --- -- - - - - + + template< typename Pointer > + class factory + { + public: + typedef typename boost::remove_cv::type result_type; + typedef typename boost::pointee::type value_type; + + factory() + { } + +# define BOOST_PP_FILENAME_1 +# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_FACTORY_MAX_ARITY) +# include BOOST_PP_ITERATE() + }; + + template< class Pointer, class Allocator, factory_alloc_propagation AP > + class factory + : Allocator::template rebind< typename boost::pointee< + typename boost::remove_cv::type >::type >::other + { + public: + typedef typename boost::remove_cv::type result_type; + typedef typename boost::pointee::type value_type; + + typedef typename Allocator::template rebind::other + allocator_type; + + explicit factory(allocator_type const & a = allocator_type()) + : allocator_type(a) + { } + + private: + + struct deleter + : allocator_type + { + inline deleter(allocator_type const& that) + : allocator_type(that) + { } + + allocator_type& get_allocator() const + { + return *const_cast( + static_cast(this)); + } + + void operator()(value_type* ptr) const + { + if (!! ptr) ptr->~value_type(); + const_cast(static_cast( + this))->deallocate(ptr,1); + } + }; + + inline allocator_type& get_allocator() const + { + return *const_cast( + static_cast(this)); + } + + inline result_type make_pointer(value_type* ptr, boost::non_type< + factory_alloc_propagation,factory_passes_alloc_to_smart_pointer>) + const + { + return result_type(ptr,deleter(this->get_allocator())); + } + inline result_type make_pointer(value_type* ptr, boost::non_type< + factory_alloc_propagation,factory_alloc_for_pointee_and_deleter>) + const + { + return result_type(ptr,deleter(this->get_allocator()), + this->get_allocator()); + } + + public: + +# define BOOST_TMP_MACRO +# define BOOST_PP_FILENAME_1 +# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_FACTORY_MAX_ARITY) +# include BOOST_PP_ITERATE() +# undef BOOST_TMP_MACRO + }; + + template< typename Pointer, class Allocator > + class factory; + // forbidden, would create a dangling reference +} + +# define BOOST_FUNCTIONAL_FACTORY_HPP_INCLUDED +# else // defined(BOOST_PP_IS_ITERATING) +# define N BOOST_PP_ITERATION() +# if !defined(BOOST_TMP_MACRO) +# if N > 0 + template< BOOST_PP_ENUM_PARAMS(N, typename T) > +# endif + inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const + { + return result_type( new value_type(BOOST_PP_ENUM_PARAMS(N,a)) ); + } +# else // defined(BOOST_TMP_MACRO) +# if N > 0 + template< BOOST_PP_ENUM_PARAMS(N, typename T) > +# endif + inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const + { + value_type* memory = this->get_allocator().allocate(1); + try + { + return make_pointer( + new(memory) value_type(BOOST_PP_ENUM_PARAMS(N,a)), + boost::non_type() ); + } + catch (...) { this->get_allocator().deallocate(memory,1); throw; } + } +# endif +# undef N +# endif // defined(BOOST_PP_IS_ITERATING) + +#endif // include guard + diff --git a/include/boost/functional/forward_adapter.hpp b/include/boost/functional/forward_adapter.hpp new file mode 100644 index 0000000..473b2a2 --- /dev/null +++ b/include/boost/functional/forward_adapter.hpp @@ -0,0 +1,473 @@ +/*============================================================================= + Copyright (c) 2007-2008 Tobias Schwinger + + Use modification and distribution are subject to 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_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED +# ifndef BOOST_PP_IS_ITERATING + +# include +# include + +# include +# include +# include +# include +# include + +# include + +# ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY +# define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 6 +# elif BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY < 3 +# undef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY +# define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 3 +# endif + + +namespace boost +{ + template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 > + class forward_adapter; + + //----- ---- --- -- - - - - + + namespace detail + { + template< class MostDerived, typename Function, typename FunctionConst, + int Arity, int MinArity > + struct forward_adapter_impl; + + struct forward_adapter_result + { + template< typename Sig > struct apply; + + private: + // Utility metafunction for qualification adjustment on arguments + template< typename T > struct q { typedef T const t; }; + template< typename T > struct q { typedef T const t; }; + template< typename T > struct q { typedef T t; }; + + // Utility metafunction to choose target function qualification + template< typename T > struct c + { typedef typename T::target_function_t t; }; + template< typename T > struct c + { typedef typename T::target_function_t t; }; + template< typename T > struct c + { typedef typename T::target_function_const_t t; }; + template< typename T > struct c + { typedef typename T::target_function_const_t t; }; + }; + } + +# define BOOST_TMP_MACRO(f,fn,fc) \ + boost::detail::forward_adapter_impl< \ + forward_adapter, fn, fc, \ + (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \ + :BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY), \ + (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) > + + template< typename Function, int Arity_Or_MinArity, int MaxArity > + class forward_adapter + : public BOOST_TMP_MACRO(Function,Function,Function const) + , Function + { + public: + forward_adapter(Function const& f = Function()) + : Function(f) + { } + + typedef Function target_function_t; + typedef Function const target_function_const_t; + + Function & target_function() { return *this; } + Function const & target_function() const { return *this; } + + template< typename Sig > struct result + : detail::forward_adapter_result::template apply + { }; + + using BOOST_TMP_MACRO(Function,Function, Function const)::operator(); + }; + template< typename Function, int Arity_Or_MinArity, int MaxArity > + class forward_adapter< Function const, Arity_Or_MinArity, MaxArity > + : public BOOST_TMP_MACRO(Function const, Function const, Function const) + , Function + { + public: + forward_adapter(Function const& f = Function()) + : Function(f) + { } + + typedef Function const target_function_t; + typedef Function const target_function_const_t; + + Function const & target_function() const { return *this; } + + template< typename Sig > struct result + : detail::forward_adapter_result::template apply + { }; + + using BOOST_TMP_MACRO(Function const,Function const, Function const) + ::operator(); + }; + template< typename Function, int Arity_Or_MinArity, int MaxArity > + class forward_adapter< Function &, Arity_Or_MinArity, MaxArity > + : public BOOST_TMP_MACRO(Function&, Function, Function) + { + Function& ref_function; + public: + forward_adapter(Function& f) + : ref_function(f) + { } + + typedef Function target_function_t; + typedef Function target_function_const_t; + + Function & target_function() const { return this->ref_function; } + + template< typename Sig > struct result + : detail::forward_adapter_result::template apply + { }; + + using BOOST_TMP_MACRO(Function&, Function, Function)::operator(); + }; + + #undef BOOST_TMP_MACRO + + namespace detail + { + template< class Self > + struct forward_adapter_result::apply< Self() > + : boost::result_of< typename c::t() > + { }; + + template< class MD, class F, class FC > + struct forward_adapter_impl + { + inline typename boost::result_of< FC() >::type + operator()() const + { + return static_cast(this)->target_function()(); + } + + inline typename boost::result_of< F() >::type + operator()() + { + return static_cast(this)->target_function()(); + } + + // closing brace gets generated by preprocessing code, below + +# define BOOST_TMP_MACRO(tpl_params,arg_types,params,args) \ + template< tpl_params > \ + inline typename boost::result_of< FC(arg_types) >::type \ + operator()(params) const \ + { \ + return static_cast(this)->target_function()(args); \ + } \ + template< tpl_params > \ + inline typename boost::result_of< F(arg_types)>::type \ + operator()(params) \ + { \ + return static_cast(this)->target_function()(args); \ + } + +# // This is the total number of iterations we need +# define count ((1 << BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY+1)-2) + +# // Chain file iteration to virtually one loop +# if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 7 +# define limit1 count +# define limit2 0 +# define limit3 0 +# else +# if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 15 +# define limit1 (count >> 8) +# define limit2 255 +# define limit3 0 +# else +# define limit1 (count >> 16) +# define limit2 255 +# define limit3 255 +# endif +# endif + +# define N 0 + +# define BOOST_PP_FILENAME_1 +# define BOOST_PP_ITERATION_LIMITS (0,limit1) +# include BOOST_PP_ITERATE() + +# undef N +# undef limit3 +# undef limit2 +# undef limit1 +# undef count +# undef BOOST_TMP_MACRO + + }; + + } // namespace detail + + template + struct result_of const ()> + : boost::detail::forward_adapter_result::template apply< + boost::forward_adapter const () > + { }; + template + struct result_of()> + : boost::detail::forward_adapter_result::template apply< + boost::forward_adapter() > + { }; + template + struct result_of const& ()> + : boost::detail::forward_adapter_result::template apply< + boost::forward_adapter const () > + { }; + template + struct result_of& ()> + : boost::detail::forward_adapter_result::template apply< + boost::forward_adapter() > + { }; +} + +# define BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED + +# elif BOOST_PP_ITERATION_DEPTH() == 1 && limit2 +# define BOOST_PP_FILENAME_2 +# define BOOST_PP_ITERATION_LIMITS (0,limit2) +# include BOOST_PP_ITERATE() +# elif BOOST_PP_ITERATION_DEPTH() == 2 && limit3 +# define BOOST_PP_FILENAME_3 +# define BOOST_PP_ITERATION_LIMITS (0,limit3) +# include BOOST_PP_ITERATE() + +# else + +# // I is the loop counter +# if limit2 && limit3 +# define I (BOOST_PP_ITERATION_1 << 16 | BOOST_PP_ITERATION_2 << 8 | \ + BOOST_PP_ITERATION_3) +# elif limit2 +# define I (BOOST_PP_ITERATION_1 << 8 | BOOST_PP_ITERATION_2) +# else +# define I BOOST_PP_ITERATION_1 +# endif + +# if I < count + +# // Done for this arity? Increment N +# if (I+2 >> N+1) +# if N == 0 +# undef N +# define N 1 +# elif N == 1 +# undef N +# define N 2 +# elif N == 2 +# undef N +# define N 3 +# elif N == 3 +# undef N +# define N 4 +# elif N == 4 +# undef N +# define N 5 +# elif N == 5 +# undef N +# define N 6 +# elif N == 6 +# undef N +# define N 7 +# elif N == 7 +# undef N +# define N 8 +# elif N == 8 +# undef N +# define N 9 +# elif N == 9 +# undef N +# define N 10 +# elif N == 10 +# undef N +# define N 11 +# elif N == 11 +# undef N +# define N 12 +# elif N == 12 +# undef N +# define N 13 +# elif N == 13 +# undef N +# define N 14 +# elif N == 14 +# undef N +# define N 15 +# elif N == 15 +# undef N +# define N 16 +# endif + + }; + + template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) > + struct forward_adapter_result::apply< Self(BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of< + typename c::t(BOOST_PP_ENUM_BINARY_PARAMS(N, + typename q::t& BOOST_PP_INTERCEPT)) > + { }; + + template< class MD, class F, class FC > + struct forward_adapter_impl + { + template< BOOST_PP_ENUM_PARAMS(N,typename T) > + inline typename boost::result_of< F( + BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)); + }; + + template< class MD, class F, class FC, int MinArity > + struct forward_adapter_impl + : forward_adapter_impl + { + using forward_adapter_impl::operator(); + +# endif + +# // Zero based count for each arity would be I-(1< + inline typename boost::result_of< FC(BOOST_PP_ENUM_PARAMS(N,PT)) + >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) const + { + return static_cast(this) + ->target_function()(BOOST_PP_ENUM_PARAMS(N,a)); + } + template< BOOST_PP_ENUM_PARAMS(N,typename T) > + inline typename boost::result_of< F(BOOST_PP_ENUM_PARAMS(N,PT)) + >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) + { + return static_cast(this) + ->target_function()(BOOST_PP_ENUM_PARAMS(N,a)); + } +# else + BOOST_TMP_MACRO(BOOST_PP_ENUM_PARAMS(N,typename T), + BOOST_PP_ENUM_PARAMS(N,PT), BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a), + BOOST_PP_ENUM_PARAMS(N,a) ) + // ...generates uglier code but is faster - it caches ENUM_* +# endif + +# undef PT0 +# undef PT1 +# undef PT2 +# undef PT3 +# undef PT4 +# undef PT5 +# undef PT6 +# undef PT7 +# undef PT8 +# undef PT9 +# undef PT10 +# undef PT11 +# undef PT12 +# undef PT13 +# undef PT14 +# undef PT15 + +# endif // I < count + +# undef I +# endif // defined(BOOST_PP_IS_ITERATING) + +#endif // include guard + diff --git a/include/boost/functional/lightweight_forward_adapter.hpp b/include/boost/functional/lightweight_forward_adapter.hpp new file mode 100644 index 0000000..37961ca --- /dev/null +++ b/include/boost/functional/lightweight_forward_adapter.hpp @@ -0,0 +1,258 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are subject to 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_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED +# ifndef BOOST_PP_IS_ITERATING + +# include +# include + +# include +# include +# include +# include +# include +# include + +# include +# include + +# ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY +# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 10 +# elif BOOST_FUNCTIONAL_FORDWARD_ADAPTER_MAX_ARITY < 3 +# undef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY +# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 3 +# endif + +namespace boost +{ + template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 > + class lightweight_forward_adapter; + + //----- ---- --- -- - - - - + + namespace detail + { + template< class MostDerived, typename Function, typename FunctionConst, + int Arity, int MinArity > + struct lightweight_forward_adapter_impl; + + struct lightweight_forward_adapter_result + { + template< typename Sig > struct apply; + + private: + // Utility metafunction for argument transform + template< typename T > struct x { typedef T const& t; }; + template< typename T > struct x< boost::reference_wrapper > + { typedef T& t; }; + template< typename T > struct x : x { }; + template< typename T > struct x : x { }; + template< typename T > struct x : x { }; + + // Utility metafunction to choose target function qualification + template< typename T > struct c + { typedef typename T::target_function_t t; }; + template< typename T > struct c + { typedef typename T::target_function_t t; }; + template< typename T > struct c + { typedef typename T::target_function_const_t t; }; + template< typename T > struct c + { typedef typename T::target_function_const_t t; }; + }; + } + +# define BOOST_TMP_MACRO(f,fn,fc) \ + boost::detail::lightweight_forward_adapter_impl< \ + lightweight_forward_adapter, fn, fc, \ + (MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \ + :BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY), \ + (Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) > + + template< typename Function, int Arity_Or_MinArity, int MaxArity > + class lightweight_forward_adapter + : public BOOST_TMP_MACRO(Function,Function,Function const) + , Function + { + public: + lightweight_forward_adapter(Function const& f = Function()) + : Function(f) + { } + + typedef Function target_function_t; + typedef Function const target_function_const_t; + + Function & target_function() { return *this; } + Function const & target_function() const { return *this; } + + template< typename Sig > struct result + : detail::lightweight_forward_adapter_result::template apply + { }; + + using BOOST_TMP_MACRO(Function,Function, Function const)::operator(); + }; + template< typename Function, int Arity_Or_MinArity, int MaxArity > + class lightweight_forward_adapter< Function const, Arity_Or_MinArity, + MaxArity > + : public BOOST_TMP_MACRO(Function const, Function const, Function const) + , Function + { + public: + lightweight_forward_adapter(Function const& f = Function()) + : Function(f) + { } + + typedef Function const target_function_t; + typedef Function const target_function_const_t; + + Function const & target_function() const { return *this; } + + template< typename Sig > struct result + : detail::lightweight_forward_adapter_result::template apply + { }; + + using BOOST_TMP_MACRO(Function const,Function const, Function const) + ::operator(); + }; + template< typename Function, int Arity_Or_MinArity, int MaxArity > + class lightweight_forward_adapter< Function &, Arity_Or_MinArity, MaxArity > + : public BOOST_TMP_MACRO(Function&, Function, Function) + { + Function& ref_function; + public: + lightweight_forward_adapter(Function& f) + : ref_function(f) + { } + + typedef Function target_function_t; + typedef Function target_function_const_t; + + Function & target_function() const { return this->ref_function; } + + template< typename Sig > struct result + : detail::lightweight_forward_adapter_result::template apply + { }; + + using BOOST_TMP_MACRO(Function&, Function, Function)::operator(); + }; + + #undef BOOST_TMP_MACRO + + namespace detail + { + template< class Self > + struct lightweight_forward_adapter_result::apply< Self() > + : boost::result_of< typename c::t() > + { }; + + template< class MD, class F, class FC > + struct lightweight_forward_adapter_impl + : lightweight_forward_adapter_result + { + inline typename boost::result_of< FC() >::type + operator()() const + { + return static_cast(this)->target_function()(); + } + + inline typename boost::result_of< F() >::type + operator()() + { + return static_cast(this)->target_function()(); + } + }; + +# define BOOST_PP_FILENAME_1 \ + +# define BOOST_PP_ITERATION_LIMITS \ + (1,BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY) +# include BOOST_PP_ITERATE() + + } // namespace detail + + template + struct result_of const ()> + : boost::detail::lightweight_forward_adapter_result::template apply< + boost::lightweight_forward_adapter const () > + { }; + template + struct result_of()> + : boost::detail::lightweight_forward_adapter_result::template apply< + boost::lightweight_forward_adapter() > + { }; + template + struct result_of const& ()> + : boost::detail::lightweight_forward_adapter_result::template apply< + boost::lightweight_forward_adapter const () > + { }; + template + struct result_of& ()> + : boost::detail::lightweight_forward_adapter_result::template apply< + boost::lightweight_forward_adapter() > + { }; +} + +# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED + +# else // defined(BOOST_PP_IS_ITERATING) +# define N BOOST_PP_ITERATION() + + template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) > + struct lightweight_forward_adapter_result::apply< + Self (BOOST_PP_ENUM_PARAMS(N,T)) > + : boost::result_of< + typename c::t (BOOST_PP_ENUM_BINARY_PARAMS(N, + typename x::t BOOST_PP_INTERCEPT)) > + { }; + + template< class MD, class F, class FC > + struct lightweight_forward_adapter_impl + : lightweight_forward_adapter_result + { + template< BOOST_PP_ENUM_PARAMS(N,typename T) > + inline typename boost::result_of< F(BOOST_PP_ENUM_BINARY_PARAMS(N, + T,const& BOOST_PP_INTERCEPT)) >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)); + }; + + template< class MD, class F, class FC, int MinArity > + struct lightweight_forward_adapter_impl + : lightweight_forward_adapter_impl + { + using lightweight_forward_adapter_impl::operator(); + +# define M(z,i,d) \ + static_cast::t>(a##i) + + template< BOOST_PP_ENUM_PARAMS(N,typename T) > + inline typename lightweight_forward_adapter_result::template apply< + MD const (BOOST_PP_ENUM_PARAMS(N,T)) >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const + { + typedef lightweight_forward_adapter_result _; + return static_cast(this)->target_function()( + BOOST_PP_ENUM(N,M,_)); + } + template< BOOST_PP_ENUM_PARAMS(N,typename T) > + inline typename lightweight_forward_adapter_result::template apply< + MD (BOOST_PP_ENUM_PARAMS(N,T)) >::type + operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) + { + typedef lightweight_forward_adapter_result _; + return static_cast(this)->target_function()( + BOOST_PP_ENUM(N,M,_)); + } +# undef M + }; + +# undef N +# endif // defined(BOOST_PP_IS_ITERATING) + +#endif // include guard + diff --git a/include/boost/functional/value_factory.hpp b/include/boost/functional/value_factory.hpp new file mode 100644 index 0000000..6047908 --- /dev/null +++ b/include/boost/functional/value_factory.hpp @@ -0,0 +1,70 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are subject to 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_FUNCTIONAL_VALUE_FACTORY_HPP_INCLUDED +# ifndef BOOST_PP_IS_ITERATING + +# include +# include +# include + +# include +# include +# include +# include +# include +# include + +# ifndef BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY +# define BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY 10 +# elif BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY < 3 +# undef BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY +# define BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY 3 +# endif + +namespace boost +{ + template< typename T > + class value_factory; + + //----- ---- --- -- - - - - + + template< typename T > + class value_factory + { + public: + typedef T result_type; + + value_factory() + { } + +# define BOOST_PP_FILENAME_1 +# define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY) +# include BOOST_PP_ITERATE() + }; + + template< typename T > class value_factory; + // forbidden, would create a dangling reference +} +# define BOOST_FUNCTIONAL_VALUE_FACTORY_HPP_INCLUDED +# else // defined(BOOST_PP_IS_ITERATING) + +# define N BOOST_PP_ITERATION() +# if N > 0 + template< BOOST_PP_ENUM_PARAMS(N, typename T) > +# endif + inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const + { + return result_type(BOOST_PP_ENUM_PARAMS(N,a)); + } +# undef N + +# endif // defined(BOOST_PP_IS_ITERATING) + +#endif // include guard + From 0be6a0b06d4ee5a630e35a7d9711ce9462a773a4 Mon Sep 17 00:00:00 2001 From: Tobias Schwinger Date: Thu, 27 Nov 2008 15:15:47 +0000 Subject: [PATCH 02/82] introduces functional / factory & forward [SVN r49957] --- factory/doc/Jamfile | 20 + factory/doc/factory.qbk | 384 ++++++++++++ factory/doc/html/boostbook.css | 528 ++++++++++++++++ factory/doc/html/index.html | 598 +++++++++++++++++++ factory/test/Jamfile | 21 + factory/test/factory.cpp | 36 ++ factory/test/factory_with_allocator.cpp | 79 +++ factory/test/value_factory.cpp | 29 + forward/doc/Jamfile | 19 + forward/doc/forward.qbk | 316 ++++++++++ forward/doc/html/boostbook.css | 528 ++++++++++++++++ forward/doc/html/index.html | 564 +++++++++++++++++ forward/test/Jamfile | 20 + forward/test/forward_adapter.cpp | 127 ++++ forward/test/lightweight_forward_adapter.cpp | 128 ++++ 15 files changed, 3397 insertions(+) create mode 100644 factory/doc/Jamfile create mode 100644 factory/doc/factory.qbk create mode 100644 factory/doc/html/boostbook.css create mode 100644 factory/doc/html/index.html create mode 100644 factory/test/Jamfile create mode 100644 factory/test/factory.cpp create mode 100644 factory/test/factory_with_allocator.cpp create mode 100644 factory/test/value_factory.cpp create mode 100644 forward/doc/Jamfile create mode 100644 forward/doc/forward.qbk create mode 100644 forward/doc/html/boostbook.css create mode 100644 forward/doc/html/index.html create mode 100644 forward/test/Jamfile create mode 100644 forward/test/forward_adapter.cpp create mode 100644 forward/test/lightweight_forward_adapter.cpp diff --git a/factory/doc/Jamfile b/factory/doc/Jamfile new file mode 100644 index 0000000..1653336 --- /dev/null +++ b/factory/doc/Jamfile @@ -0,0 +1,20 @@ + +# (C) Copyright Tobias Schwinger +# +# Use modification and distribution are subject to the boost Software License, +# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt). + +using quickbook ; + +xml factory : factory.qbk ; +boostbook standalone : factory + : + boost.root=../../../../.. + boost.libraries=../../../../libraries.htm + chunk.section.depth=0 + chunk.first.sections=0 + generate.section.toc.level=2 + toc.max.depth=1 + ; + + diff --git a/factory/doc/factory.qbk b/factory/doc/factory.qbk new file mode 100644 index 0000000..487537c --- /dev/null +++ b/factory/doc/factory.qbk @@ -0,0 +1,384 @@ +[library Boost.Functional/Factory + [quickbook 1.3] + [version 1.0] + [authors [Schwinger, Tobias]] + [copyright 2007 2008 Tobias Schwinger] + [license + 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]) + ] + [purpose Function object templates for object creation.] + [category higher-order] + [category generic] + [last-revision $Date: 2008/11/01 21:44:52 $] +] + +[def __boost_bind__ [@http://www.boost.org/libs/bind/bind.html Boost.Bind]] +[def __boost__bind__ [@http://www.boost.org/libs/bind/bind.html `boost::bind`]] + +[def __boost__forward_adapter__ [@http://www.boost.org/libs/functional/forward/doc/index.html `boost::forward_adapter`]] +[def __fusion_functional_adapters__ [@http://www.boost.org/libs/fusion/doc/html/functional.html Fusion Functional Adapters]] + +[def __boost_function__ [@http://www.boost.org/doc/html/function.html Boost.Function]] +[def __boost__function__ [@http://www.boost.org/doc/html/function.html `boost::function`]] + +[def __smart_pointers__ [@http://www.boost.org/libs/smart_ptr/index.html Smart Pointers]] +[def __boost__shared_ptr__ [@http://www.boost.org/libs/smart_ptr/shared_ptr.htm `boost::shared_ptr`]] + +[def __std__map__ [@http://www.sgi.com/tech/stl/map.html `std::map`]] +[def __std__string__ [@http://www.sgi.com/tech/stl/string.html `std::string`]] +[def __std_allocator__ [@http://www.sgi.com/tech/stl/concepts/allocator.html Allocator]] +[def __std_allocators__ [@http://www.sgi.com/tech/stl/concepts/allocator.html Allocators]] + +[def __boost__ptr_map__ [@http://www.boost.org/libs/ptr_container/doc/ptr_map.html `__boost__ptr_map__`]] + +[def __boost__factory__ `boost::factory`] +[def __boost__value_factory__ `boost::value_factory`] + +[def __factory__ `factory`] +[def __value_factory__ `value_factory`] + + +[section Brief Description] + +The template __boost__factory__ lets you encapsulate a `new` expression +as a function object, __boost__value_factory__ encapsulates a constructor +invocation without `new`. + + __boost__factory__()(arg1,arg2,arg3) + // same as new T(arg1,arg2,arg3) + + __boost__value_factory__()(arg1,arg2,arg3) + // same as T(arg1,arg2,arg3) + +For technical reasons the arguments to the function objects have to be +LValues. A factory that also accepts RValues can be composed using the +__boost__forward_adapter__ or __boost__bind__. + +[endsect] + +[section Background] + +In traditional Object Oriented Programming a Factory is an object implementing +an interface of one or more methods that construct objects conforming to known +interfaces. + + // assuming a_concrete_class and another_concrete_class are derived + // from an_abstract_class + + class a_factory + { + public: + virtual an_abstract_class* create() const = 0; + virtual ~a_factory() { } + }; + + class a_concrete_factory : public a_factory + { + public: + virtual an_abstract_class* create() const + { + return new a_concrete_class(); + } + }; + + class another_concrete_factory : public a_factory + { + public: + virtual an_abstract_class* create() const + { + return new another_concrete_class(); + } + }; + + // [...] + + int main() + { + __boost__ptr_map__<__std__string__,a_factory> factories; + + // [...] + + factories.insert("a_name",std::auto_ptr( + new a_concrete_factory)); + factories.insert("another_name",std::auto_ptr( + new another_concrete_factory)); + + // [...] + + std::auto_ptr x = factories[some_name]->create(); + + // [...] + } + +This approach has several drawbacks. The most obvious one is that there is +lots of boilerplate code. In other words there is too much code to express +a rather simple intention. We could use templates to get rid of some of it +but the approach remains inflexible: + + o We may want a factory that takes some arguments that are forwarded to + the constructor, + o we will probably want to use smart pointers, + o we may want several member functions to create different kinds of + objects, + o we might not necessarily need a polymorphic base class for the objects, + o as we will see, we do not need a factory base class at all, + o we might want to just call the constructor - without `new` to create + an object on the stack, and + o finally we might want to use customized memory management. + +Experience has shown that using function objects and generic Boost components +for their composition, Design Patterns that describe callback mechasisms +(typically requiring a high percentage of boilerplate code with pure Object +Oriented methodology) become implementable with just few code lines and without +extra classes. + +Factories are callback mechanisms for constructors, so we provide two class +templates, __boost__value_factory__ and __boost__factory__, that encasulate +object construction via direct application of the constructor and the `new` +operator, respectively. + +We let the function objects forward their arguments to the construction +expressions they encapsulate. Overthis __boost__factory__ optionally allows +the use of smart pointers and __std_allocators__. + +Compile-time polymorphism can be used where appropriate, + + template< class T > + void do_something() + { + // [...] + T x = T(a,b); + + // for conceptually similar objects x we neither need virtual + // functions nor a common base class in this context. + // [...] + } + +Now, to allow inhomogenous signaturs for the constructors of the types passed +in for `T` we can use __value_factory__ and __boost__bind__ to normalize between +them. + + template< class ValueFactory > + void do_something(ValueFactory make_obj = ValueFactory()) + { + // [...] + typename ValueFactory::result_type x = make_obj(a,b); + + // for conceptually similar objects x we neither need virtual + // functions nor a common base class in this context. + // [...] + } + + int main() + { + // [...] + + do_something(__boost__value_factory__()); + do_something(boost::bind(__boost__value_factory__(),_1,5,_2)); + // construct X(a,b) and Y(a,5,b), respectively. + + // [...] + } + +Maybe we want our objects to outlive the function's scope, in this case we +have to use dynamic allocation; + + template< class Factory > + whatever do_something(Factory new_obj = Factory()) + { + typename Factory::result_type ptr = new_obj(a,b); + + // again, no common base class or virtual functions needed, + // we could enforce a polymorphic base by writing e.g. + // boost::shared_ptr + // instead of + // typename Factory::result_type + // above. + // Note that we are also free to have the type erasure happen + // somewhere else (e.g. in the constructor of this function's + // result type). + + // [...] + } + + // [... call do_something like above but with __factory__ instead + // of __value_factory__] + +Although we might have created polymorphic objects in the previous example, +we have used compile time polymorphism for the factory. If we want to erase +the type of the factory and thus allow polymorphism at run time, we can +use __boost_function__ to do so. The first example can be rewritten as +follows. + + typedef boost::function< an_abstract_class*() > a_factory; + + // [...] + + int main() + { + __std__map__<__std__string__,a_factory> factories; + + // [...] + + factories["a_name"] = __boost__factory__(); + factories["another_name"] = + __boost__factory__(); + + // [...] + } + +Of course we can just as easy create factories that take arguments and/or +return __smart_pointers__. + +[endsect] + + +[section:reference Reference] + + +[section value_factory] + +[heading Description] + +Function object template that invokes the constructor of the type `T`. + +[heading Header] + #include + +[heading Synopsis] + + namespace boost + { + template< typename T > + class value_factory; + } + +[variablelist Notation + [[`T`] [an arbitrary type with at least one public constructor]] + [[`a0`...`aN`] [argument LValues to a constructor of `T`]] + [[`F`] [the type `value_factory`]] + [[`f`] [an instance object of `F`]] +] + +[heading Expression Semantics] + +[table + [[Expression] [Semantics]] + [[`F()`] [creates an object of type `F`.]] + [[`F(f)`] [creates an object of type `F`.]] + [[`f(a0`...`aN)`] [returns `T(a0`...`aN)`.]] + [[`F::result_type`] [is the type `T`.]] +] + +[heading Limits] + +The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set the +maximum arity. It defaults to 10. + +[endsect] + + +[section factory] + +[heading Description] + +Function object template that dynamically constructs a pointee object for +the type of pointer given as template argument. Smart pointers may be used +for the template argument, given that `boost::pointee::type` yields +the pointee type. + +If an __allocator__ is given, it is used for memory allocation and the +placement form of the `new` operator is used to construct the object. +A function object that calls the destructor and deallocates the memory +with a copy of the Allocator is used for the second constructor argument +of `Pointer` (thus it must be a __smart_pointer__ that provides a suitable +constructor, such as __boost__shared_ptr__). + +If a third template argument is `factory_passes_alloc_to_smart_pointer`, +the allocator itself is used for the third constructor argument of `Pointer` +(__boost__shared_ptr__ then uses the allocator to manage the memory of its +seperately allocated reference counter). + +[heading Header] + #include + +[heading Synopsis] + + namespace boost + { + enum factory_alloc_propagation + { + factory_alloc_for_pointee_and_deleter, + factory_passes_alloc_to_smart_pointer + }; + + template< typename Pointer, + class Allocator = boost::none_t, + factory_alloc_propagation AllocProp = + factory_alloc_for_pointee_and_deleter > + class factory; + } + +[variablelist Notation + [[`T`] [an arbitrary type with at least one public constructor]] + [[`P`] [pointer or smart pointer to `T`]] + [[`a0`...`aN`] [argument LValues to a constructor of `T`]] + [[`F`] [the type `factory

`]] + [[`f`] [an instance object of `F`]] +] + +[heading Expression Semantics] + +[table + [[Expression] [Semantics]] + [[`F()`] [creates an object of type `F`.]] + [[`F(f)`] [creates an object of type `F`.]] + [[`f(a0`...`aN)`] [dynamically creates an object of type `T` using + `a0`...`aN` as arguments for the constructor invocation.]] + [[`F::result_type`] [is the type `P` with top-level cv-qualifiers removed.]] +] + +[heading Limits] + +The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the +maximum arity. It defaults to 10. + +[endsect] + +[endsect] + +[section Acknowledgements] + +Eric Niebler requested a function to invoke a type's constructor (with the +arguments supplied as a Tuple) as a Fusion feature. These Factory utilities are +a factored-out generalization of this idea. + +Dave Abrahams suggested Smart Pointer support for exception safety, providing +useful hints for the implementation. + +Joel de Guzman's documentation style was copied from Fusion. + +Further, I want to thank Peter Dimov for sharing his insights on language +details and their evolution. + +[endsect] + +[section References] + +# [@http://en.wikipedia.org/wiki/Design_Patterns Design Patterns], + Gamma et al. - Addison Wesley Publishing, 1995 + +# [@http://www.sgi.com/tech/stl/ Standard Template Library Programmer's Guide], + Hewlett-Packard Company, 1994 + +# [@http://www.boost.org/libs/bind/bind.html Boost.Bind], + Peter Dimov, 2001-2005 + +# [@http://www.boost.org/doc/html/function.html Boost.Function], + Douglas Gregor, 2001-2004 + +[endsect] + + diff --git a/factory/doc/html/boostbook.css b/factory/doc/html/boostbook.css new file mode 100644 index 0000000..858d43c --- /dev/null +++ b/factory/doc/html/boostbook.css @@ -0,0 +1,528 @@ +/*============================================================================= + Copyright (c) 2004 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to 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) +=============================================================================*/ + +/*============================================================================= + Body defaults +=============================================================================*/ + + body + { + margin: 1em; + font-family: sans-serif; + } + +/*============================================================================= + Paragraphs +=============================================================================*/ + + p + { + text-align: left; + font-size: 10pt; + line-height: 1.15; + } + +/*============================================================================= + Program listings +=============================================================================*/ + + /* Code on paragraphs */ + p tt.computeroutput + { + font-size: 9pt; + } + + pre.synopsis + { + font-size: 90%; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + .programlisting, + .screen + { + font-size: 9pt; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + /* Program listings in tables don't get borders */ + td .programlisting, + td .screen + { + margin: 0pc 0pc 0pc 0pc; + padding: 0pc 0pc 0pc 0pc; + } + +/*============================================================================= + Headings +=============================================================================*/ + + h1, h2, h3, h4, h5, h6 + { + text-align: left; + margin: 1em 0em 0.5em 0em; + font-weight: bold; + } + + h1 { font: 140% } + h2 { font: bold 140% } + h3 { font: bold 130% } + h4 { font: bold 120% } + h5 { font: italic 110% } + h6 { font: italic 100% } + + /* Top page titles */ + title, + h1.title, + h2.title + h3.title, + h4.title, + h5.title, + h6.title, + .refentrytitle + { + font-weight: bold; + margin-bottom: 1pc; + } + + h1.title { font-size: 140% } + h2.title { font-size: 140% } + h3.title { font-size: 130% } + h4.title { font-size: 120% } + h5.title { font-size: 110% } + h6.title { font-size: 100% } + + .section h1 + { + margin: 0em 0em 0.5em 0em; + font-size: 140%; + } + + .section h2 { font-size: 140% } + .section h3 { font-size: 130% } + .section h4 { font-size: 120% } + .section h5 { font-size: 110% } + .section h6 { font-size: 100% } + + /* Code on titles */ + h1 tt.computeroutput { font-size: 140% } + h2 tt.computeroutput { font-size: 140% } + h3 tt.computeroutput { font-size: 130% } + h4 tt.computeroutput { font-size: 120% } + h5 tt.computeroutput { font-size: 110% } + h6 tt.computeroutput { font-size: 100% } + +/*============================================================================= + Author +=============================================================================*/ + + h3.author + { + font-size: 100% + } + +/*============================================================================= + Lists +=============================================================================*/ + + li + { + font-size: 10pt; + line-height: 1.3; + } + + /* Unordered lists */ + ul + { + text-align: left; + } + + /* Ordered lists */ + ol + { + text-align: left; + } + +/*============================================================================= + Links +=============================================================================*/ + + a + { + text-decoration: none; /* no underline */ + } + + a:hover + { + text-decoration: underline; + } + +/*============================================================================= + Spirit style navigation +=============================================================================*/ + + .spirit-nav + { + text-align: right; + } + + .spirit-nav a + { + color: white; + padding-left: 0.5em; + } + + .spirit-nav img + { + border-width: 0px; + } + +/*============================================================================= + Table of contents +=============================================================================*/ + + .toc + { + margin: 1pc 4% 0pc 4%; + padding: 0.1pc 1pc 0.1pc 1pc; + font-size: 80%; + line-height: 1.15; + } + + .boost-toc + { + float: right; + padding: 0.5pc; + } + +/*============================================================================= + Tables +=============================================================================*/ + + .table-title, + div.table p.title + { + margin-left: 4%; + padding-right: 0.5em; + padding-left: 0.5em; + } + + .informaltable table, + .table table + { + width: 92%; + margin-left: 4%; + margin-right: 4%; + } + + div.informaltable table, + div.table table + { + padding: 4px; + } + + /* Table Cells */ + div.informaltable table tr td, + div.table table tr td + { + padding: 0.5em; + text-align: left; + font-size: 9pt; + } + + div.informaltable table tr th, + div.table table tr th + { + padding: 0.5em 0.5em 0.5em 0.5em; + border: 1pt solid white; + font-size: 80%; + } + +/*============================================================================= + Blurbs +=============================================================================*/ + + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + font-size: 9pt; /* A little bit smaller than the main text */ + line-height: 1.2; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.0pc 0.5pc; + } + + div.sidebar img + { + padding: 1pt; + } + +/*============================================================================= + Callouts +=============================================================================*/ + .line_callout_bug img + { + float: left; + position:relative; + left: 4px; + top: -12px; + clear: left; + margin-left:-22px; + } + + .callout_bug img + { + } + +/*============================================================================= + Variable Lists +=============================================================================*/ + + /* Make the terms in definition lists bold */ + div.variablelist dl dt, + span.term + { + font-weight: bold; + font-size: 10pt; + } + + div.variablelist table tbody tr td + { + text-align: left; + vertical-align: top; + padding: 0em 2em 0em 0em; + font-size: 10pt; + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + + div.variablelist dl dt + { + margin-bottom: 0.2em; + } + + div.variablelist dl dd + { + margin: 0em 0em 0.5em 2em; + font-size: 10pt; + } + + div.variablelist table tbody tr td p, + div.variablelist dl dd p + { + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + +/*============================================================================= + Misc +=============================================================================*/ + + /* Title of books and articles in bibliographies */ + span.title + { + font-style: italic; + } + + span.underline + { + text-decoration: underline; + } + + span.strikethrough + { + text-decoration: line-through; + } + + /* Copyright, Legal Notice */ + div div.legalnotice p + { + text-align: left + } + +/*============================================================================= + Colors +=============================================================================*/ + + @media screen + { + /* Links */ + a + { + color: #005a9c; + } + + a:visited + { + color: #9c5a9c; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, + h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited + { + text-decoration: none; /* no underline */ + color: #000000; + } + + /* Syntax Highlighting */ + .keyword { color: #0000AA; } + .identifier { color: #000000; } + .special { color: #707070; } + .preprocessor { color: #402080; } + .char { color: teal; } + .comment { color: #800000; } + .string { color: teal; } + .number { color: teal; } + .white_bkd { background-color: #FFFFFF; } + .dk_grey_bkd { background-color: #999999; } + + /* Copyright, Legal Notice */ + .copyright + { + color: #666666; + font-size: small; + } + + div div.legalnotice p + { + color: #666666; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid #DCDCDC; + } + + .programlisting, + .screen + { + border: 1px solid #DCDCDC; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Blurbs */ + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + border: 1px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + } + + div.informaltable table tr th, + div.table table tr th + { + background-color: #F0F0F0; + border: 1px solid #DCDCDC; + } + + /* Misc */ + span.highlight + { + color: #00A000; + } + } + + @media print + { + /* Links */ + a + { + color: black; + } + + a:visited + { + color: black; + } + + .spirit-nav + { + display: none; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid gray; + } + + .programlisting, + .screen + { + border: 1px solid gray; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid gray; + } + + .informaltable table, + .table table + { + border: 1px solid gray; + border-collapse: collapse; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid gray; + } + + div.informaltable table tr th, + div.table table tr th + { + border: 1px solid gray; + } + + /* Misc */ + span.highlight + { + font-weight: bold; + } + } diff --git a/factory/doc/html/index.html b/factory/doc/html/index.html new file mode 100644 index 0000000..93ce15f --- /dev/null +++ b/factory/doc/html/index.html @@ -0,0 +1,598 @@ + + + +Chapter 1. Boost.Functional/Factory 1.0 + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+


+
+
+
+

+Chapter 1. Boost.Functional/Factory 1.0

+

+Tobias Schwinger +

+
+
+

+ 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) +

+
+
+ +
+ +

+ The template boost::factory lets you encapsulate a new expression as a function object, boost::value_factory + encapsulates a constructor invocation without new. +

+
boost::factory<T*>()(arg1,arg2,arg3) 
+// same as new T(arg1,arg2,arg3)
+
+boost::value_factory<T>()(arg1,arg2,arg3)
+// same as T(arg1,arg2,arg3)
+
+

+ For technical reasons the arguments to the function objects have to be LValues. + A factory that also accepts RValues can be composed using the boost::forward_adapter + or boost::bind. +

+
+
+ +

+ In traditional Object Oriented Programming a Factory is an object implementing + an interface of one or more methods that construct objects conforming to known + interfaces. +

+
// assuming a_concrete_class and another_concrete_class are derived
+// from an_abstract_class
+
+class a_factory
+{
+  public:
+    virtual an_abstract_class* create() const = 0;
+    virtual ~a_factory() { }
+};
+
+class a_concrete_factory : public a_factory
+{
+  public:
+    virtual an_abstract_class* create() const
+    {
+        return new a_concrete_class();
+    }
+};
+
+class another_concrete_factory : public a_factory
+{
+  public:
+    virtual an_abstract_class* create() const
+    {
+        return new another_concrete_class();
+    }
+};
+
+// [...]
+
+int main()
+{
+    __boost__ptr_map__<std::string,a_factory> factories;
+
+    // [...]
+
+    factories.insert("a_name",std::auto_ptr<a_factory>(
+        new a_concrete_factory));
+    factories.insert("another_name",std::auto_ptr<a_factory>(
+        new another_concrete_factory));
+
+    // [...]
+
+    std::auto_ptr<an_abstract_factory> x = factories[some_name]->create();
+
+    // [...]
+}
+
+

+ This approach has several drawbacks. The most obvious one is that there is + lots of boilerplate code. In other words there is too much code to express + a rather simple intention. We could use templates to get rid of some of it + but the approach remains inflexible: +

+
o We may want a factory that takes some arguments that are forwarded to
+  the constructor,
+o we will probably want to use smart pointers,
+o we may want several member functions to create different kinds of
+  objects,
+o we might not necessarily need a polymorphic base class for the objects,
+o as we will see, we do not need a factory base class at all, 
+o we might want to just call the constructor - without #new# to create
+  an object on the stack, and
+o finally we might want to use customized memory management.
+
+

+ Experience has shown that using function objects and generic Boost components + for their composition, Design Patterns that describe callback mechasisms (typically + requiring a high percentage of boilerplate code with pure Object Oriented methodology) + become implementable with just few code lines and without extra classes. +

+

+ Factories are callback mechanisms for constructors, so we provide two class + templates, boost::value_factory and boost::factory, + that encasulate object construction via direct application of the constructor + and the new operator, respectively. +

+

+ We let the function objects forward their arguments to the construction expressions + they encapsulate. Overthis boost::factory + optionally allows the use of smart pointers and Allocators. +

+

+ Compile-time polymorphism can be used where appropriate, +

+
template< class T >
+void do_something()
+{
+    // [...]
+    T x = T(a,b);
+
+    // for conceptually similar objects x we neither need virtual
+    // functions nor a common base class in this context.
+    // [...]
+}
+
+

+ Now, to allow inhomogenous signaturs for the constructors of the types passed + in for T we can use value_factory and boost::bind + to normalize between them. +

+
template< class ValueFactory > 
+void do_something(ValueFactory make_obj = ValueFactory())
+{
+    // [...]
+    typename ValueFactory::result_type x = make_obj(a,b);
+
+    // for conceptually similar objects x we neither need virtual
+    // functions nor a common base class in this context.
+    // [...]
+}
+
+int main()
+{
+    // [...]
+
+    do_something(boost::value_factory<X>());
+    do_something(boost::bind(boost::value_factory<Y>(),_1,5,_2));
+    // construct X(a,b) and Y(a,5,b), respectively.
+
+    // [...]
+}
+
+

+ Maybe we want our objects to outlive the function's scope, in this case we + have to use dynamic allocation; +

+
template< class Factory >
+whatever do_something(Factory new_obj = Factory())
+{
+    typename Factory::result_type ptr = new_obj(a,b);
+
+    // again, no common base class or virtual functions needed,
+    // we could enforce a polymorphic base by writing e.g.
+    //    boost::shared_ptr<base>
+    // instead of
+    //    typename Factory::result_type
+    // above.
+    // Note that we are also free to have the type erasure happen 
+    // somewhere else (e.g. in the constructor of this function's
+    // result type).
+
+    // [...]
+}
+
+// [... call do_something like above but with __factory__ instead
+// of __value_factory__]
+
+

+ Although we might have created polymorphic objects in the previous example, + we have used compile time polymorphism for the factory. If we want to erase + the type of the factory and thus allow polymorphism at run time, we can use + Boost.Function + to do so. The first example can be rewritten as follows. +

+
typedef boost::function< an_abstract_class*() > a_factory;
+
+// [...]
+
+int main()
+{
+    std::map<std::string,a_factory> factories;
+
+    // [...]
+
+    factories["a_name"] = boost::factory<a_concrete_class*>();
+    factories["another_name"] = 
+        boost::factory<another_concrete_class*>();
+
+    // [...]
+} 
+
+

+ Of course we can just as easy create factories that take arguments and/or return + Smart Pointers. +

+
+
+ + +
+ +

+ + Description +

+

+ Function object template that invokes the constructor of the type T. +

+

+ + Header +

+
#include <boost/functional/value_factory.hpp>
+
+

+ + Synopsis +

+
namespace boost
+{
+    template< typename T >
+    class value_factory;
+}
+
+
+

Notation

+
+
T
+

+ an arbitrary type with at least one public constructor +

+
a0...aN
+

+ argument LValues to a constructor of T +

+
F
+

+ the type value_factory<F> +

+
f
+

+ an instance object of F +

+
+
+

+ + Expression + Semantics +

+
++++ + + + + + + + + + + + + + + + + + + + + + + +
+

+ Expression +

+
+

+ Semantics +

+
+

+ F() +

+
+

+ creates an object of type F. +

+
+

+ F(f) +

+
+

+ creates an object of type F. +

+
+

+ f(a0...aN) +

+
+

+ returns T(a0...aN). +

+
+

+ F::result_type +

+
+

+ is the type T. +

+
+

+ + Limits +

+

+ The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set + the maximum arity. It defaults to 10. +

+
+
+ +

+ + Description +

+

+ Function object template that dynamically constructs a pointee object for + the type of pointer given as template argument. Smart pointers may be used + for the template argument, given that boost::pointee<Pointer>::type + yields the pointee type. +

+

+ If an _allocator_ is given, it is used + for memory allocation and the placement form of the new + operator is used to construct the object. A function object that calls the + destructor and deallocates the memory with a copy of the Allocator is used + for the second constructor argument of Pointer + (thus it must be a __smartpointer_ + that provides a suitable constructor, such as boost::shared_ptr). +

+

+ If a third template argument is factory_passes_alloc_to_smart_pointer, + the allocator itself is used for the third constructor argument of Pointer (boost::shared_ptr then uses the allocator + to manage the memory of its seperately allocated reference counter). +

+

+ + Header +

+
#include <boost/functional/factory.hpp>
+
+

+ + Synopsis +

+
namespace boost
+{
+    enum factory_alloc_propagation
+    {
+        factory_alloc_for_pointee_and_deleter,
+        factory_passes_alloc_to_smart_pointer
+    };
+
+    template< typename Pointer, 
+        class Allocator = boost::none_t,
+        factory_alloc_propagation AllocProp =
+            factory_alloc_for_pointee_and_deleter >
+    class factory;
+}
+
+
+

Notation

+
+
T
+

+ an arbitrary type with at least one public constructor +

+
P
+

+ pointer or smart pointer to T +

+
a0...aN
+

+ argument LValues to a constructor of T +

+
F
+

+ the type factory<P> +

+
f
+

+ an instance object of F +

+
+
+

+ + Expression + Semantics +

+
++++ + + + + + + + + + + + + + + + + + + + + + + +
+

+ Expression +

+
+

+ Semantics +

+
+

+ F() +

+
+

+ creates an object of type F. +

+
+

+ F(f) +

+
+

+ creates an object of type F. +

+
+

+ f(a0...aN) +

+
+

+ dynamically creates an object of type T + using a0...aN as arguments for the constructor + invocation. +

+
+

+ F::result_type +

+
+

+ is the type P with + top-level cv-qualifiers removed. +

+
+

+ + Limits +

+

+ The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the maximum + arity. It defaults to 10. +

+
+
+
+ +

+ Eric Niebler requested a function to invoke a type's constructor (with the + arguments supplied as a Tuple) as a Fusion feature. These Factory utilities + are a factored-out generalization of this idea. +

+

+ Dave Abrahams suggested Smart Pointer support for exception safety, providing + useful hints for the implementation. +

+

+ Joel de Guzman's documentation style was copied from Fusion. +

+

+ Further, I want to thank Peter Dimov for sharing his insights on language details + and their evolution. +

+
+
+ +
    +
  1. +Design Patterns, + Gamma et al. - Addison Wesley Publishing, 1995 +
  2. +
  3. +Standard Template Library Programmer's + Guide, Hewlett-Packard Company, 1994 +
  4. +
  5. +Boost.Bind, + Peter Dimov, 2001-2005 +
  6. +
  7. +Boost.Function, + Douglas Gregor, 2001-2004 +
  8. +
+
+
+ + + +

Last revised: November 01, 2008 at 21:44:52 GMT

+
+
+ + diff --git a/factory/test/Jamfile b/factory/test/Jamfile new file mode 100644 index 0000000..4abdb68 --- /dev/null +++ b/factory/test/Jamfile @@ -0,0 +1,21 @@ + +# (C) Copyright Tobias Schwinger +# +# Use modification and distribution are subject to the boost Software License, +# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt). + +import testing ; + +project factory-tests + : requirements + /Users/tosh/Lab/boost + /Users/tosh/Lab/deploy/x_files/factory + ; + +test-suite functional/factory + : + [ run value_factory.cpp ] + [ run factory.cpp ] + [ run factory_with_allocator.cpp ] + ; + diff --git a/factory/test/factory.cpp b/factory/test/factory.cpp new file mode 100644 index 0000000..dff40a7 --- /dev/null +++ b/factory/test/factory.cpp @@ -0,0 +1,36 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are subject to 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). +==============================================================================*/ + +#include +#include + +#include + +class sum +{ + int val_sum; + public: + sum(int a, int b) : val_sum(a + b) { } + + operator int() const { return this->val_sum; } +}; + +int main() +{ + int one = 1, two = 2; + { + sum* instance( boost::factory< sum* >()(one,two) ); + BOOST_TEST(*instance == 3); + } + { + std::auto_ptr instance( boost::factory< std::auto_ptr >()(one,two) ); + BOOST_TEST(*instance == 3); + } + return boost::report_errors(); +} + diff --git a/factory/test/factory_with_allocator.cpp b/factory/test/factory_with_allocator.cpp new file mode 100644 index 0000000..decd656 --- /dev/null +++ b/factory/test/factory_with_allocator.cpp @@ -0,0 +1,79 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are subject to 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). +==============================================================================*/ + +#include +#include + +#include +#include +#include + +using std::size_t; + +class sum +{ + int val_sum; + public: + sum(int a, int b) : val_sum(a + b) { } + + operator int() const { return this->val_sum; } +}; + +template< typename T > +class counting_allocator : public std::allocator +{ + public: + counting_allocator() + { } + + template< typename OtherT > + struct rebind { typedef counting_allocator other; }; + + template< typename OtherT > + counting_allocator(counting_allocator const& that) + { } + + static size_t n_allocated; + T* allocate(size_t n, void const* hint = 0l) + { + n_allocated += 1; + return std::allocator::allocate(n,hint); + } + + static size_t n_deallocated; + void deallocate(T* ptr, size_t n) + { + n_deallocated += 1; + return std::allocator::deallocate(ptr,n); + } +}; +template< typename T > size_t counting_allocator::n_allocated = 0; +template< typename T > size_t counting_allocator::n_deallocated = 0; + +int main() +{ + int one = 1, two = 2; + { + boost::shared_ptr instance( + boost::factory< boost::shared_ptr, counting_allocator, + boost::factory_alloc_for_pointee_and_deleter >()(one,two) ); + BOOST_TEST(*instance == 3); + } + BOOST_TEST(counting_allocator::n_allocated == 1); + BOOST_TEST(counting_allocator::n_deallocated == 1); + { + boost::shared_ptr instance( + boost::factory< boost::shared_ptr, counting_allocator, + boost::factory_passes_alloc_to_smart_pointer >()(one,two) ); + BOOST_TEST(*instance == 3); + } + BOOST_TEST(counting_allocator::n_allocated == 2); + BOOST_TEST(counting_allocator::n_deallocated == 2); + return boost::report_errors(); +} + diff --git a/factory/test/value_factory.cpp b/factory/test/value_factory.cpp new file mode 100644 index 0000000..e63c9ec --- /dev/null +++ b/factory/test/value_factory.cpp @@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are subject to 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). +==============================================================================*/ + +#include +#include + +class sum +{ + int val_sum; + public: + sum(int a, int b) : val_sum(a + b) { } + operator int() const { return this->val_sum; } +}; + +int main() +{ + int one = 1, two = 2; + { + sum instance( boost::value_factory< sum >()(one,two) ); + BOOST_TEST(instance == 3); + } + return boost::report_errors(); +} + diff --git a/forward/doc/Jamfile b/forward/doc/Jamfile new file mode 100644 index 0000000..5665497 --- /dev/null +++ b/forward/doc/Jamfile @@ -0,0 +1,19 @@ + +# (C) Copyright Tobias Schwinger +# +# Use modification and distribution are subject to the boost Software License, +# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt). + +using quickbook ; + +xml forward : forward.qbk ; +boostbook standalone : forward + : + boost.root=../../../../.. + boost.libraries=../../../../libraries.htm + chunk.section.depth=0 + chunk.first.sections=0 + generate.section.toc.level=2 + toc.max.depth=1 + ; + diff --git a/forward/doc/forward.qbk b/forward/doc/forward.qbk new file mode 100644 index 0000000..4eb227d --- /dev/null +++ b/forward/doc/forward.qbk @@ -0,0 +1,316 @@ +[library Boost.Functional/Forward + [quickbook 1.3] + [version 1.0] + [authors [Schwinger, Tobias]] + [copyright 2007 2008 Tobias Schwinger] + [license + 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]) + ] + [purpose Function object adapters for generic argument forwarding.] + [category higher-order] + [category generic] + [last-revision $Date: 2008/11/01 19:58:50 $] +] + +[def __unspecified__ /unspecified/] +[def __boost_ref__ [@http://www.boost.org/doc/html/ref.html Boost.Ref]] +[def __boost_result_of__ [@http://www.boost.org/libs/utility/utility.htm#result_of Boost.ResultOf]] +[def __boost__result_of__ [@http://www.boost.org/libs/utility/utility.htm#result_of `boost::result_of`]] +[def __the_forwarding_problem__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem]] +[def __boost_fusion__ [@http://www.boost.org/libs/fusion/doc/html/index.html Boost.Fusion]] + +[section Brief Description] + +`boost::forward_adapter` provides a reusable adapter template for function +objects. It forwards RValues as references to const, while leaving LValues +as-is. + + struct g // function object that only accept LValues + { + template< typename T0, typename T1, typename T2 > + void operator()(T0 & t0, T1 & t1, T2 & t2) const; + + typedef void result_type; + }; + + // Adapted version also accepts RValues and forwards + // them as references to const, LValues as-is + typedef boost::forward_adapter f; + +Another adapter, `boost::lighweight_forward_adapter` allows forwarding with +some help from the user accepting and unwrapping reference wrappers (see +__boost_ref__) for reference arguments, const qualifying all other arguments. + +The target functions must be compatible with __boost_result_of__, and so are +the adapters. + +[endsect] + +[section Background] + +Let's suppose we have some function `f` that we can call like this: + + f(123,a_variable); + +Now we want to write another, generic function `g` that can be called the +same way and returns some object that calls `f` with the same arguments. + + f(123,a_variable) == g(f,123,a_variable).call_f() + +[heading Why would we want to do it, anyway?] + +Maybe we want to run `f` several times. Or maybe we want to run it within +another thread. Maybe we just want to encapsulate the call expression for now, +and then use it with other code that allows to compose more complex expressions +in order to decompose it with C++ templates and have the compiler generate some +machinery that eventually calls `f` at runtime (in other words; apply a +technique that is commonly referred to as Expression Templates). + +[heading Now, how do we do it?] + +The bad news is: It's impossible. + +That is so because there is a slight difference between a variable and an +expression that evaluates to its value: Given + + int y; + int const z = 0; + +and + + template< typename T > void func1(T & x); + +we can call + + func1(y); // x is a reference to a non-const object + func1(z); // x is a reference to a const object + +where + + func1(1); // fails to compile. + +This way we can safely have `func1` store its reference argument and the +compiler keeps us from storing a reference to an object with temporary lifetime. + +It is important to realize that non-constness and whether an object binds to a +non-const reference parameter are two different properties. The latter is the +distinction between LValues and RValues. The names stem from the left hand side +and the right hand side of assignment expressions, thus LValues are typically +the ones you can assign to, and RValues the temporary results from the right +hand side expression. + + y = 1+2; // a is LValue, 1+2 is the expression producing the RValue, + // 1+2 = a; // usually makes no sense. + + func1(y); // works, because y is an LValue + // func1(1+2); // fails to compile, because we only got an RValue. + +If we add const qualification on the parameter, our function also accepts +RValues: + + template< typename T > void func2(T const & x); + + // [...] function scope: + func2(1); // x is a reference to a const temporary, object, + func2(y); // x is a reference to a const object, while y is not const, and + func2(z); // x is a reference to a const object, just like z. + +In all cases, the argument `x` in `func2` is a const-qualified LValue. +We can use function overloading to identify non-const LValues: + + template< typename T > void func3(T const & x); // #1 + template< typename T > void func3(T & x); // #2 + + // [...] function scope: + func3(1); // x is a reference to a const, temporary object in #1, + func3(y); // x is a reference to a non-const object in #2, and + func3(z); // x is a reference to a const object in #1. + +Note that all arguments `x` in the overloaded function `func3` are LValues. +In fact, there is no way to transport RValues into a function as-is in C++98. +Also note that we can't distinguish between what used to be a const qualified +LValue and an RValue. + +That's as close as we can get to a generic forwarding function `g` as +described above by the means of C++ 98. See __the_forwarding_problem__ for a +very detailed discussion including solutions that require language changes. + +Now, for actually implementing it, we need 2^N overloads for N parameters +(each with and without const qualifier) for each number of arguments +(that is 2^(Nmax+1) - 2^Nmin). Right, that means the compile-time complexity +is O(2^N), however the factor is low so it works quite well for a reasonable +number (< 10) of arguments. + +[endsect] + +[section:reference Reference] + +[section forward_adapter] + +[heading Description] + +Function object adapter template whose instances are callable with LValue and +RValue arguments. RValue arguments are forwarded as reference-to-const typed +LValues. + +An arity can be given as second, numeric non-type template argument to restrict +forwarding to a specific arity. +If a third, numeric non-type template argument is present, the second and third +template argument are treated as minimum and maximum arity, respectively. +Specifying an arity can be helpful to improve the readability of diagnostic +messages and compile time performance. + +__boost_result_of__ can be used to determine the result types of specific call +expressions. + +[heading Header] + #include + +[heading Synopsis] + + namespace boost + { + template< class Function, + int Arity_Or_MinArity = __unspecified__, int MaxArity = __unspecified__ > + class forward_adapter; + } + +[variablelist Notation + [[`F`] [a possibly const qualified function object type or reference type thereof]] + [[`f`] [an object convertible to `F`]] + [[`FA`] [the type `forward_adapter`]] + [[`fa`] [an instance object of `FA`, initialized with `f`]] + [[`a0`...`aN`] [arguments to `fa`]] +] + +The result type of a target function invocation must be + + __boost__result_of__::type + +where `TA0`...`TAN` denote the argument types of `a0`...`aN`. + +[heading Expression Semantics] + +[table + [[Expression] [Semantics]] + [[`FA(f)`] [creates an adapter, initializes the target function with `f`.]] + [[`FA()`] [creates an adapter, attempts to use `F`'s default constructor.]] + [[`fa(a0`...`aN)`] [calls `f` with with arguments `a0`...`aN`.]] +] + +[heading Limits] + +The macro BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY can be defined to set the +maximum call arity. It defaults to 6. + +[heading Complexity] + +Preprocessing time: O(2^N), where N is the arity limit. +Compile time: O(2^N), where N depends on the arity range. +Run time: O(0) if the compiler inlines, O(1) otherwise. + +[endsect] + + +[section lightweight_forward_adapter] + +[heading Description] + +Function object adapter template whose instances are callable with LValue and +RValue arguments. All arguments are forwarded as reference-to-const typed +LValues, except for reference wrappers which are unwrapped and may yield +non-const LValues. + +An arity can be given as second, numeric non-type template argument to restrict +forwarding to a specific arity. +If a third, numeric non-type template argument is present, the second and third +template argument are treated as minimum and maximum arity, respectively. +Specifying an arity can be helpful to improve the readability of diagnostic +messages and compile time performance. + +__boost_result_of__ can be used to determine the result types of specific call +expressions. + +[heading Header] + #include + +[heading Synopsis] + + namespace boost + { + template< class Function, + int Arity_Or_MinArity = __unspecified__, int MaxArity = __unspecified__ > + struct lightweight_forward_adapter; + } + +[variablelist Notation + [[`F`] [a possibly const qualified function object type or reference type thereof]] + [[`f`] [an object convertible to `F`]] + [[`FA`] [the type `lightweight_forward_adapter`]] + [[`fa`] [an instance of `FA`, initialized with `f`]] + [[`a0`...`aN`] [arguments to `fa`]] +] + +The result type of a target function invocation must be + + __boost__result_of__::type + +where `TA0`...`TAN` denote the argument types of `a0`...`aN`. + +[heading Expression Semantics] + +[table + [[Expression] [Semantics]] + [[`FA(f)`] [creates an adapter, initializes the target function with `f`.]] + [[`FA()`] [creates an adapter, attempts to use `F`'s default constructor.]] + [[`fa(a0`...`aN)`] [calls `f` with with const arguments `a0`...`aN`. If `aI` is a + reference wrapper it is unwrapped.]] +] + +[heading Limits] + +The macro BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY can be defined +to set the maximum call arity. It defaults to 10. + +[heading Complexity] + +Preprocessing time: O(N), where N is the arity limit. +Compile time: O(N), where N is the effective arity of a call. +Run time: O(0) if the compiler inlines, O(1) otherwise. + +[endsect] + +[endsect] + + +[section Acknowledgements] + +As these utilities are factored out of the __boost_fusion__ functional module, +I want to thank Dan Marsden and Joel de Guzman for letting me participate in the +development of that great library in the first place. + +Further, I want to credit the authors of the references below, for their +in-depth investigation of the problem and the solution implemented here. + +Last but not least I want to thank Vesa Karnoven and Paul Mensonides for the +Boost Preprocessor library. Without it, I would have ended up with an external +code generator for this one. + +[endsect] + + +[section References] + +# [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem], + Peter Dimov, Howard E. Hinnant, David Abrahams, 2002 + +# [@http://www.boost.org/libs/utility/utility.htm#result_of Boost.ResultOf], + Douglas Gregor, 2004 + +# [@http://www.boost.org/doc/html/ref.html Boost.Ref], + Jaakko Jarvi, Peter Dimov, Douglas Gregor, David Abrahams, 1999-2002 + +[endsect] + diff --git a/forward/doc/html/boostbook.css b/forward/doc/html/boostbook.css new file mode 100644 index 0000000..858d43c --- /dev/null +++ b/forward/doc/html/boostbook.css @@ -0,0 +1,528 @@ +/*============================================================================= + Copyright (c) 2004 Joel de Guzman + http://spirit.sourceforge.net/ + + Use, modification and distribution is subject to 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) +=============================================================================*/ + +/*============================================================================= + Body defaults +=============================================================================*/ + + body + { + margin: 1em; + font-family: sans-serif; + } + +/*============================================================================= + Paragraphs +=============================================================================*/ + + p + { + text-align: left; + font-size: 10pt; + line-height: 1.15; + } + +/*============================================================================= + Program listings +=============================================================================*/ + + /* Code on paragraphs */ + p tt.computeroutput + { + font-size: 9pt; + } + + pre.synopsis + { + font-size: 90%; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + .programlisting, + .screen + { + font-size: 9pt; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + /* Program listings in tables don't get borders */ + td .programlisting, + td .screen + { + margin: 0pc 0pc 0pc 0pc; + padding: 0pc 0pc 0pc 0pc; + } + +/*============================================================================= + Headings +=============================================================================*/ + + h1, h2, h3, h4, h5, h6 + { + text-align: left; + margin: 1em 0em 0.5em 0em; + font-weight: bold; + } + + h1 { font: 140% } + h2 { font: bold 140% } + h3 { font: bold 130% } + h4 { font: bold 120% } + h5 { font: italic 110% } + h6 { font: italic 100% } + + /* Top page titles */ + title, + h1.title, + h2.title + h3.title, + h4.title, + h5.title, + h6.title, + .refentrytitle + { + font-weight: bold; + margin-bottom: 1pc; + } + + h1.title { font-size: 140% } + h2.title { font-size: 140% } + h3.title { font-size: 130% } + h4.title { font-size: 120% } + h5.title { font-size: 110% } + h6.title { font-size: 100% } + + .section h1 + { + margin: 0em 0em 0.5em 0em; + font-size: 140%; + } + + .section h2 { font-size: 140% } + .section h3 { font-size: 130% } + .section h4 { font-size: 120% } + .section h5 { font-size: 110% } + .section h6 { font-size: 100% } + + /* Code on titles */ + h1 tt.computeroutput { font-size: 140% } + h2 tt.computeroutput { font-size: 140% } + h3 tt.computeroutput { font-size: 130% } + h4 tt.computeroutput { font-size: 120% } + h5 tt.computeroutput { font-size: 110% } + h6 tt.computeroutput { font-size: 100% } + +/*============================================================================= + Author +=============================================================================*/ + + h3.author + { + font-size: 100% + } + +/*============================================================================= + Lists +=============================================================================*/ + + li + { + font-size: 10pt; + line-height: 1.3; + } + + /* Unordered lists */ + ul + { + text-align: left; + } + + /* Ordered lists */ + ol + { + text-align: left; + } + +/*============================================================================= + Links +=============================================================================*/ + + a + { + text-decoration: none; /* no underline */ + } + + a:hover + { + text-decoration: underline; + } + +/*============================================================================= + Spirit style navigation +=============================================================================*/ + + .spirit-nav + { + text-align: right; + } + + .spirit-nav a + { + color: white; + padding-left: 0.5em; + } + + .spirit-nav img + { + border-width: 0px; + } + +/*============================================================================= + Table of contents +=============================================================================*/ + + .toc + { + margin: 1pc 4% 0pc 4%; + padding: 0.1pc 1pc 0.1pc 1pc; + font-size: 80%; + line-height: 1.15; + } + + .boost-toc + { + float: right; + padding: 0.5pc; + } + +/*============================================================================= + Tables +=============================================================================*/ + + .table-title, + div.table p.title + { + margin-left: 4%; + padding-right: 0.5em; + padding-left: 0.5em; + } + + .informaltable table, + .table table + { + width: 92%; + margin-left: 4%; + margin-right: 4%; + } + + div.informaltable table, + div.table table + { + padding: 4px; + } + + /* Table Cells */ + div.informaltable table tr td, + div.table table tr td + { + padding: 0.5em; + text-align: left; + font-size: 9pt; + } + + div.informaltable table tr th, + div.table table tr th + { + padding: 0.5em 0.5em 0.5em 0.5em; + border: 1pt solid white; + font-size: 80%; + } + +/*============================================================================= + Blurbs +=============================================================================*/ + + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + font-size: 9pt; /* A little bit smaller than the main text */ + line-height: 1.2; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.0pc 0.5pc; + } + + div.sidebar img + { + padding: 1pt; + } + +/*============================================================================= + Callouts +=============================================================================*/ + .line_callout_bug img + { + float: left; + position:relative; + left: 4px; + top: -12px; + clear: left; + margin-left:-22px; + } + + .callout_bug img + { + } + +/*============================================================================= + Variable Lists +=============================================================================*/ + + /* Make the terms in definition lists bold */ + div.variablelist dl dt, + span.term + { + font-weight: bold; + font-size: 10pt; + } + + div.variablelist table tbody tr td + { + text-align: left; + vertical-align: top; + padding: 0em 2em 0em 0em; + font-size: 10pt; + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + + div.variablelist dl dt + { + margin-bottom: 0.2em; + } + + div.variablelist dl dd + { + margin: 0em 0em 0.5em 2em; + font-size: 10pt; + } + + div.variablelist table tbody tr td p, + div.variablelist dl dd p + { + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + +/*============================================================================= + Misc +=============================================================================*/ + + /* Title of books and articles in bibliographies */ + span.title + { + font-style: italic; + } + + span.underline + { + text-decoration: underline; + } + + span.strikethrough + { + text-decoration: line-through; + } + + /* Copyright, Legal Notice */ + div div.legalnotice p + { + text-align: left + } + +/*============================================================================= + Colors +=============================================================================*/ + + @media screen + { + /* Links */ + a + { + color: #005a9c; + } + + a:visited + { + color: #9c5a9c; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, + h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited + { + text-decoration: none; /* no underline */ + color: #000000; + } + + /* Syntax Highlighting */ + .keyword { color: #0000AA; } + .identifier { color: #000000; } + .special { color: #707070; } + .preprocessor { color: #402080; } + .char { color: teal; } + .comment { color: #800000; } + .string { color: teal; } + .number { color: teal; } + .white_bkd { background-color: #FFFFFF; } + .dk_grey_bkd { background-color: #999999; } + + /* Copyright, Legal Notice */ + .copyright + { + color: #666666; + font-size: small; + } + + div div.legalnotice p + { + color: #666666; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid #DCDCDC; + } + + .programlisting, + .screen + { + border: 1px solid #DCDCDC; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Blurbs */ + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + border: 1px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + } + + div.informaltable table tr th, + div.table table tr th + { + background-color: #F0F0F0; + border: 1px solid #DCDCDC; + } + + /* Misc */ + span.highlight + { + color: #00A000; + } + } + + @media print + { + /* Links */ + a + { + color: black; + } + + a:visited + { + color: black; + } + + .spirit-nav + { + display: none; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid gray; + } + + .programlisting, + .screen + { + border: 1px solid gray; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid gray; + } + + .informaltable table, + .table table + { + border: 1px solid gray; + border-collapse: collapse; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid gray; + } + + div.informaltable table tr th, + div.table table tr th + { + border: 1px solid gray; + } + + /* Misc */ + span.highlight + { + font-weight: bold; + } + } diff --git a/forward/doc/html/index.html b/forward/doc/html/index.html new file mode 100644 index 0000000..e82fe81 --- /dev/null +++ b/forward/doc/html/index.html @@ -0,0 +1,564 @@ + + + +Chapter 1. Boost.Functional/Forward 1.0 + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+
+
+

+Chapter 1. Boost.Functional/Forward 1.0

+

+Tobias Schwinger +

+
+
+

+ 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) +

+
+
+ +
+ +

+ boost::forward_adapter provides a reusable adapter + template for function objects. It forwards RValues as references to const, + while leaving LValues as-is. +

+
struct g // function object that only accept LValues
+{
+    template< typename T0, typename T1, typename T2 >
+    void operator()(T0 & t0, T1 & t1, T2 & t2) const;
+
+    typedef void result_type;
+};
+
+// Adapted version also accepts RValues and forwards
+// them as references to const, LValues as-is
+typedef boost::forward_adapter<g> f;
+
+

+ Another adapter, boost::lighweight_forward_adapter allows forwarding + with some help from the user accepting and unwrapping reference wrappers (see + Boost.Ref) for + reference arguments, const qualifying all other arguments. +

+

+ The target functions must be compatible with Boost.ResultOf, + and so are the adapters. +

+
+
+ +

+ Let's suppose we have some function f + that we can call like this: +

+
f(123,a_variable);
+
+

+ Now we want to write another, generic function g + that can be called the same way and returns some object that calls f with the same arguments. +

+
f(123,a_variable) == g(f,123,a_variable).call_f()
+
+

+ + Why + would we want to do it, anyway? +

+

+ Maybe we want to run f several + times. Or maybe we want to run it within another thread. Maybe we just want + to encapsulate the call expression for now, and then use it with other code + that allows to compose more complex expressions in order to decompose it with + C++ templates and have the compiler generate some machinery that eventually + calls f at runtime (in other + words; apply a technique that is commonly referred to as Expression Templates). +

+

+ + Now, + how do we do it? +

+

+ The bad news is: It's impossible. +

+

+ That is so because there is a slight difference between a variable and an expression + that evaluates to its value: Given +

+
int y;
+int const z = 0;
+
+

+ and +

+
template< typename T > void func1(T & x);
+
+

+ we can call +

+
func1(y); // x is a reference to a non-const object
+func1(z); // x is a reference to a const object
+
+

+ where +

+
func1(1); // fails to compile.
+
+

+ This way we can safely have func1 + store its reference argument and the compiler keeps us from storing a reference + to an object with temporary lifetime. +

+

+ It is important to realize that non-constness and whether an object binds to + a non-const reference parameter are two different properties. The latter is + the distinction between LValues and RValues. The names stem from the left hand + side and the right hand side of assignment expressions, thus LValues are typically + the ones you can assign to, and RValues the temporary results from the right + hand side expression. +

+
y = 1+2;        // a is LValue, 1+2 is the expression producing the RValue,
+// 1+2 = a;     // usually makes no sense. 
+
+func1(y);       // works, because y is an LValue
+// func1(1+2);  // fails to compile, because we only got an RValue.
+
+

+ If we add const qualification on the parameter, our function also accepts RValues: +

+
template< typename T > void func2(T const & x);
+
+// [...] function scope:
+func2(1); // x is a reference to a const temporary, object,
+func2(y); // x is a reference to a const object, while y is not const, and
+func2(z); // x is a reference to a const object, just like z.
+
+

+ In all cases, the argument x + in func2 is a const-qualified + LValue. We can use function overloading to identify non-const LValues: +

+
template< typename T > void func3(T const & x); // #1
+template< typename T > void func3(T & x);       // #2
+
+// [...] function scope:
+func3(1); // x is a reference to a const, temporary object in #1,
+func3(y); // x is a reference to a non-const object in #2, and
+func3(z); // x is a reference to a const object in #1.
+
+

+ Note that all arguments x in + the overloaded function func3 + are LValues. In fact, there is no way to transport RValues into a function + as-is in C++98. Also note that we can't distinguish between what used to be + a const qualified LValue and an RValue. +

+

+ That's as close as we can get to a generic forwarding function g as described above by the means of C++ + 98. See The + Forwarding Problem for a very detailed discussion including solutions + that require language changes. +

+

+ Now, for actually implementing it, we need 2^N overloads for N parameters (each + with and without const qualifier) for each number of arguments (that is 2^(Nmax+1) + - 2^Nmin). Right, that means the compile-time complexity is O(2^N), however + the factor is low so it works quite well for a reasonable number (< 10) + of arguments. +

+
+
+ + +
+ +

+ + Description +

+

+ Function object adapter template whose instances are callable with LValue + and RValue arguments. RValue arguments are forwarded as reference-to-const + typed LValues. +

+

+ An arity can be given as second, numeric non-type template argument to restrict + forwarding to a specific arity. If a third, numeric non-type template argument + is present, the second and third template argument are treated as minimum + and maximum arity, respectively. Specifying an arity can be helpful to improve + the readability of diagnostic messages and compile time performance. +

+

+ Boost.ResultOf + can be used to determine the result types of specific call expressions. +

+

+ + Header +

+
#include <boost/functional/forward_adapter.hpp>
+
+

+ + Synopsis +

+
namespace boost
+{
+    template< class Function,
+        int Arity_Or_MinArity = unspecified, int MaxArity = unspecified >
+    class forward_adapter;
+}
+
+
+

Notation

+
+
F
+

+ a possibly const qualified function object type or reference type thereof +

+
f
+

+ an object convertible to F +

+
FA
+

+ the type forward_adapter<F> +

+
fa
+

+ an instance object of FA, + initialized with f +

+
a0...aN
+

+ arguments to fa +

+
+
+

+ The result type of a target function invocation must be +

+
boost::result_of<F*(TA0 [const]&...TAN [const]&])>::type
+
+

+ where TA0...TAN denote the argument types of a0...aN. +

+

+ + Expression + Semantics +

+
++++ + + + + + + + + + + + + + + + + + + +
+

+ Expression +

+
+

+ Semantics +

+
+

+ FA(f) +

+
+

+ creates an adapter, initializes the target function with f. +

+
+

+ FA() +

+
+

+ creates an adapter, attempts to use F's + default constructor. +

+
+

+ fa(a0...aN) +

+
+

+ calls f with with + arguments a0...aN. +

+
+

+ + Limits +

+

+ The macro BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY can be defined to set + the maximum call arity. It defaults to 6. +

+

+ + Complexity +

+

+ Preprocessing time: O(2^N), where N is the arity limit. Compile time: O(2^N), + where N depends on the arity range. Run time: O(0) if the compiler inlines, + O(1) otherwise. +

+
+
+ +

+ + Description +

+

+ Function object adapter template whose instances are callable with LValue + and RValue arguments. All arguments are forwarded as reference-to-const typed + LValues, except for reference wrappers which are unwrapped and may yield + non-const LValues. +

+

+ An arity can be given as second, numeric non-type template argument to restrict + forwarding to a specific arity. If a third, numeric non-type template argument + is present, the second and third template argument are treated as minimum + and maximum arity, respectively. Specifying an arity can be helpful to improve + the readability of diagnostic messages and compile time performance. +

+

+ Boost.ResultOf + can be used to determine the result types of specific call expressions. +

+

+ + Header +

+
#include <boost/functional/lightweight_forward_adapter.hpp>
+
+

+ + Synopsis +

+
namespace boost
+{
+    template< class Function,
+        int Arity_Or_MinArity = unspecified, int MaxArity = unspecified >
+    struct lightweight_forward_adapter;
+}
+
+
+

Notation

+
+
F
+

+ a possibly const qualified function object type or reference type thereof +

+
f
+

+ an object convertible to F +

+
FA
+

+ the type lightweight_forward_adapter<F> +

+
fa
+

+ an instance of FA, initialized + with f +

+
a0...aN
+

+ arguments to fa +

+
+
+

+ The result type of a target function invocation must be +

+
boost::result_of<F*(TA0 [const]&...TAN [const]&])>::type
+
+

+ where TA0...TAN denote the argument types of a0...aN. +

+

+ + Expression + Semantics +

+
++++ + + + + + + + + + + + + + + + + + + +
+

+ Expression +

+
+

+ Semantics +

+
+

+ FA(f) +

+
+

+ creates an adapter, initializes the target function with f. +

+
+

+ FA() +

+
+

+ creates an adapter, attempts to use F's + default constructor. +

+
+

+ fa(a0...aN) +

+
+

+ calls f with with + const arguments a0...aN. If aI + is a reference wrapper it is unwrapped. +

+
+

+ + Limits +

+

+ The macro BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY can be defined + to set the maximum call arity. It defaults to 10. +

+

+ + Complexity +

+

+ Preprocessing time: O(N), where N is the arity limit. Compile time: O(N), + where N is the effective arity of a call. Run time: O(0) if the compiler + inlines, O(1) otherwise. +

+
+
+
+ +

+ As these utilities are factored out of the Boost.Fusion + functional module, I want to thank Dan Marsden and Joel de Guzman for letting + me participate in the development of that great library in the first place. +

+

+ Further, I want to credit the authors of the references below, for their in-depth + investigation of the problem and the solution implemented here. +

+

+ Last but not least I want to thank Vesa Karnoven and Paul Mensonides for the + Boost Preprocessor library. Without it, I would have ended up with an external + code generator for this one. +

+
+
+ +
    +
  1. +The + Forwarding Problem, Peter Dimov, Howard E. Hinnant, David Abrahams, + 2002 +
  2. +
  3. +Boost.ResultOf, + Douglas Gregor, 2004 +
  4. +
  5. +Boost.Ref, Jaakko + Jarvi, Peter Dimov, Douglas Gregor, David Abrahams, 1999-2002 +
  6. +
+
+
+ + + +

Last revised: November 01, 2008 at 19:58:50 GMT

+
+
+ + diff --git a/forward/test/Jamfile b/forward/test/Jamfile new file mode 100644 index 0000000..56c01d3 --- /dev/null +++ b/forward/test/Jamfile @@ -0,0 +1,20 @@ + +# (C) Copyright Tobias Schwinger +# +# Use modification and distribution are subject to the boost Software License, +# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt). + +import testing ; + +project forward-tests + : requirements + /Users/tosh/Lab/boost + /Users/tosh/Lab/deploy/x_files/forward + ; + +test-suite functional/forward + : + [ run forward_adapter.cpp ] + [ run lightweight_forward_adapter.cpp ] + ; + diff --git a/forward/test/forward_adapter.cpp b/forward/test/forward_adapter.cpp new file mode 100644 index 0000000..6956d4e --- /dev/null +++ b/forward/test/forward_adapter.cpp @@ -0,0 +1,127 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are subject to 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). +==============================================================================*/ + +#include + +#ifdef BOOST_MSVC +# pragma warning(disable: 4244) // no conversion warnings, please +#endif + +#include +#include + +#include + +#include +#include + +#include + +template +class test_func : public Base +{ + int val; +public: + test_func(int v) : val(v) { } + + template + test_func(test_func const & that) + : val(that.val) + { } + + template friend class test_func; + + int operator()(int & l, int const & r) const + { + return l=r+val; + } + long operator()(int & l, int const & r) + { + return -(l=r+val); + } + + template + struct result + { + typedef void type; + }; + + // ensure result_of argument types are what's expected + // note: this is *not* how client code should look like + template + struct result< Self const(int&,int const&) > { typedef int type; }; + + template + struct result< Self(int&,int const&) > { typedef long type; }; + + template + struct result< Self(int&,int&) > { typedef char type; }; +}; + +enum { int_, long_, char_ }; + +int type_of(int) { return int_; } +int type_of(long) { return long_; } +int type_of(char) { return char_; } + +int main() +{ + { + using boost::is_same; + using boost::result_of; + typedef boost::forward_adapter< test_func<> > f; + + // lvalue,rvalue + BOOST_TEST(( is_same< + result_of< f(int&, int) >::type, long >::value )); + BOOST_TEST(( is_same< + result_of< f const (int&, int) >::type, int >::value )); + // lvalue,const lvalue + BOOST_TEST(( is_same< + result_of< f(int&, int const &) >::type, long >::value )); + BOOST_TEST(( is_same< + result_of< f const (int&, int const &) >::type, int >::value )); + // lvalue,lvalue + BOOST_TEST(( is_same< + result_of< f(int&, int&) >::type, char >::value )); + BOOST_TEST(( is_same< + result_of< f const (int&, int&) >::type, char >::value )); + } + { + using boost::noncopyable; + using boost::forward_adapter; + + int x = 0; + test_func f(7); + forward_adapter< test_func<> > func(f); + forward_adapter< test_func & > func_ref(f); + forward_adapter< test_func & > const func_ref_c(f); + forward_adapter< test_func<> const > func_c(f); + forward_adapter< test_func<> > const func_c2(f); + forward_adapter< test_func const & > func_c_ref(f); + + BOOST_TEST( type_of( func(x,1) ) == long_ ); + BOOST_TEST( type_of( func_ref(x,1) ) == long_ ); + BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ ); + BOOST_TEST( type_of( func_c(x,1) ) == int_ ); + BOOST_TEST( type_of( func_c2(x,1) ) == int_ ); + BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ ); + BOOST_TEST( type_of( func(x,x) ) == char_ ); + + BOOST_TEST( func(x,1) == -8 ); + BOOST_TEST( func_ref(x,1) == -8 ); + BOOST_TEST( func_ref_c(x,1) == -8 ); + BOOST_TEST( func_c(x,1) == 8 ); + BOOST_TEST( func_c2(x,1) == 8 ); + BOOST_TEST( func_c_ref(x,1) == 8 ); + } + + return boost::report_errors(); +} + + diff --git a/forward/test/lightweight_forward_adapter.cpp b/forward/test/lightweight_forward_adapter.cpp new file mode 100644 index 0000000..7b0d304 --- /dev/null +++ b/forward/test/lightweight_forward_adapter.cpp @@ -0,0 +1,128 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are subject to 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). +==============================================================================*/ + +#include + +#ifdef BOOST_MSVC +# pragma warning(disable: 4244) // no conversion warnings, please +#endif + +#include +#include + +#include + +#include +#include + +#include + +template +class test_func : public Base +{ + int val; +public: + test_func(int v) : val(v) { } + + template + test_func(test_func const & that) + : val(that.val) + { } + + template friend class test_func; + + int operator()(int & l, int const & r) const + { + return l=r+val; + } + long operator()(int & l, int const & r) + { + return -(l=r+val); + } + + template + struct result + { + typedef void type; + }; + + // ensure result_of argument types are what's expected + // note: this is *not* how client code should look like + template + struct result< Self const(int&,int const&) > { typedef int type; }; + + template + struct result< Self(int&,int const&) > { typedef long type; }; + + template + struct result< Self(int&,int&) > { typedef char type; }; +}; + +enum { int_, long_, char_ }; + +int type_of(int) { return int_; } +int type_of(long) { return long_; } +int type_of(char) { return char_; } + +int main() +{ + { + using boost::is_same; + using boost::result_of; + typedef boost::lightweight_forward_adapter< test_func<> > f; + typedef boost::reference_wrapper ref; + typedef boost::reference_wrapper cref; + + // lvalue,rvalue + BOOST_TEST(( is_same< + result_of< f(ref, int) >::type, long >::value )); + BOOST_TEST(( is_same< + result_of< f const (ref, int) >::type, int >::value )); + // lvalue,const lvalue + BOOST_TEST(( is_same< + result_of< f(ref, cref) >::type, long >::value )); + BOOST_TEST(( is_same< + result_of< f const (ref, cref) >::type, int >::value )); + // lvalue,lvalue + BOOST_TEST(( is_same< + result_of< f(ref, ref) >::type, char >::value )); + BOOST_TEST(( is_same< + result_of< f const (ref, ref) >::type, char >::value )); + } + { + using boost::noncopyable; + using boost::lightweight_forward_adapter; + + int v = 0; boost::reference_wrapper x(v); + test_func f(7); + lightweight_forward_adapter< test_func<> > func(f); + lightweight_forward_adapter< test_func & > func_ref(f); + lightweight_forward_adapter< test_func & > const func_ref_c(f); + lightweight_forward_adapter< test_func<> const > func_c(f); + lightweight_forward_adapter< test_func<> > const func_c2(f); + lightweight_forward_adapter< test_func const & > func_c_ref(f); + + BOOST_TEST( type_of( func(x,1) ) == long_ ); + BOOST_TEST( type_of( func_ref(x,1) ) == long_ ); + BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ ); + BOOST_TEST( type_of( func_c(x,1) ) == int_ ); + BOOST_TEST( type_of( func_c2(x,1) ) == int_ ); + BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ ); + BOOST_TEST( type_of( func(x,x) ) == char_ ); + + BOOST_TEST( func(x,1) == -8 ); + BOOST_TEST( func_ref(x,1) == -8 ); + BOOST_TEST( func_ref_c(x,1) == -8 ); + BOOST_TEST( func_c(x,1) == 8 ); + BOOST_TEST( func_c2(x,1) == 8 ); + BOOST_TEST( func_c_ref(x,1) == 8 ); + } + + return boost::report_errors(); +} + From ba511c8939b7ac4497359c9609e4c48fb27f4d2a Mon Sep 17 00:00:00 2001 From: Tobias Schwinger Date: Thu, 27 Nov 2008 15:32:23 +0000 Subject: [PATCH 03/82] removes absolute paths (from development machine) [SVN r49958] --- factory/test/Jamfile | 3 --- forward/test/Jamfile | 3 --- 2 files changed, 6 deletions(-) diff --git a/factory/test/Jamfile b/factory/test/Jamfile index 4abdb68..6c4f6eb 100644 --- a/factory/test/Jamfile +++ b/factory/test/Jamfile @@ -7,9 +7,6 @@ import testing ; project factory-tests - : requirements - /Users/tosh/Lab/boost - /Users/tosh/Lab/deploy/x_files/factory ; test-suite functional/factory diff --git a/forward/test/Jamfile b/forward/test/Jamfile index 56c01d3..9169456 100644 --- a/forward/test/Jamfile +++ b/forward/test/Jamfile @@ -7,9 +7,6 @@ import testing ; project forward-tests - : requirements - /Users/tosh/Lab/boost - /Users/tosh/Lab/deploy/x_files/forward ; test-suite functional/forward From d7fb4371925c5578eb8c0c229d9cb5bb1100422e Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 8 Jan 2009 13:37:33 +0000 Subject: [PATCH 04/82] Rename parameter to avoid Visual C++ warning about clash with boost::array. Fixes #2643 [SVN r50514] --- include/boost/functional/hash/hash.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 9de4990..b789ad6 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -58,10 +58,10 @@ namespace boost #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) template< class T, unsigned N > - std::size_t hash_value(const T (&array)[N]); + std::size_t hash_value(const T (&x)[N]); template< class T, unsigned N > - std::size_t hash_value(T (&array)[N]); + std::size_t hash_value(T (&x)[N]); #endif std::size_t hash_value(float v); @@ -281,15 +281,15 @@ namespace boost #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) template< class T, unsigned N > - inline std::size_t hash_value(const T (&array)[N]) + inline std::size_t hash_value(const T (&x)[N]) { - return hash_range(array, array + N); + return hash_range(x, x + N); } template< class T, unsigned N > - inline std::size_t hash_value(T (&array)[N]) + inline std::size_t hash_value(T (&x)[N]) { - return hash_range(array, array + N); + return hash_range(x, x + N); } #endif From 650b8b122078812712684bdcbfc082b50a97e6d3 Mon Sep 17 00:00:00 2001 From: John Maddock Date: Sun, 8 Feb 2009 16:59:14 +0000 Subject: [PATCH 05/82] Add Jamfile to build PDF versions of all the docs. Tweaked some existing Jamfiles so that PDF build finds all the necessary image files etc. Tweaked fo.xsl to provide more options by default, and improve formatting. [SVN r51104] --- hash/doc/Jamfile.v2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hash/doc/Jamfile.v2 b/hash/doc/Jamfile.v2 index 731a228..75922f2 100644 --- a/hash/doc/Jamfile.v2 +++ b/hash/doc/Jamfile.v2 @@ -5,7 +5,7 @@ xml hash : hash.qbk ; boostbook standalone : hash : - admon.graphics.path=images/ + html:admon.graphics.path=images/ navig.graphics.path=images/ html.stylesheet=boostbook.css boost.root=../../../../.. From 9df97a85973586234ff5fd287571cd408298f625 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 15 Feb 2009 19:32:04 +0000 Subject: [PATCH 06/82] Use the new 'boost:' links for the hash, unordered and quickbook documentation. [SVN r51262] --- hash/doc/intro.qbk | 6 +++--- hash/doc/portability.qbk | 2 +- hash/doc/tutorial.qbk | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hash/doc/intro.qbk b/hash/doc/intro.qbk index bba5de3..b027719 100644 --- a/hash/doc/intro.qbk +++ b/hash/doc/intro.qbk @@ -13,11 +13,11 @@ TR1]] [def __unordered__ [link unordered Boost.Unordered]] [def __intrusive__ [link intrusive.unordered_set_unordered_multiset Boost.Intrusive]] -[def __multi-index__ [@../../libs/multi_index/doc/index.html +[def __multi-index__ [@boost:/libs/multi_index/doc/index.html Boost Multi-Index Containers Library]] -[def __multi-index-short__ [@../../libs/multi_index/doc/index.html +[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html Boost.MultiIndex]] -[def __bimap__ [@../../libs/bimap/index.html Boost.Bimap]] +[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]] [def __issues__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf Library Extension Technical Report Issues List]] diff --git a/hash/doc/portability.qbk b/hash/doc/portability.qbk index e9100ce..fabb298 100644 --- a/hash/doc/portability.qbk +++ b/hash/doc/portability.qbk @@ -88,7 +88,7 @@ boost namespace: } Full code for this example is at -[@../../libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp]. +[@boost:/libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp]. [h2 Other Issues] diff --git a/hash/doc/tutorial.qbk b/hash/doc/tutorial.qbk index eaf9a95..b2f79f5 100644 --- a/hash/doc/tutorial.qbk +++ b/hash/doc/tutorial.qbk @@ -3,7 +3,7 @@ / 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) ] -[def __multi-index-short__ [@../../libs/multi_index/doc/index.html +[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html Boost.MultiIndex]] [section:tutorial Tutorial] @@ -110,9 +110,9 @@ And you can now use [classref boost::hash] with book: assert(books.find(dandelion) == books.end()); The full example can be found in: -[@../../libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.hpp] +[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.hpp] and -[@../../libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp]. +[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp]. [tip When writing a hash function, first look at how the equality function works. @@ -170,7 +170,7 @@ of point, it can be repeatedly called for any number of elements. It calls [funcref boost::hash_value hash_value] on the supplied element, and combines it with the seed. Full code for this example is at -[@../../libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp]. +[@boost:/libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp]. [note When using [funcref boost::hash_combine] the order of the From 2c291488b62b0a4cc21270b2ce8eb7b0d406e2de Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 15 Feb 2009 19:32:19 +0000 Subject: [PATCH 07/82] Don't copy images for the standalone hash and unordered documentation, was only really required before the libraries were integrated into boost. [SVN r51263] --- hash/doc/Jamfile.v2 | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/hash/doc/Jamfile.v2 b/hash/doc/Jamfile.v2 index 75922f2..a191e02 100644 --- a/hash/doc/Jamfile.v2 +++ b/hash/doc/Jamfile.v2 @@ -5,24 +5,14 @@ xml hash : hash.qbk ; boostbook standalone : hash : - html:admon.graphics.path=images/ - navig.graphics.path=images/ - html.stylesheet=boostbook.css + html.stylesheet=../../../../../doc/html/boostbook.css boost.root=../../../../.. boost.libraries=../../../../libraries.htm + navig.graphics=1 + chunk.first.sections=1 chunk.section.depth=2 generate.section.toc.level=2 toc.section.depth=1 toc.max.depth=1 - - css - images ; - -install css : [ glob $(BOOST_ROOT)/doc/src/*.css ] - : html ; -install images : [ glob $(BOOST_ROOT)/doc/src/images/*.png ] - : html/images ; -explicit css ; -explicit images ; From af6eb9fa6f65c7162fa1b77944a7510f99d87dcd Mon Sep 17 00:00:00 2001 From: John Maddock Date: Tue, 17 Feb 2009 10:05:58 +0000 Subject: [PATCH 08/82] Add PDF generation options to fix external links to point to the web site. Added a few more Boostbook based libs that were missed first time around. Fixed PDF naming issues. [SVN r51284] --- hash/doc/Jamfile.v2 | 1 + 1 file changed, 1 insertion(+) diff --git a/hash/doc/Jamfile.v2 b/hash/doc/Jamfile.v2 index a191e02..acdf5ec 100644 --- a/hash/doc/Jamfile.v2 +++ b/hash/doc/Jamfile.v2 @@ -15,4 +15,5 @@ boostbook standalone : hash : generate.section.toc.level=2 toc.section.depth=1 toc.max.depth=1 + pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/libs/functional/hash/doc/html ; From 23956c03601a62bee7289af1c3be08a34a8dc889 Mon Sep 17 00:00:00 2001 From: Tobias Schwinger Date: Fri, 20 Feb 2009 23:36:42 +0000 Subject: [PATCH 09/82] straightens visibility issues [SVN r51359] --- include/boost/functional/factory.hpp | 2 +- include/boost/functional/forward_adapter.hpp | 5 ++--- include/boost/functional/lightweight_forward_adapter.hpp | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/boost/functional/factory.hpp b/include/boost/functional/factory.hpp index d97fea5..6692427 100644 --- a/include/boost/functional/factory.hpp +++ b/include/boost/functional/factory.hpp @@ -58,7 +58,7 @@ namespace boost template< class Pointer, class Allocator, factory_alloc_propagation AP > class factory - : Allocator::template rebind< typename boost::pointee< + : private Allocator::template rebind< typename boost::pointee< typename boost::remove_cv::type >::type >::other { public: diff --git a/include/boost/functional/forward_adapter.hpp b/include/boost/functional/forward_adapter.hpp index 473b2a2..0a4bc36 100644 --- a/include/boost/functional/forward_adapter.hpp +++ b/include/boost/functional/forward_adapter.hpp @@ -45,7 +45,6 @@ namespace boost { template< typename Sig > struct apply; - private: // Utility metafunction for qualification adjustment on arguments template< typename T > struct q { typedef T const t; }; template< typename T > struct q { typedef T const t; }; @@ -73,7 +72,7 @@ namespace boost template< typename Function, int Arity_Or_MinArity, int MaxArity > class forward_adapter : public BOOST_TMP_MACRO(Function,Function,Function const) - , Function + , private Function { public: forward_adapter(Function const& f = Function()) @@ -95,7 +94,7 @@ namespace boost template< typename Function, int Arity_Or_MinArity, int MaxArity > class forward_adapter< Function const, Arity_Or_MinArity, MaxArity > : public BOOST_TMP_MACRO(Function const, Function const, Function const) - , Function + , private Function { public: forward_adapter(Function const& f = Function()) diff --git a/include/boost/functional/lightweight_forward_adapter.hpp b/include/boost/functional/lightweight_forward_adapter.hpp index 37961ca..98509a8 100644 --- a/include/boost/functional/lightweight_forward_adapter.hpp +++ b/include/boost/functional/lightweight_forward_adapter.hpp @@ -46,7 +46,6 @@ namespace boost { template< typename Sig > struct apply; - private: // Utility metafunction for argument transform template< typename T > struct x { typedef T const& t; }; template< typename T > struct x< boost::reference_wrapper > @@ -77,7 +76,7 @@ namespace boost template< typename Function, int Arity_Or_MinArity, int MaxArity > class lightweight_forward_adapter : public BOOST_TMP_MACRO(Function,Function,Function const) - , Function + , private Function { public: lightweight_forward_adapter(Function const& f = Function()) @@ -100,7 +99,7 @@ namespace boost class lightweight_forward_adapter< Function const, Arity_Or_MinArity, MaxArity > : public BOOST_TMP_MACRO(Function const, Function const, Function const) - , Function + , private Function { public: lightweight_forward_adapter(Function const& f = Function()) From de1a390d437a4fad35e6e5b69b8c37886edece53 Mon Sep 17 00:00:00 2001 From: Tobias Schwinger Date: Sat, 21 Feb 2009 15:40:34 +0000 Subject: [PATCH 10/82] adds index.html for redirection to the documentation [SVN r51365] --- factory/index.html | 15 +++++++++++++++ forward/index.html | 15 +++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 factory/index.html create mode 100644 forward/index.html diff --git a/factory/index.html b/factory/index.html new file mode 100644 index 0000000..1803029 --- /dev/null +++ b/factory/index.html @@ -0,0 +1,15 @@ + + + + + + + Automatic redirection failed, click this + link  
+

© Copyright Tobias Schwinger, 2009

+

Distributed under the Boost Software License, Version 1.0. (See + accompanying file + LICENSE_1_0.txt or copy at + www.boost.org/LICENSE_1_0.txt)

+ + diff --git a/forward/index.html b/forward/index.html new file mode 100644 index 0000000..1803029 --- /dev/null +++ b/forward/index.html @@ -0,0 +1,15 @@ + + + + + + + Automatic redirection failed, click this + link  
+

© Copyright Tobias Schwinger, 2009

+

Distributed under the Boost Software License, Version 1.0. (See + accompanying file + LICENSE_1_0.txt or copy at + www.boost.org/LICENSE_1_0.txt)

+ + From eac8fab2cd3216096d05c4c631e13ef138c5c4fa Mon Sep 17 00:00:00 2001 From: Tobias Schwinger Date: Sun, 22 Feb 2009 06:21:34 +0000 Subject: [PATCH 11/82] prevents vicious type deduction for array arguments [SVN r51378] --- include/boost/functional/lightweight_forward_adapter.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/boost/functional/lightweight_forward_adapter.hpp b/include/boost/functional/lightweight_forward_adapter.hpp index 98509a8..d21ac42 100644 --- a/include/boost/functional/lightweight_forward_adapter.hpp +++ b/include/boost/functional/lightweight_forward_adapter.hpp @@ -231,7 +231,8 @@ namespace boost template< BOOST_PP_ENUM_PARAMS(N,typename T) > inline typename lightweight_forward_adapter_result::template apply< - MD const (BOOST_PP_ENUM_PARAMS(N,T)) >::type + MD const (BOOST_PP_ENUM_BINARY_PARAMS(N, + T,const& BOOST_PP_INTERCEPT)) >::type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const { typedef lightweight_forward_adapter_result _; @@ -240,7 +241,8 @@ namespace boost } template< BOOST_PP_ENUM_PARAMS(N,typename T) > inline typename lightweight_forward_adapter_result::template apply< - MD (BOOST_PP_ENUM_PARAMS(N,T)) >::type + MD (BOOST_PP_ENUM_BINARY_PARAMS(N, + T,const& BOOST_PP_INTERCEPT)) >::type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) { typedef lightweight_forward_adapter_result _; From 453a20706f3e220a0f3375f77f2570f2be41e227 Mon Sep 17 00:00:00 2001 From: Tobias Schwinger Date: Sun, 22 Feb 2009 16:27:22 +0000 Subject: [PATCH 12/82] adds missing template parameters for partial specialisations [SVN r51392] --- include/boost/functional/factory.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/functional/factory.hpp b/include/boost/functional/factory.hpp index 6692427..4aa4267 100644 --- a/include/boost/functional/factory.hpp +++ b/include/boost/functional/factory.hpp @@ -41,8 +41,8 @@ namespace boost //----- ---- --- -- - - - - - template< typename Pointer > - class factory + template< typename Pointer, factory_alloc_propagation AP > + class factory { public: typedef typename boost::remove_cv::type result_type; @@ -124,8 +124,8 @@ namespace boost # undef BOOST_TMP_MACRO }; - template< typename Pointer, class Allocator > - class factory; + template< typename Pointer, class Allocator, factory_alloc_propagation AP > + class factory; // forbidden, would create a dangling reference } From ca3563cfaf491453996d6f0c0b25d479fc63e5b4 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 22 Feb 2009 23:49:51 +0000 Subject: [PATCH 13/82] Fix the hash dirname. [SVN r51407] --- hash/doc/hash.qbk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hash/doc/hash.qbk b/hash/doc/hash.qbk index 39d6d97..b734fb4 100644 --- a/hash/doc/hash.qbk +++ b/hash/doc/hash.qbk @@ -6,7 +6,7 @@ defined types] [category higher-order] [id hash] - [dirname hash] + [dirname functional/hash] [license Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at From ac3aa4971afc084f341013602fc486a415431697 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 8 Mar 2009 09:45:11 +0000 Subject: [PATCH 14/82] Move hash_fwd into the hash subdirectory. I should have done this in the last release. But now all of the hash implementation is in the hash subdirectory. [SVN r51645] --- include/boost/functional/hash/hash.hpp | 2 +- include/boost/functional/hash/hash_fwd.hpp | 40 ++++++++++++++++++++++ include/boost/functional/hash_fwd.hpp | 31 +---------------- 3 files changed, 42 insertions(+), 31 deletions(-) create mode 100644 include/boost/functional/hash/hash_fwd.hpp diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index b789ad6..8cd5a60 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -10,7 +10,7 @@ #if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP) #define BOOST_FUNCTIONAL_HASH_HASH_HPP -#include +#include #include #include #include diff --git a/include/boost/functional/hash/hash_fwd.hpp b/include/boost/functional/hash/hash_fwd.hpp new file mode 100644 index 0000000..8b7d8e5 --- /dev/null +++ b/include/boost/functional/hash/hash_fwd.hpp @@ -0,0 +1,40 @@ + +// Copyright 2005-2008 Daniel James. +// 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) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP) +#define BOOST_FUNCTIONAL_HASH_FWD_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +namespace boost +{ + template struct hash; + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template void hash_combine(std::size_t& seed, T& v); +#else + template void hash_combine(std::size_t& seed, T const& v); +#endif + + template std::size_t hash_range(It, It); + template void hash_range(std::size_t&, It, It); + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) + template inline std::size_t hash_range(T*, T*); + template inline void hash_range(std::size_t&, T*, T*); +#endif +} + +#endif diff --git a/include/boost/functional/hash_fwd.hpp b/include/boost/functional/hash_fwd.hpp index 8b7d8e5..51b8d09 100644 --- a/include/boost/functional/hash_fwd.hpp +++ b/include/boost/functional/hash_fwd.hpp @@ -7,34 +7,5 @@ // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf // issue 6.18. -#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP) -#define BOOST_FUNCTIONAL_HASH_FWD_HPP +#include -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include -#include -#include - -namespace boost -{ - template struct hash; - -#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) - template void hash_combine(std::size_t& seed, T& v); -#else - template void hash_combine(std::size_t& seed, T const& v); -#endif - - template std::size_t hash_range(It, It); - template void hash_range(std::size_t&, It, It); - -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) - template inline std::size_t hash_range(T*, T*); - template inline void hash_range(std::size_t&, T*, T*); -#endif -} - -#endif From e27d60777be08a139e921560f36ee38589f3ba56 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 8 Mar 2009 09:45:30 +0000 Subject: [PATCH 15/82] Remove deprecated headers. Fixes #2412. [SVN r51646] --- hash/test/Jamfile.v2 | 1 - hash/test/hash_deprecated_headers.cpp | 26 ------------------------ include/boost/functional/hash/deque.hpp | 7 ------- include/boost/functional/hash/list.hpp | 7 ------- include/boost/functional/hash/map.hpp | 7 ------- include/boost/functional/hash/pair.hpp | 7 ------- include/boost/functional/hash/set.hpp | 7 ------- include/boost/functional/hash/vector.hpp | 7 ------- 8 files changed, 69 deletions(-) delete mode 100644 hash/test/hash_deprecated_headers.cpp delete mode 100644 include/boost/functional/hash/deque.hpp delete mode 100644 include/boost/functional/hash/list.hpp delete mode 100644 include/boost/functional/hash/map.hpp delete mode 100644 include/boost/functional/hash/pair.hpp delete mode 100644 include/boost/functional/hash/set.hpp delete mode 100644 include/boost/functional/hash/vector.hpp diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index 2f771b3..ff149a7 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -40,7 +40,6 @@ test-suite functional/hash [ compile-fail hash_no_ext_fail_test.cpp ] [ run hash_no_ext_macro_1.cpp ] [ run hash_no_ext_macro_2.cpp ] - [ compile-fail hash_deprecated_headers.cpp ] ; build-project ../examples ; diff --git a/hash/test/hash_deprecated_headers.cpp b/hash/test/hash_deprecated_headers.cpp deleted file mode 100644 index 6a97e70..0000000 --- a/hash/test/hash_deprecated_headers.cpp +++ /dev/null @@ -1,26 +0,0 @@ - -// Copyright 2007-2008 Daniel James. -// 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) - -// All these headers are meant output a warning, but not cause the compilation -// to fail. - -#include -#include -#include -#include -#include -#include - -// And a quick check that the hash library was included. -// Strictly speaking I should do this once for each header -// but that would just be wasting the testing resources. - -#include - -int main() { - std::vector v; - boost::hash > x; - x(v); -} diff --git a/include/boost/functional/hash/deque.hpp b/include/boost/functional/hash/deque.hpp deleted file mode 100644 index 0dd8b99..0000000 --- a/include/boost/functional/hash/deque.hpp +++ /dev/null @@ -1,7 +0,0 @@ - -// Copyright 2005-2008 Daniel James. -// 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) - -#error "boost/functional/hash/deque.hpp is no longer supported, use boost/functional/hash.hpp instead." -#include diff --git a/include/boost/functional/hash/list.hpp b/include/boost/functional/hash/list.hpp deleted file mode 100644 index 61e7b6d..0000000 --- a/include/boost/functional/hash/list.hpp +++ /dev/null @@ -1,7 +0,0 @@ - -// Copyright 2005-2008 Daniel James. -// 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) - -#error "boost/functional/hash/list.hpp is no longer supported, use boost/functional/hash.hpp instead." -#include diff --git a/include/boost/functional/hash/map.hpp b/include/boost/functional/hash/map.hpp deleted file mode 100644 index 2dcd58b..0000000 --- a/include/boost/functional/hash/map.hpp +++ /dev/null @@ -1,7 +0,0 @@ - -// Copyright 2005-2008 Daniel James. -// 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) - -#error "boost/functional/hash/map.hpp is no longer supported, use boost/functional/hash.hpp instead." -#include diff --git a/include/boost/functional/hash/pair.hpp b/include/boost/functional/hash/pair.hpp deleted file mode 100644 index d771460..0000000 --- a/include/boost/functional/hash/pair.hpp +++ /dev/null @@ -1,7 +0,0 @@ - -// Copyright 2005-2008 Daniel James. -// 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) - -#error "boost/functional/hash/pair.hpp is no longer supported, use boost/functional/hash.hpp instead." -#include diff --git a/include/boost/functional/hash/set.hpp b/include/boost/functional/hash/set.hpp deleted file mode 100644 index e85f80d..0000000 --- a/include/boost/functional/hash/set.hpp +++ /dev/null @@ -1,7 +0,0 @@ - -// Copyright 2005-2008 Daniel James. -// 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) - -#error "boost/functional/hash/set.hpp is no longer supported, use boost/functional/hash.hpp instead." -#include diff --git a/include/boost/functional/hash/vector.hpp b/include/boost/functional/hash/vector.hpp deleted file mode 100644 index 7fe2be6..0000000 --- a/include/boost/functional/hash/vector.hpp +++ /dev/null @@ -1,7 +0,0 @@ - -// Copyright 2005-2008 Daniel James. -// 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) - -#error "boost/functional/hash/vector.hpp is no longer supported, use boost/functional/hash.hpp instead." -#include From 1c44695b876fca432f5a06ee9511910770fc38d3 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 9 Mar 2009 20:56:23 +0000 Subject: [PATCH 16/82] Update copyright dates in hash and unordered. [SVN r51667] --- hash/doc/ref.xml | 2 +- hash/examples/books.cpp | 2 +- hash/examples/books.hpp | 2 +- hash/examples/portable.cpp | 2 +- hash/test/compile_time.hpp | 2 +- hash/test/config.hpp | 2 +- hash/test/container_fwd_test.cpp | 2 +- hash/test/hash_built_in_array_test.cpp | 2 +- hash/test/hash_complex_test.cpp | 2 +- hash/test/hash_custom_test.cpp | 2 +- hash/test/hash_deque_test.cpp | 2 +- hash/test/hash_float_test.cpp | 2 +- hash/test/hash_float_test.hpp | 2 +- hash/test/hash_friend_test.cpp | 2 +- hash/test/hash_function_pointer_test.cpp | 2 +- hash/test/hash_fwd_test.hpp | 2 +- hash/test/hash_fwd_test_1.cpp | 2 +- hash/test/hash_fwd_test_2.cpp | 2 +- hash/test/hash_global_namespace_test.cpp | 2 +- hash/test/hash_list_test.cpp | 2 +- hash/test/hash_long_double_test.cpp | 2 +- hash/test/hash_map_test.cpp | 2 +- hash/test/hash_map_test.hpp | 2 +- hash/test/hash_no_ext_fail_test.cpp | 2 +- hash/test/hash_no_ext_macro_1.cpp | 2 +- hash/test/hash_no_ext_macro_2.cpp | 2 +- hash/test/hash_number_test.cpp | 2 +- hash/test/hash_pointer_test.cpp | 2 +- hash/test/hash_range_test.cpp | 2 +- hash/test/hash_sequence_test.hpp | 2 +- hash/test/hash_set_test.cpp | 2 +- hash/test/hash_set_test.hpp | 2 +- hash/test/hash_string_test.cpp | 2 +- hash/test/hash_value_array_test.cpp | 2 +- hash/test/hash_vector_test.cpp | 2 +- hash/test/link_ext_test.cpp | 2 +- hash/test/link_no_ext_test.cpp | 2 +- hash/test/link_test.cpp | 2 +- hash/test/link_test_2.cpp | 2 +- include/boost/functional/hash.hpp | 6 +----- include/boost/functional/hash/detail/float_functions.hpp | 2 +- include/boost/functional/hash/detail/hash_float.hpp | 6 +----- include/boost/functional/hash/extensions.hpp | 2 +- include/boost/functional/hash/hash.hpp | 2 +- include/boost/functional/hash/hash_fwd.hpp | 2 +- include/boost/functional/hash_fwd.hpp | 6 +----- 46 files changed, 46 insertions(+), 58 deletions(-) diff --git a/hash/doc/ref.xml b/hash/doc/ref.xml index 6bb32ce..1fe97d3 100644 --- a/hash/doc/ref.xml +++ b/hash/doc/ref.xml @@ -1,6 +1,6 @@ diff --git a/hash/examples/books.cpp b/hash/examples/books.cpp index 2615564..d54b353 100644 --- a/hash/examples/books.cpp +++ b/hash/examples/books.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/examples/books.hpp b/hash/examples/books.hpp index c0cf414..ac87a9d 100644 --- a/hash/examples/books.hpp +++ b/hash/examples/books.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/examples/portable.cpp b/hash/examples/portable.cpp index 98026c1..88f2fc7 100644 --- a/hash/examples/portable.cpp +++ b/hash/examples/portable.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/compile_time.hpp b/hash/test/compile_time.hpp index 873df13..bd86038 100644 --- a/hash/test/compile_time.hpp +++ b/hash/test/compile_time.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/config.hpp b/hash/test/config.hpp index 9ef55b7..0f84cc7 100644 --- a/hash/test/config.hpp +++ b/hash/test/config.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/container_fwd_test.cpp b/hash/test/container_fwd_test.cpp index bae96c7..87f5b90 100644 --- a/hash/test/container_fwd_test.cpp +++ b/hash/test/container_fwd_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_built_in_array_test.cpp b/hash/test/hash_built_in_array_test.cpp index 3d17f28..9c91799 100644 --- a/hash/test/hash_built_in_array_test.cpp +++ b/hash/test/hash_built_in_array_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_complex_test.cpp b/hash/test/hash_complex_test.cpp index e941fdd..dd519c9 100644 --- a/hash/test/hash_complex_test.cpp +++ b/hash/test/hash_complex_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_custom_test.cpp b/hash/test/hash_custom_test.cpp index 09e8ad8..9943d0c 100644 --- a/hash/test/hash_custom_test.cpp +++ b/hash/test/hash_custom_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_deque_test.cpp b/hash/test/hash_deque_test.cpp index 78841f8..bfb2691 100644 --- a/hash/test/hash_deque_test.cpp +++ b/hash/test/hash_deque_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_float_test.cpp b/hash/test/hash_float_test.cpp index c23365d..2490f8d 100644 --- a/hash/test/hash_float_test.cpp +++ b/hash/test/hash_float_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_float_test.hpp b/hash/test/hash_float_test.hpp index 2ef3a86..eef49b2 100644 --- a/hash/test/hash_float_test.hpp +++ b/hash/test/hash_float_test.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_friend_test.cpp b/hash/test/hash_friend_test.cpp index 8f005e6..cac4c7f 100644 --- a/hash/test/hash_friend_test.cpp +++ b/hash/test/hash_friend_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2006-2008 Daniel James. +// Copyright 2006-2009 Daniel James. // 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) diff --git a/hash/test/hash_function_pointer_test.cpp b/hash/test/hash_function_pointer_test.cpp index c171535..7fa4c89 100644 --- a/hash/test/hash_function_pointer_test.cpp +++ b/hash/test/hash_function_pointer_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_fwd_test.hpp b/hash/test/hash_fwd_test.hpp index 4822510..2438abf 100644 --- a/hash/test/hash_fwd_test.hpp +++ b/hash/test/hash_fwd_test.hpp @@ -1,5 +1,5 @@ -// Copyright 2006-2008 Daniel James. +// Copyright 2006-2009 Daniel James. // 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) diff --git a/hash/test/hash_fwd_test_1.cpp b/hash/test/hash_fwd_test_1.cpp index f9dfadb..e9a1cd8 100644 --- a/hash/test/hash_fwd_test_1.cpp +++ b/hash/test/hash_fwd_test_1.cpp @@ -1,5 +1,5 @@ -// Copyright 2006-2008 Daniel James. +// Copyright 2006-2009 Daniel James. // 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) diff --git a/hash/test/hash_fwd_test_2.cpp b/hash/test/hash_fwd_test_2.cpp index 24ccc95..bfa701d 100644 --- a/hash/test/hash_fwd_test_2.cpp +++ b/hash/test/hash_fwd_test_2.cpp @@ -1,5 +1,5 @@ -// Copyright 2006-2008 Daniel James. +// Copyright 2006-2009 Daniel James. // 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) diff --git a/hash/test/hash_global_namespace_test.cpp b/hash/test/hash_global_namespace_test.cpp index eafd22b..a45278c 100644 --- a/hash/test/hash_global_namespace_test.cpp +++ b/hash/test/hash_global_namespace_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2006-2008 Daniel James. +// Copyright 2006-2009 Daniel James. // 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) diff --git a/hash/test/hash_list_test.cpp b/hash/test/hash_list_test.cpp index 0fd2bc5..30560d3 100644 --- a/hash/test/hash_list_test.cpp +++ b/hash/test/hash_list_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_long_double_test.cpp b/hash/test/hash_long_double_test.cpp index d4cbfce..860a679 100644 --- a/hash/test/hash_long_double_test.cpp +++ b/hash/test/hash_long_double_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_map_test.cpp b/hash/test/hash_map_test.cpp index 2ee6bc1..2f813c3 100644 --- a/hash/test/hash_map_test.cpp +++ b/hash/test/hash_map_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_map_test.hpp b/hash/test/hash_map_test.hpp index bb03279..3b52a50 100644 --- a/hash/test/hash_map_test.hpp +++ b/hash/test/hash_map_test.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_no_ext_fail_test.cpp b/hash/test/hash_no_ext_fail_test.cpp index 3959738..ef7ae96 100644 --- a/hash/test/hash_no_ext_fail_test.cpp +++ b/hash/test/hash_no_ext_fail_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2006-2008 Daniel James. +// Copyright 2006-2009 Daniel James. // 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) diff --git a/hash/test/hash_no_ext_macro_1.cpp b/hash/test/hash_no_ext_macro_1.cpp index db2e580..640c36a 100644 --- a/hash/test/hash_no_ext_macro_1.cpp +++ b/hash/test/hash_no_ext_macro_1.cpp @@ -1,5 +1,5 @@ -// Copyright 2006-2008 Daniel James. +// Copyright 2006-2009 Daniel James. // 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) diff --git a/hash/test/hash_no_ext_macro_2.cpp b/hash/test/hash_no_ext_macro_2.cpp index dbeb68d..2f53779 100644 --- a/hash/test/hash_no_ext_macro_2.cpp +++ b/hash/test/hash_no_ext_macro_2.cpp @@ -1,5 +1,5 @@ -// Copyright 2006-2008 Daniel James. +// Copyright 2006-2009 Daniel James. // 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) diff --git a/hash/test/hash_number_test.cpp b/hash/test/hash_number_test.cpp index ef97e99..1000258 100644 --- a/hash/test/hash_number_test.cpp +++ b/hash/test/hash_number_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_pointer_test.cpp b/hash/test/hash_pointer_test.cpp index 673f67a..5fcbc27 100644 --- a/hash/test/hash_pointer_test.cpp +++ b/hash/test/hash_pointer_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_range_test.cpp b/hash/test/hash_range_test.cpp index aac819b..66aad26 100644 --- a/hash/test/hash_range_test.cpp +++ b/hash/test/hash_range_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_sequence_test.hpp b/hash/test/hash_sequence_test.hpp index ad5b5df..4093bc4 100644 --- a/hash/test/hash_sequence_test.hpp +++ b/hash/test/hash_sequence_test.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_set_test.cpp b/hash/test/hash_set_test.cpp index 538c4fd..8b5463d 100644 --- a/hash/test/hash_set_test.cpp +++ b/hash/test/hash_set_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_set_test.hpp b/hash/test/hash_set_test.hpp index 2184d47..2a60781 100644 --- a/hash/test/hash_set_test.hpp +++ b/hash/test/hash_set_test.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_string_test.cpp b/hash/test/hash_string_test.cpp index b58ec18..85f5a0d 100644 --- a/hash/test/hash_string_test.cpp +++ b/hash/test/hash_string_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_value_array_test.cpp b/hash/test/hash_value_array_test.cpp index c39e9f1..75dfd4f 100644 --- a/hash/test/hash_value_array_test.cpp +++ b/hash/test/hash_value_array_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/hash_vector_test.cpp b/hash/test/hash_vector_test.cpp index 5d8ff50..de02fe8 100644 --- a/hash/test/hash_vector_test.cpp +++ b/hash/test/hash_vector_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/link_ext_test.cpp b/hash/test/link_ext_test.cpp index 936cab6..ca4c8f3 100644 --- a/hash/test/link_ext_test.cpp +++ b/hash/test/link_ext_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2006-2008 Daniel James. +// Copyright 2006-2009 Daniel James. // 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) diff --git a/hash/test/link_no_ext_test.cpp b/hash/test/link_no_ext_test.cpp index 22b03fa..7f46984 100644 --- a/hash/test/link_no_ext_test.cpp +++ b/hash/test/link_no_ext_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/link_test.cpp b/hash/test/link_test.cpp index 2819e05..37f9ee1 100644 --- a/hash/test/link_test.cpp +++ b/hash/test/link_test.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/hash/test/link_test_2.cpp b/hash/test/link_test_2.cpp index 8be1635..f32065c 100644 --- a/hash/test/link_test_2.cpp +++ b/hash/test/link_test_2.cpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/include/boost/functional/hash.hpp b/include/boost/functional/hash.hpp index 46b611b..44983f1 100644 --- a/include/boost/functional/hash.hpp +++ b/include/boost/functional/hash.hpp @@ -1,11 +1,7 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) -// Based on Peter Dimov's proposal -// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf -// issue 6.18. - #include diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 154bab7..074b64f 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/include/boost/functional/hash/detail/hash_float.hpp b/include/boost/functional/hash/detail/hash_float.hpp index ca449da..5d5ac34 100644 --- a/include/boost/functional/hash/detail/hash_float.hpp +++ b/include/boost/functional/hash/detail/hash_float.hpp @@ -1,12 +1,8 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) -// Based on Peter Dimov's proposal -// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf -// issue 6.18. - #if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER) #define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER diff --git a/include/boost/functional/hash/extensions.hpp b/include/boost/functional/hash/extensions.hpp index b9d868e..d173314 100644 --- a/include/boost/functional/hash/extensions.hpp +++ b/include/boost/functional/hash/extensions.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 8cd5a60..67284fc 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/include/boost/functional/hash/hash_fwd.hpp b/include/boost/functional/hash/hash_fwd.hpp index 8b7d8e5..1d51b07 100644 --- a/include/boost/functional/hash/hash_fwd.hpp +++ b/include/boost/functional/hash/hash_fwd.hpp @@ -1,5 +1,5 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) diff --git a/include/boost/functional/hash_fwd.hpp b/include/boost/functional/hash_fwd.hpp index 51b8d09..b640988 100644 --- a/include/boost/functional/hash_fwd.hpp +++ b/include/boost/functional/hash_fwd.hpp @@ -1,11 +1,7 @@ -// Copyright 2005-2008 Daniel James. +// Copyright 2005-2009 Daniel James. // 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) -// Based on Peter Dimov's proposal -// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf -// issue 6.18. - #include From bb3e603cfe23f207cb04bb22ce94ed614b2412eb Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 16 Mar 2009 20:21:05 +0000 Subject: [PATCH 17/82] Use paragraphs inside purpose tags. [SVN r51802] --- hash/doc/ref.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hash/doc/ref.xml b/hash/doc/ref.xml index 1fe97d3..47a09d5 100644 --- a/hash/doc/ref.xml +++ b/hash/doc/ref.xml @@ -34,7 +34,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) std::unary_function<T, std::size_t> - A TR1 compliant hash function object. + A TR1 compliant hash function object. std::size_t @@ -419,10 +419,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) void size_t & T const& - + Called repeatedly to incrementally create a hash value from several variables. - + seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); hash_value is called without @@ -460,10 +460,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) It - + Calculate the combined hash value of the elements of an iterator range. - + For the two argument overload: @@ -511,9 +511,9 @@ for(; first != last; ++first) --> - + Implementation of the hash function. - + std::size_t From e5e7db003d8222caad39d5ef96dd3f31cd938e70 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 31 Mar 2009 19:43:58 +0000 Subject: [PATCH 18/82] Changelog for unordered and hash. [SVN r52084] --- hash/doc/changes.qbk | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hash/doc/changes.qbk b/hash/doc/changes.qbk index 667322b..eed63f1 100644 --- a/hash/doc/changes.qbk +++ b/hash/doc/changes.qbk @@ -73,5 +73,14 @@ functional/hash, not functional. `boost/functional/detail/container_fwd.hpp` has been moved to `boost/detail/container_fwd.hpp` as it's used outside of this library, the others have been moved to `boost/functional/hash/detail`. + +[h2 Boost 1.39.0] + +* Move the hash_fwd.hpp implementation into the hash subdirectory, leaving a + forwarding header in the old location. You should still use the old location, + the new location is mainly for implementation and possible modularization. +* [@https://svn.boost.org/trac/boost/ticket/2412 Ticket 2412]: Removed deprecated + headers. + [endsect] From 18c9f2a435dd85aca59fe504c11399a1d0157e67 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 8 Apr 2009 05:51:31 +0000 Subject: [PATCH 19/82] Detect gcc stdlib for gcc 4.0.1. For some reason the normal macros aren't defined for the standard library that comes with gcc 4.0.1 (although maybe just on BSDs?). So try to detect the library for that compiler. [SVN r52245] --- hash/test/Jamfile.v2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index ff149a7..d037847 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -10,6 +10,8 @@ project hash-tests gcc:_GLIBCXX_DEBUG gcc:-Wsign-promo #gcc:-Wextra + darwin:_GLIBCXX_DEBUG + darwin:-Wsign-promo ; test-suite functional/hash From 8ca11394de43380ec3905dec43247f9006bfe9f6 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 10 Apr 2009 19:25:32 +0000 Subject: [PATCH 20/82] Don't use debug containers on darwin. I'm getting errors from the darwin 4.2 debug containers which appear to a problem with its implementation. [SVN r52304] --- hash/test/Jamfile.v2 | 2 -- 1 file changed, 2 deletions(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index d037847..ff149a7 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -10,8 +10,6 @@ project hash-tests gcc:_GLIBCXX_DEBUG gcc:-Wsign-promo #gcc:-Wextra - darwin:_GLIBCXX_DEBUG - darwin:-Wsign-promo ; test-suite functional/hash From f201c2dd17c8d091c046d8054e304c75984d3c38 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 19 Apr 2009 09:17:18 +0000 Subject: [PATCH 21/82] Fix float support on vxWorks. Thanks to Dustin Spicuzza. Refs #2957 [SVN r52481] --- include/boost/functional/hash/detail/float_functions.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 074b64f..69cf91a 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -59,6 +59,10 @@ # define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS # endif +// vxWorks. It has its own math library, but uses Dinkumware STL +#elif defined(__VXWORKS__) +# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS + // Dinkumware. #elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) // Some versions of Visual C++ don't seem to have the C++ overloads but they From a0a96229c8cfce4a76e3398b6a1b33cb122bacf2 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 22 Apr 2009 21:12:49 +0000 Subject: [PATCH 22/82] Add a missing entry to the changelog. [SVN r52552] --- hash/doc/changes.qbk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hash/doc/changes.qbk b/hash/doc/changes.qbk index eed63f1..1d4d6d2 100644 --- a/hash/doc/changes.qbk +++ b/hash/doc/changes.qbk @@ -81,6 +81,7 @@ the new location is mainly for implementation and possible modularization. * [@https://svn.boost.org/trac/boost/ticket/2412 Ticket 2412]: Removed deprecated headers. - +* [@https://svn.boost.org/trac/boost/ticket/2957 Ticket 2957]: Fix configuration + for vxworks. [endsect] From 6c28028f996a0ffe64f6d68a3841b047477e2368 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 16 May 2009 14:23:59 +0000 Subject: [PATCH 23/82] Use a local copy of the valid HTML 4.01 icon. [SVN r53048] --- binders.html | 2 +- function_traits.html | 2 +- index.html | 2 +- mem_fun.html | 2 +- negators.html | 2 +- ptr_fun.html | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/binders.html b/binders.html index f30ed90..30c2c4b 100644 --- a/binders.html +++ b/binders.html @@ -144,7 +144,7 @@ binder2nd(const Operation& x,

Valid HTML 4.01 Transitional

Revised diff --git a/function_traits.html b/function_traits.html index 65fbd9f..c0ce510 100644 --- a/function_traits.html +++ b/function_traits.html @@ -216,7 +216,7 @@ class unary_negate : // ...


Valid HTML 4.01 Transitional

Revised diff --git a/index.html b/index.html index 29ea0d2..86d8bac 100644 --- a/index.html +++ b/index.html @@ -246,7 +246,7 @@ std::for_each(c.begin(), c.end(),


Valid HTML 4.01 Transitional

Revised diff --git a/mem_fun.html b/mem_fun.html index 901ec2a..23dc102 100644 --- a/mem_fun.html +++ b/mem_fun.html @@ -185,7 +185,7 @@ S operator()(T* p, typename call_traits<A>::param_type x) const


Valid HTML 4.01 Transitional

Revised diff --git a/negators.html b/negators.html index 226b0d0..9d31750 100644 --- a/negators.html +++ b/negators.html @@ -141,7 +141,7 @@ bool operator()(typename call_traits<typename Predicate::argument_type>::p


Valid HTML 4.01 Transitional

Revised diff --git a/ptr_fun.html b/ptr_fun.html index 10c0ac3..0dc62b4 100644 --- a/ptr_fun.html +++ b/ptr_fun.html @@ -141,7 +141,7 @@ Result operator()(typename call_traits<Arg>::param_type x) const


Valid HTML 4.01 Transitional

Revised From 5806a8935d89469383350818ee73ff9def5934e9 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 21 May 2009 21:21:11 +0000 Subject: [PATCH 24/82] Move the hash limits workaround into its own file. [SVN r53159] --- hash/test/hash_float_test.hpp | 2 +- hash/test/hash_function_pointer_test.cpp | 1 - hash/test/hash_number_test.cpp | 2 +- hash/test/hash_string_test.cpp | 1 - .../functional/hash/detail/hash_float.hpp | 35 +----------- .../boost/functional/hash/detail/limits.hpp | 57 +++++++++++++++++++ include/boost/functional/hash/hash.hpp | 1 + 7 files changed, 61 insertions(+), 38 deletions(-) create mode 100644 include/boost/functional/hash/detail/limits.hpp diff --git a/hash/test/hash_float_test.hpp b/hash/test/hash_float_test.hpp index eef49b2..eed2e31 100644 --- a/hash/test/hash_float_test.hpp +++ b/hash/test/hash_float_test.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include #include diff --git a/hash/test/hash_function_pointer_test.cpp b/hash/test/hash_function_pointer_test.cpp index 7fa4c89..73719e2 100644 --- a/hash/test/hash_function_pointer_test.cpp +++ b/hash/test/hash_function_pointer_test.cpp @@ -13,7 +13,6 @@ #include -#include #include #include diff --git a/hash/test/hash_number_test.cpp b/hash/test/hash_number_test.cpp index 1000258..88e03bd 100644 --- a/hash/test/hash_number_test.cpp +++ b/hash/test/hash_number_test.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include diff --git a/hash/test/hash_string_test.cpp b/hash/test/hash_string_test.cpp index 85f5a0d..b3b8394 100644 --- a/hash/test/hash_string_test.cpp +++ b/hash/test/hash_string_test.cpp @@ -13,7 +13,6 @@ #include -#include #include #include #include diff --git a/include/boost/functional/hash/detail/hash_float.hpp b/include/boost/functional/hash/detail/hash_float.hpp index 5d5ac34..9844c6a 100644 --- a/include/boost/functional/hash/detail/hash_float.hpp +++ b/include/boost/functional/hash/detail/hash_float.hpp @@ -19,9 +19,9 @@ #endif #include +#include #include #include -#include #include // Select implementation for the current platform. @@ -50,43 +50,10 @@ #endif -// On OpenBSD, numeric_limits is not reliable for long doubles, but -// the macros defined in are. - -#if defined(__OpenBSD__) -#include -#endif - namespace boost { namespace hash_detail { - template - struct limits : std::numeric_limits {}; - -#if defined(__OpenBSD__) - template <> - struct limits - : std::numeric_limits - { - static long double epsilon() { - return LDBL_EPSILON; - } - - static long double (max)() { - return LDBL_MAX; - } - - static long double (min)() { - return LDBL_MIN; - } - - BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG); - BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP); - BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP); - }; -#endif // __OpenBSD__ - inline void hash_float_combine(std::size_t& seed, std::size_t value) { seed ^= value + (seed<<6) + (seed>>2); diff --git a/include/boost/functional/hash/detail/limits.hpp b/include/boost/functional/hash/detail/limits.hpp new file mode 100644 index 0000000..b691d5b --- /dev/null +++ b/include/boost/functional/hash/detail/limits.hpp @@ -0,0 +1,57 @@ + +// Copyright 2005-2009 Daniel James. +// 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) +// +// On some platforms std::limits gives incorrect values for long double. +// This tries to work around them. + +#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER) +#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +// On OpenBSD, numeric_limits is not reliable for long doubles, but +// the macros defined in are. + +#if defined(__OpenBSD__) +#include +#endif + +namespace boost +{ + namespace hash_detail + { + template + struct limits : std::numeric_limits {}; + +#if defined(__OpenBSD__) + template <> + struct limits + : std::numeric_limits + { + static long double epsilon() { + return LDBL_EPSILON; + } + + static long double (max)() { + return LDBL_MAX; + } + + static long double (min)() { + return LDBL_MIN; + } + + BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG); + BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP); + BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP); + }; +#endif // __OpenBSD__ + } +} + +#endif \ No newline at end of file diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 67284fc..12283ff 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) #include From b0f91804a98125ce98aca2226f6b86e640902927 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 21 May 2009 21:21:44 +0000 Subject: [PATCH 25/82] Move the two different hash float implementation into their own header. [SVN r53160] --- .../functional/hash/detail/hash_float.hpp | 133 +++++------------- .../hash/detail/hash_float_generic.hpp | 85 +++++++++++ .../functional/hash/detail/hash_float_x86.hpp | 56 ++++++++ 3 files changed, 180 insertions(+), 94 deletions(-) create mode 100644 include/boost/functional/hash/detail/hash_float_generic.hpp create mode 100644 include/boost/functional/hash/detail/hash_float_x86.hpp diff --git a/include/boost/functional/hash/detail/hash_float.hpp b/include/boost/functional/hash/detail/hash_float.hpp index 9844c6a..b5ed719 100644 --- a/include/boost/functional/hash/detail/hash_float.hpp +++ b/include/boost/functional/hash/detail/hash_float.hpp @@ -18,123 +18,57 @@ #endif #endif +#include #include #include #include #include #include -// Select implementation for the current platform. +// Include hash implementation for the current platform. // Cygwn #if defined(__CYGWIN__) # if defined(__i386__) || defined(_M_IX86) -# define BOOST_HASH_USE_x86_BINARY_HASH +# include +# else +# include # endif +#else +# include +#endif + +// Can we use fpclassify? // STLport -#elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -// fpclassify aren't good enough on STLport. +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#defined BOOST_HASH_USE_FPCLASSIFY 0 // GNU libstdc++ 3 #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) # if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \ !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) -# define BOOST_HASH_USE_FPCLASSIFY +# define BOOST_HASH_USE_FPCLASSIFY 1 +# else +# define BOOST_HASH_USE_FPCLASSIFY 0 # endif -// Dinkumware Library, on Visual C++ -#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) - -// Not using _fpclass because it is only available for double. - +// Everything else +#else +# define BOOST_HASH_USE_FPCLASSIFY 0 #endif +#if BOOST_HASH_USE_FPCLASSIFY + +#include + namespace boost { namespace hash_detail { - inline void hash_float_combine(std::size_t& seed, std::size_t value) - { - seed ^= value + (seed<<6) + (seed>>2); - } - -// A simple, non-portable hash algorithm for x86. -#if defined(BOOST_HASH_USE_x86_BINARY_HASH) - inline std::size_t float_hash_impl(float v) - { - boost::uint32_t* ptr = (boost::uint32_t*)&v; - std::size_t seed = *ptr; - return seed; - } - - inline std::size_t float_hash_impl(double v) - { - boost::uint32_t* ptr = (boost::uint32_t*)&v; - std::size_t seed = *ptr++; - hash_float_combine(seed, *ptr); - return seed; - } - - inline std::size_t float_hash_impl(long double v) - { - boost::uint32_t* ptr = (boost::uint32_t*)&v; - std::size_t seed = *ptr++; - hash_float_combine(seed, *ptr++); - hash_float_combine(seed, *(boost::uint16_t*)ptr); - return seed; - } - -#else - - template - inline std::size_t float_hash_impl(T v) - { - int exp = 0; - - v = boost::hash_detail::call_frexp(v, &exp); - - // A postive value is easier to hash, so combine the - // sign with the exponent. - if(v < 0) { - v = -v; - exp += limits::max_exponent - - limits::min_exponent; - } - - // The result of frexp is always between 0.5 and 1, so its - // top bit will always be 1. Subtract by 0.5 to remove that. - v -= T(0.5); - v = boost::hash_detail::call_ldexp(v, - limits::digits + 1); - std::size_t seed = static_cast(v); - v -= seed; - - // ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1; - std::size_t const length - = (limits::digits * - boost::static_log2::radix>::value - 1) - / limits::digits; - - for(std::size_t i = 0; i != length; ++i) - { - v = boost::hash_detail::call_ldexp(v, - limits::digits); - std::size_t part = static_cast(v); - v -= part; - hash_float_combine(seed, part); - } - - hash_float_combine(seed, exp); - - return seed; - } -#endif - template inline std::size_t float_hash_value(T v) { -#if defined(BOOST_HASH_USE_FPCLASSIFY) using namespace std; switch (fpclassify(v)) { case FP_ZERO: @@ -150,15 +84,26 @@ namespace boost BOOST_ASSERT(0); return 0; } -#else - return v == 0 ? 0 : float_hash_impl(v); -#endif } } } -#if defined(BOOST_MSVC) -#pragma warning(pop) -#endif +#else // !BOOST_HASH_USE_FPCLASSIFY + +namespace boost +{ + namespace hash_detail + { + template + inline std::size_t float_hash_value(T v) + { + return v == 0 ? 0 : float_hash_impl(v); + } + } +} + +#endif // BOOST_HASH_USE_FPCLASSIFY + +#undef BOOST_HASH_USE_FPCLASSIFY #endif diff --git a/include/boost/functional/hash/detail/hash_float_generic.hpp b/include/boost/functional/hash/detail/hash_float_generic.hpp new file mode 100644 index 0000000..ee6b92a --- /dev/null +++ b/include/boost/functional/hash/detail/hash_float_generic.hpp @@ -0,0 +1,85 @@ + +// Copyright 2005-2009 Daniel James. +// 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) + +// A general purpose hash function for non-zero floating point values. + +#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER) +#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER + +#include +#include +#include + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +#if BOOST_MSVC >= 1400 +#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does + // not satisfy test. Loop body not executed +#endif +#endif + +namespace boost +{ + namespace hash_detail + { + inline void hash_float_combine(std::size_t& seed, std::size_t value) + { + seed ^= value + (seed<<6) + (seed>>2); + } + + template + inline std::size_t float_hash_impl(T v) + { + int exp = 0; + + v = boost::hash_detail::call_frexp(v, &exp); + + // A postive value is easier to hash, so combine the + // sign with the exponent. + if(v < 0) { + v = -v; + exp += limits::max_exponent - + limits::min_exponent; + } + + // The result of frexp is always between 0.5 and 1, so its + // top bit will always be 1. Subtract by 0.5 to remove that. + v -= T(0.5); + v = boost::hash_detail::call_ldexp(v, + limits::digits + 1); + std::size_t seed = static_cast(v); + v -= seed; + + // ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1; + std::size_t const length + = (limits::digits * + boost::static_log2::radix>::value - 1) + / limits::digits; + + for(std::size_t i = 0; i != length; ++i) + { + v = boost::hash_detail::call_ldexp(v, + limits::digits); + std::size_t part = static_cast(v); + v -= part; + hash_float_combine(seed, part); + } + + hash_float_combine(seed, exp); + + return seed; + } + } +} + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif \ No newline at end of file diff --git a/include/boost/functional/hash/detail/hash_float_x86.hpp b/include/boost/functional/hash/detail/hash_float_x86.hpp new file mode 100644 index 0000000..b39bb0d --- /dev/null +++ b/include/boost/functional/hash/detail/hash_float_x86.hpp @@ -0,0 +1,56 @@ + +// Copyright 2005-2009 Daniel James. +// 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) + +// A non-portable hash function form non-zero floats on x86. +// +// Even if you're on an x86 platform, this might not work if their floating +// point isn't set up as this expects. So this should only be used if it's +// absolutely certain that it will work. + +#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER) +#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER + +#include + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +namespace boost +{ + namespace hash_detail + { + inline void hash_float_combine(std::size_t& seed, std::size_t value) + { + seed ^= value + (seed<<6) + (seed>>2); + } + + inline std::size_t float_hash_impl(float v) + { + boost::uint32_t* ptr = (boost::uint32_t*)&v; + std::size_t seed = *ptr; + return seed; + } + + inline std::size_t float_hash_impl(double v) + { + boost::uint32_t* ptr = (boost::uint32_t*)&v; + std::size_t seed = *ptr++; + hash_float_combine(seed, *ptr); + return seed; + } + + inline std::size_t float_hash_impl(long double v) + { + boost::uint32_t* ptr = (boost::uint32_t*)&v; + std::size_t seed = *ptr++; + hash_float_combine(seed, *ptr++); + hash_float_combine(seed, *(boost::uint16_t*)ptr); + return seed; + } + } +} + +#endif From e1a56446d8cbcc0b06a3da2d51d7c4b5d00975d1 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 21 May 2009 21:22:04 +0000 Subject: [PATCH 26/82] Try to automatically detect which float functions are available. [SVN r53161] --- .../hash/detail/float_functions.hpp | 296 ++++++++++-------- .../hash/detail/hash_float_generic.hpp | 24 +- 2 files changed, 186 insertions(+), 134 deletions(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 69cf91a..cc4c8fb 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -6,7 +6,11 @@ #if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP) #define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP +#include #include +#include +#include +//#include #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once @@ -17,146 +21,186 @@ // library implementations don't support this. On some that don't, the C99 // float functions (frexpf, frexpl, etc.) are available. // -// Some of this is based on guess work. If I don't know any better I assume that -// the standard C++ overloaded functions are available. If they're not then this -// means that the argument is cast to a double and back, which is inefficient -// and will give pretty bad results for long doubles - so if you know better -// let me know. +// The following tries to automatically detect which are available. -// STLport: -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -# if (defined(__GNUC__) && __GNUC__ < 3 && (defined(linux) || defined(__linux) || defined(__linux__))) || defined(__DMC__) -# define BOOST_HASH_USE_C99_FLOAT_FUNCS -# elif defined(BOOST_MSVC) && BOOST_MSVC < 1300 -# define BOOST_HASH_USE_C99_FLOAT_FUNCS -# else -# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS -# endif +namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { + // Dummy functions to detect when the actual function we want isn't + // available. + // + // AFAICT these have to be outside of the boost namespace, as if they're in + // the boost namespace they'll always be preferable to any other function + // (since the arguments are built in types, ADL can't be used). -// Roguewave: -// -// On borland 5.51, with roguewave 2.1.1 the standard C++ overloads aren't -// defined, but for the same version of roguewave on sunpro they are. -#elif defined(_RWSTD_VER) -# if defined(__BORLANDC__) -# define BOOST_HASH_USE_C99_FLOAT_FUNCS -# define BOOST_HASH_C99_NO_FLOAT_FUNCS -# elif defined(__DECCXX) -# define BOOST_HASH_USE_C99_FLOAT_FUNCS -# else -# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS -# endif + struct none {}; -// libstdc++ (gcc 3.0 onwards, I think) -#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) -# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS + none ldexpf(int, int); + none ldexpl(int, int); + none frexpf(int, int*); + none frexpl(int, int*); -// SGI: -#elif defined(__STL_CONFIG_H) -# if defined(linux) || defined(__linux) || defined(__linux__) -# define BOOST_HASH_USE_C99_FLOAT_FUNCS -# else -# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS -# endif + template none ldexp(Float, int); + template none frexp(Float, int*); +} -// vxWorks. It has its own math library, but uses Dinkumware STL -#elif defined(__VXWORKS__) -# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS - -// Dinkumware. -#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) -// Some versions of Visual C++ don't seem to have the C++ overloads but they -// all seem to have the c99 float overloads -# if defined(BOOST_MSVC) -# define BOOST_HASH_USE_C99_FLOAT_FUNCS -// On other platforms the C++ overloads seem to have been introduced sometime -// before 402. -# elif defined(_CPPLIB_VER) && (_CPPLIB_VER >= 402) -# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS -# else -# define BOOST_HASH_USE_C99_FLOAT_FUNCS -# endif - -// Digital Mars -#elif defined(__DMC__) -# define BOOST_HASH_USE_C99_FLOAT_FUNCS - -// Use overloaded float functions by default. -#else -# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS -#endif - -namespace boost -{ - namespace hash_detail - { - - inline float call_ldexp(float v, int exp) - { +namespace boost { + namespace hash_detail { + namespace detect { using namespace std; -#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \ - defined(BOOST_HASH_C99_NO_FLOAT_FUNCS) - return ldexp(v, exp); -#else - return ldexpf(v, exp); -#endif - } + using namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS; + + // A type for detecting return type of functions. + template struct is; + template <> struct is { char x[10]; }; + template <> struct is { char x[20]; }; + template <> struct is { char x[30]; }; + template <> struct is { char x[40]; }; - inline double call_ldexp(double v, int exp) - { - using namespace std; - return ldexp(v, exp); - } + // Convert the return type of a function to a type we can use. + template is float_type(T); - inline long double call_ldexp(long double v, int exp) - { - using namespace std; -#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) - return ldexp(v, exp); -#else - return ldexpl(v, exp); -#endif - } +#define BOOST_HASH_CALL_FLOAT_FUNC(func, type2) \ + struct func##_access { \ + template \ + struct check \ + { \ + static Float x; \ + static type2 y; \ + BOOST_STATIC_CONSTANT(bool, value = \ + sizeof(float_type(func(x,y))) \ + == sizeof(is)); \ + }; \ + \ + template \ + struct call \ + { \ + Float operator()(Float a, type2 b) const \ + { \ + return func(a, b); \ + } \ + }; \ + } - inline float call_frexp(float v, int* exp) - { - using namespace std; -#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \ - defined(BOOST_HASH_C99_NO_FLOAT_FUNCS) - return frexp(v, exp); -#else - return frexpf(v, exp); -#endif + BOOST_HASH_CALL_FLOAT_FUNC(ldexpf, int); + BOOST_HASH_CALL_FLOAT_FUNC(ldexpl, int); + BOOST_HASH_CALL_FLOAT_FUNC(ldexp, int); + BOOST_HASH_CALL_FLOAT_FUNC(frexpf, int*); + BOOST_HASH_CALL_FLOAT_FUNC(frexpl, int*); + BOOST_HASH_CALL_FLOAT_FUNC(frexp, int*); + +#undef BOOST_CALL_HAS_FLOAT_FUNC } + + // check + // + // Use in select_impl to help old compilers with a value template. + + template + struct check : Access::BOOST_NESTED_TEMPLATE check {}; - inline double call_frexp(double v, int* exp) - { - using namespace std; - return frexp(v, exp); - } + // found_impl + // + // Used in select_impl when an appropriate function has + // been found. - inline long double call_frexp(long double v, int* exp) + template + struct found_impl { - using namespace std; -#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) - return frexp(v, exp); -#else - return frexpl(v, exp); -#endif - } + // Ignore further types + + template + struct x { + typedef found_impl type; + }; + + // Use Access for result + + struct type : Access::BOOST_NESTED_TEMPLATE call + { + BOOST_STATIC_CONSTANT(bool, value = true); + }; + }; + + // select_impl + // + // Used to choose which floating point function to use for a particular + // floating point type. + + struct select_impl + { + // Check if Access is appropriate for Float + + template + struct x : + boost::detail::if_true < + ::boost::hash_detail::check::value + > + ::BOOST_NESTED_TEMPLATE then< + found_impl, select_impl + > {}; + + // Result for nothing found. + + struct type + { + BOOST_STATIC_CONSTANT(bool, value = false); + }; + }; + + // call_ldexp + // + // call_ldexp::value = Is there an appropriate version of call_ldexp + // for this type? + // Is there is, this is a function object that will call that overload + + template + struct call_ldexp : select_impl + :: BOOST_NESTED_TEMPLATE x::type + :: BOOST_NESTED_TEMPLATE x::type + :: BOOST_NESTED_TEMPLATE x::type + :: type {}; + + // call_frexp + // + // call_frexp::value = Is there an appropriate version of call_frexp + // for this type? + // Is there is, this is a function object that will call that overload + + template + struct call_frexp : select_impl + :: BOOST_NESTED_TEMPLATE x::type + :: BOOST_NESTED_TEMPLATE x::type + :: BOOST_NESTED_TEMPLATE x::type + :: type {}; + + // has_float_functions + // + // Have we fround frexp and ldexp for the given float type. + + template + struct has_float_functions + { + BOOST_STATIC_CONSTANT(bool, value = ( + ::boost::type_traits::ice_and< + ::boost::hash_detail::call_ldexp::value, + ::boost::hash_detail::call_frexp::value + >::value + )); + }; + + + // select_hash_type + // + // If there is support for a particular floating point type, use that + // otherwise use double (there's always support for double). + + template + struct select_hash_type : + boost::detail::if_true < + ::boost::hash_detail::has_float_functions::value + > ::BOOST_NESTED_TEMPLATE then < + Float, double + > {}; } } -#if defined(BOOST_HASH_USE_C99_FLOAT_FUNCS) -#undef BOOST_HASH_USE_C99_FLOAT_FUNCS -#endif - -#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) -#undef BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS -#endif - -#if defined(BOOST_HASH_C99_NO_FLOAT_FUNCS) -#undef BOOST_HASH_C99_NO_FLOAT_FUNCS -#endif - #endif diff --git a/include/boost/functional/hash/detail/hash_float_generic.hpp b/include/boost/functional/hash/detail/hash_float_generic.hpp index ee6b92a..164e18a 100644 --- a/include/boost/functional/hash/detail/hash_float_generic.hpp +++ b/include/boost/functional/hash/detail/hash_float_generic.hpp @@ -34,14 +34,17 @@ namespace boost } template - inline std::size_t float_hash_impl(T v) + inline std::size_t float_hash_impl2(T v) { + boost::hash_detail::call_frexp frexp; + boost::hash_detail::call_ldexp ldexp; + int exp = 0; - v = boost::hash_detail::call_frexp(v, &exp); + v = frexp(v, &exp); // A postive value is easier to hash, so combine the - // sign with the exponent. + // sign with the exponent and use the absolute value. if(v < 0) { v = -v; exp += limits::max_exponent - @@ -51,8 +54,7 @@ namespace boost // The result of frexp is always between 0.5 and 1, so its // top bit will always be 1. Subtract by 0.5 to remove that. v -= T(0.5); - v = boost::hash_detail::call_ldexp(v, - limits::digits + 1); + v = ldexp(v, limits::digits + 1); std::size_t seed = static_cast(v); v -= seed; @@ -64,8 +66,7 @@ namespace boost for(std::size_t i = 0; i != length; ++i) { - v = boost::hash_detail::call_ldexp(v, - limits::digits); + v = ldexp(v, limits::digits); std::size_t part = static_cast(v); v -= part; hash_float_combine(seed, part); @@ -74,6 +75,13 @@ namespace boost hash_float_combine(seed, exp); return seed; + }; + + template + inline std::size_t float_hash_impl(T v) + { + typedef BOOST_DEDUCED_TYPENAME select_hash_type::type type; + return float_hash_impl2(static_cast(v)); } } } @@ -82,4 +90,4 @@ namespace boost #pragma warning(pop) #endif -#endif \ No newline at end of file +#endif From e52c15df4ee655788c4eb16b76ca758864aee826 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 22 May 2009 06:00:56 +0000 Subject: [PATCH 27/82] Fix a typo. [SVN r53167] --- include/boost/functional/hash/detail/float_functions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index cc4c8fb..7ab7079 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -174,7 +174,7 @@ namespace boost { // has_float_functions // - // Have we fround frexp and ldexp for the given float type. + // Is there an overload of frexp and ldexp for the given float type. template struct has_float_functions From 6b49fd3d49f129ad04e816ad4cb2896ad802473d Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 22 May 2009 06:01:19 +0000 Subject: [PATCH 28/82] Spell out exactly which functions can be used with which types. I was hitting some ambiguity errors when the function was for the wrong type. [SVN r53168] --- .../hash/detail/float_functions.hpp | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 7ab7079..6f21169 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -153,12 +153,26 @@ namespace boost { // Is there is, this is a function object that will call that overload template - struct call_ldexp : select_impl - :: BOOST_NESTED_TEMPLATE x::type - :: BOOST_NESTED_TEMPLATE x::type - :: BOOST_NESTED_TEMPLATE x::type + struct call_ldexp; + + template <> + struct call_ldexp : select_impl + :: x::type + :: x::type :: type {}; + template <> + struct call_ldexp : select_impl + :: x::type + :: type {}; + + template <> + struct call_ldexp : select_impl + :: x::type + :: x::type + :: type {}; + + // call_frexp // // call_frexp::value = Is there an appropriate version of call_frexp @@ -166,10 +180,23 @@ namespace boost { // Is there is, this is a function object that will call that overload template - struct call_frexp : select_impl - :: BOOST_NESTED_TEMPLATE x::type - :: BOOST_NESTED_TEMPLATE x::type - :: BOOST_NESTED_TEMPLATE x::type + struct call_frexp; + + template <> + struct call_frexp : select_impl + :: x::type + :: x::type + :: type {}; + + template <> + struct call_frexp : select_impl + :: x::type + :: type {}; + + template <> + struct call_frexp : select_impl + :: x::type + :: x::type :: type {}; // has_float_functions From 7d98446408b82751e5debe417e7da38cae94f439 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 22 May 2009 06:01:35 +0000 Subject: [PATCH 29/82] Some STLport fixes for hash. [SVN r53169] --- include/boost/functional/hash/detail/hash_float.hpp | 2 +- include/boost/functional/hash/detail/limits.hpp | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/boost/functional/hash/detail/hash_float.hpp b/include/boost/functional/hash/detail/hash_float.hpp index b5ed719..0137ab7 100644 --- a/include/boost/functional/hash/detail/hash_float.hpp +++ b/include/boost/functional/hash/detail/hash_float.hpp @@ -42,7 +42,7 @@ // STLport #if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#defined BOOST_HASH_USE_FPCLASSIFY 0 +#define BOOST_HASH_USE_FPCLASSIFY 0 // GNU libstdc++ 3 #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) diff --git a/include/boost/functional/hash/detail/limits.hpp b/include/boost/functional/hash/detail/limits.hpp index b691d5b..b7e8853 100644 --- a/include/boost/functional/hash/detail/limits.hpp +++ b/include/boost/functional/hash/detail/limits.hpp @@ -16,9 +16,10 @@ #include // On OpenBSD, numeric_limits is not reliable for long doubles, but -// the macros defined in are. +// the macros defined in are and support long double when STLport +// doesn't. -#if defined(__OpenBSD__) +#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE) #include #endif @@ -29,7 +30,7 @@ namespace boost template struct limits : std::numeric_limits {}; -#if defined(__OpenBSD__) +#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE) template <> struct limits : std::numeric_limits @@ -49,6 +50,9 @@ namespace boost BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG); BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP); BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP); +#if defined(_STLP_NO_LONG_DOUBLE) + BOOST_STATIC_CONSTANT(int, radix = FLT_RADIX); +#endif }; #endif // __OpenBSD__ } From 0c4c77ea346ae289ebdfef576ac3032a2d179368 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 22 May 2009 13:35:56 +0000 Subject: [PATCH 30/82] Rename struct to avoid using 'type::'type' which confuses some compilers. [SVN r53175] --- .../functional/hash/detail/float_functions.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 6f21169..40b2c03 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -114,7 +114,7 @@ namespace boost { // Use Access for result - struct type : Access::BOOST_NESTED_TEMPLATE call + struct result : Access::BOOST_NESTED_TEMPLATE call { BOOST_STATIC_CONSTANT(bool, value = true); }; @@ -140,7 +140,7 @@ namespace boost { // Result for nothing found. - struct type + struct result { BOOST_STATIC_CONSTANT(bool, value = false); }; @@ -159,18 +159,18 @@ namespace boost { struct call_ldexp : select_impl :: x::type :: x::type - :: type {}; + :: result {}; template <> struct call_ldexp : select_impl :: x::type - :: type {}; + :: result {}; template <> struct call_ldexp : select_impl :: x::type :: x::type - :: type {}; + :: result {}; // call_frexp @@ -186,18 +186,18 @@ namespace boost { struct call_frexp : select_impl :: x::type :: x::type - :: type {}; + :: result {}; template <> struct call_frexp : select_impl :: x::type - :: type {}; + :: result {}; template <> struct call_frexp : select_impl :: x::type :: x::type - :: type {}; + :: result {}; // has_float_functions // From b610456580db01ee95b185ae3234084a296ca26f Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 22 May 2009 19:00:35 +0000 Subject: [PATCH 31/82] Explicitly qualify 'none' to avoid confusion with boost::none. [SVN r53185] --- include/boost/functional/hash/detail/float_functions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 40b2c03..a842d6e 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -53,7 +53,7 @@ namespace boost { template <> struct is { char x[10]; }; template <> struct is { char x[20]; }; template <> struct is { char x[30]; }; - template <> struct is { char x[40]; }; + template <> struct is { char x[40]; }; // Convert the return type of a function to a type we can use. template is float_type(T); From 6de823b18b7c62351c35a4e2865a17b0f8528609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Hunold?= Date: Sat, 23 May 2009 13:03:25 +0000 Subject: [PATCH 32/82] Fix gcc -pedantic error:extra extra ';' [SVN r53203] --- include/boost/functional/hash/detail/hash_float_generic.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/functional/hash/detail/hash_float_generic.hpp b/include/boost/functional/hash/detail/hash_float_generic.hpp index 164e18a..f9acee9 100644 --- a/include/boost/functional/hash/detail/hash_float_generic.hpp +++ b/include/boost/functional/hash/detail/hash_float_generic.hpp @@ -75,7 +75,7 @@ namespace boost hash_float_combine(seed, exp); return seed; - }; + } template inline std::size_t float_hash_impl(T v) From 1ccd4616fcb0ef2ce0c06781d8fee60180b8d712 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 23 May 2009 15:21:38 +0000 Subject: [PATCH 33/82] Try to deal with macros for frexpl and ldexpl. The error message for msvc-9.0~wm5~stlport5.2 suggests that frexpl and ldexpl are macros. [SVN r53205] --- .../hash/detail/float_functions.hpp | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index a842d6e..5030580 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -10,7 +10,6 @@ #include #include #include -//#include #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once @@ -33,10 +32,18 @@ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { struct none {}; +#if !defined(ldexpf) none ldexpf(int, int); +#endif +#if !defined(ldexpl) none ldexpl(int, int); +#endif +#if !defined(frexpf) none frexpf(int, int*); +#endif +#if !defined(frexpl) none frexpl(int, int*); +#endif template none ldexp(Float, int); template none frexp(Float, int*); @@ -80,11 +87,48 @@ namespace boost { }; \ } +#define BOOST_HASH_CALL_FLOAT_MACRO(func, type, type2) \ + struct func##_access { \ + template \ + struct check { \ + BOOST_STATIC_CONSTANT(bool, value = true); \ + }; \ + \ + template \ + struct call \ + { \ + Float operator()(Float a, type2 b) const \ + { \ + return func(a, b); \ + } \ + }; \ + } + +#if defined(ldexpf) + BOOST_HASH_CALL_FLOAT_MACRO(ldexpf, float, int); +#else BOOST_HASH_CALL_FLOAT_FUNC(ldexpf, int); +#endif + +#if defined(ldexpl) + BOOST_HASH_CALL_FLOAT_MACRO(ldexpl, long double, int); +#else BOOST_HASH_CALL_FLOAT_FUNC(ldexpl, int); - BOOST_HASH_CALL_FLOAT_FUNC(ldexp, int); +#endif + +#if defined(frexpf) + BOOST_HASH_CALL_FLOAT_MACRO(frexpf, float, int*); +#else BOOST_HASH_CALL_FLOAT_FUNC(frexpf, int*); +#endif + +#if defined(frexpl) + BOOST_HASH_CALL_FLOAT_MACRO(frexpl, long double, int*); +#else BOOST_HASH_CALL_FLOAT_FUNC(frexpl, int*); +#endif + + BOOST_HASH_CALL_FLOAT_FUNC(ldexp, int); BOOST_HASH_CALL_FLOAT_FUNC(frexp, int*); #undef BOOST_CALL_HAS_FLOAT_FUNC From e655314f73ca726e7c4dc1ea772efebcb96d047f Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 25 May 2009 13:45:16 +0000 Subject: [PATCH 34/82] Check for float functions with less templates. The only template mechanism now used is full specialization, so this should hopefully be more portable to compilers we don't test. [SVN r53247] --- hash/test/hash_float_test.hpp | 21 + .../hash/detail/float_functions.hpp | 415 ++++++++---------- .../boost/functional/hash/detail/limits.hpp | 2 +- 3 files changed, 209 insertions(+), 229 deletions(-) diff --git a/hash/test/hash_float_test.hpp b/hash/test/hash_float_test.hpp index eed2e31..77c652c 100644 --- a/hash/test/hash_float_test.hpp +++ b/hash/test/hash_float_test.hpp @@ -23,6 +23,10 @@ #pragma warning(disable:4127) // conditional expression is constant #endif +char const* float_type(float*) { return "float"; } +char const* float_type(double*) { return "double"; } +char const* float_type(long double*) { return "long double"; } + template void float_tests(char const* name, T* = 0) { @@ -36,6 +40,15 @@ void float_tests(char const* name, T* = 0) <<"boost::hash_detail::limits::digits = " <::digits<<"\n" <<"\n" + <<"boost::hash_detail::call_ldexp::float_type = " + <::float_type*)0)<<"\n" + <<"boost::call_frexp::float_type = " + <::float_type*)0)<<"\n" + <<"boost::hash_detail::call_frexp::float_type = " + <::float_type*)0)<<"\n" + <<"boost::hash_detail::select_hash_type::type = " + <::type*)0)<<"\n" + <<"\n" ; HASH_NAMESPACE::hash x1; @@ -112,6 +125,14 @@ void float_tests(char const* name, T* = 0) T half_max = max / 2; T quarter_max = max / 4; T three_quarter_max = max - quarter_max; + + // Check the limits::max is in range. + BOOST_TEST(max != half_max); + BOOST_TEST(max != quarter_max); + BOOST_TEST(max != three_quarter_max); + BOOST_TEST(half_max != quarter_max); + BOOST_TEST(half_max != three_quarter_max); + BOOST_TEST(quarter_max != three_quarter_max); BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max)); BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max)); diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 5030580..df18a84 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -8,8 +8,6 @@ #include #include -#include -#include #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once @@ -22,240 +20,203 @@ // // The following tries to automatically detect which are available. -namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { - // Dummy functions to detect when the actual function we want isn't - // available. - // - // AFAICT these have to be outside of the boost namespace, as if they're in - // the boost namespace they'll always be preferable to any other function - // (since the arguments are built in types, ADL can't be used). - - struct none {}; - -#if !defined(ldexpf) - none ldexpf(int, int); -#endif -#if !defined(ldexpl) - none ldexpl(int, int); -#endif -#if !defined(frexpf) - none frexpf(int, int*); -#endif -#if !defined(frexpl) - none frexpl(int, int*); -#endif - - template none ldexp(Float, int); - template none frexp(Float, int*); -} - namespace boost { namespace hash_detail { - namespace detect { - using namespace std; - using namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS; + + // Returned by dummy versions of the float functions. + + struct not_found { + // Implicitly convertible to float and long double in order to avoid + // a compile error when the dummy float functions are used. + + inline operator float() const { return 0; } + inline operator long double() const { return 0; } + }; - // A type for detecting return type of functions. - template struct is; - template <> struct is { char x[10]; }; - template <> struct is { char x[20]; }; - template <> struct is { char x[30]; }; - template <> struct is { char x[40]; }; + // A type for detecting the return type of functions. - // Convert the return type of a function to a type we can use. - template is float_type(T); - -#define BOOST_HASH_CALL_FLOAT_FUNC(func, type2) \ - struct func##_access { \ - template \ - struct check \ - { \ - static Float x; \ - static type2 y; \ - BOOST_STATIC_CONSTANT(bool, value = \ - sizeof(float_type(func(x,y))) \ - == sizeof(is)); \ - }; \ - \ - template \ - struct call \ - { \ - Float operator()(Float a, type2 b) const \ - { \ - return func(a, b); \ - } \ - }; \ - } - -#define BOOST_HASH_CALL_FLOAT_MACRO(func, type, type2) \ - struct func##_access { \ - template \ - struct check { \ - BOOST_STATIC_CONSTANT(bool, value = true); \ - }; \ - \ - template \ - struct call \ - { \ - Float operator()(Float a, type2 b) const \ - { \ - return func(a, b); \ - } \ - }; \ - } - -#if defined(ldexpf) - BOOST_HASH_CALL_FLOAT_MACRO(ldexpf, float, int); -#else - BOOST_HASH_CALL_FLOAT_FUNC(ldexpf, int); -#endif - -#if defined(ldexpl) - BOOST_HASH_CALL_FLOAT_MACRO(ldexpl, long double, int); -#else - BOOST_HASH_CALL_FLOAT_FUNC(ldexpl, int); -#endif - -#if defined(frexpf) - BOOST_HASH_CALL_FLOAT_MACRO(frexpf, float, int*); -#else - BOOST_HASH_CALL_FLOAT_FUNC(frexpf, int*); -#endif - -#if defined(frexpl) - BOOST_HASH_CALL_FLOAT_MACRO(frexpl, long double, int*); -#else - BOOST_HASH_CALL_FLOAT_FUNC(frexpl, int*); -#endif - - BOOST_HASH_CALL_FLOAT_FUNC(ldexp, int); - BOOST_HASH_CALL_FLOAT_FUNC(frexp, int*); + template struct is; + template <> struct is { char x[10]; }; + template <> struct is { char x[20]; }; + template <> struct is { char x[30]; }; + template <> struct is { char x[40]; }; -#undef BOOST_CALL_HAS_FLOAT_FUNC - } - - // check - // - // Use in select_impl to help old compilers with a value template. - - template - struct check : Access::BOOST_NESTED_TEMPLATE check {}; + // Used to convert the return type of a function to a type for sizeof. - // found_impl - // - // Used in select_impl when an appropriate function has - // been found. - - template - struct found_impl - { - // Ignore further types - - template - struct x { - typedef found_impl type; - }; - - // Use Access for result - - struct result : Access::BOOST_NESTED_TEMPLATE call - { - BOOST_STATIC_CONSTANT(bool, value = true); - }; - }; - - // select_impl - // - // Used to choose which floating point function to use for a particular - // floating point type. - - struct select_impl - { - // Check if Access is appropriate for Float - - template - struct x : - boost::detail::if_true < - ::boost::hash_detail::check::value - > - ::BOOST_NESTED_TEMPLATE then< - found_impl, select_impl - > {}; - - // Result for nothing found. - - struct result - { - BOOST_STATIC_CONSTANT(bool, value = false); - }; - }; + template is float_type(T); // call_ldexp // - // call_ldexp::value = Is there an appropriate version of call_ldexp - // for this type? - // Is there is, this is a function object that will call that overload - - template - struct call_ldexp; - - template <> - struct call_ldexp : select_impl - :: x::type - :: x::type - :: result {}; - - template <> - struct call_ldexp : select_impl - :: x::type - :: result {}; - - template <> - struct call_ldexp : select_impl - :: x::type - :: x::type - :: result {}; - + // This will get specialized for float and long double + + template struct call_ldexp + { + typedef double float_type; + + inline double operator()(double a, int b) const + { + using namespace std; + return ldexp(a, b); + } + }; // call_frexp // - // call_frexp::value = Is there an appropriate version of call_frexp - // for this type? - // Is there is, this is a function object that will call that overload + // This will get specialized for float and long double - template - struct call_frexp; - - template <> - struct call_frexp : select_impl - :: x::type - :: x::type - :: result {}; - - template <> - struct call_frexp : select_impl - :: x::type - :: result {}; - - template <> - struct call_frexp : select_impl - :: x::type - :: x::type - :: result {}; - - // has_float_functions - // - // Is there an overload of frexp and ldexp for the given float type. - - template - struct has_float_functions + template struct call_frexp { - BOOST_STATIC_CONSTANT(bool, value = ( - ::boost::type_traits::ice_and< - ::boost::hash_detail::call_ldexp::value, - ::boost::hash_detail::call_frexp::value - >::value - )); + typedef double float_type; + + inline double operator()(double a, int* b) const + { + using namespace std; + return frexp(a, b); + } + }; + } +} + +// A namespace for dummy functions to detect when the actual function we want +// isn't available. ldexpl, ldexpf etc. might be added tby the macros below. +// +// AFAICT these have to be outside of the boost namespace, as if they're in +// the boost namespace they'll always be preferable to any other function +// (since the arguments are built in types, ADL can't be used). + +namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { + template boost::hash_detail::not_found ldexp(Float, int); + template boost::hash_detail::not_found frexp(Float, int*); +} + +// Macros for generating specializations of call_ldexp and call_frexp. +// +// check_cpp and check_c99 check if the C++ or C99 functions are available. +// +// Then the call_* functions select an appropriate implementation. +// +// I used c99_func in a few places just to get a unique name. + +#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \ +namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \ + boost::hash_detail::not_found c99_func(int, type2); \ +} \ + \ +namespace boost { \ + namespace hash_detail { \ + namespace c99_func##_detect { \ + using namespace std; \ + using namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS; \ + \ + struct check { \ + static type1 x; \ + static type2 y; \ + BOOST_STATIC_CONSTANT(bool, cpp = \ + sizeof(float_type(cpp_func(x,y))) \ + == sizeof(is)); \ + BOOST_STATIC_CONSTANT(bool, c99 = \ + sizeof(float_type(c99_func(x,y))) \ + == sizeof(is)); \ + }; \ + } \ + \ + template \ + struct call_##c99_func##_c99 : \ + call_##cpp_func {}; \ + \ + template <> \ + struct call_##c99_func##_c99 { \ + typedef type1 float_type; \ + \ + inline type1 operator()(type1 a, type2 b) const \ + { \ + return c99_func(a, b); \ + } \ + }; \ + \ + template \ + struct call_##c99_func##_cpp : \ + call_##c99_func##_c99< \ + ::boost::hash_detail::c99_func##_detect::check::c99 \ + > {}; \ + \ + template <> \ + struct call_##c99_func##_cpp { \ + typedef type1 float_type; \ + \ + inline type1 operator()(type1 a, type2 b) const \ + { \ + return cpp_func(a, b); \ + } \ + }; \ + \ + template <> \ + struct call_##cpp_func : \ + call_##c99_func##_cpp< \ + ::boost::hash_detail::c99_func##_detect::check::cpp \ + > {}; \ + } \ +} + +#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \ +namespace boost { \ + namespace hash_detail { \ + \ + template <> \ + struct call_##cpp_func { \ + typedef type1 float_type; \ + inline type1 operator()(type1 x, type2 y) const { \ + return c99_func(x, y); \ + } \ + }; \ + } \ +} + +#if defined(ldexpf) +BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int) +#else +BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int) +#endif + +#if defined(ldexpl) +BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int) +#else +BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int) +#endif + +#if defined(frexpf) +BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*) +#else +BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*) +#endif + +#if defined(frexpl) +BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*) +#else +BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*) +#endif + +#undef BOOST_HASH_CALL_FLOAT_MACRO +#undef BOOST_HASH_CALL_FLOAT_FUNC + + +namespace boost +{ + namespace hash_detail + { + template + struct select_hash_type_impl { + typedef double type; + }; + + template <> + struct select_hash_type_impl { + typedef float type; + }; + + template <> + struct select_hash_type_impl { + typedef long double type; }; @@ -265,12 +226,10 @@ namespace boost { // otherwise use double (there's always support for double). template - struct select_hash_type : - boost::detail::if_true < - ::boost::hash_detail::has_float_functions::value - > ::BOOST_NESTED_TEMPLATE then < - Float, double - > {}; + struct select_hash_type : select_hash_type_impl< + BOOST_DEDUCED_TYPENAME call_ldexp::float_type, + BOOST_DEDUCED_TYPENAME call_frexp::float_type + > {}; } } diff --git a/include/boost/functional/hash/detail/limits.hpp b/include/boost/functional/hash/detail/limits.hpp index b7e8853..f5b520e 100644 --- a/include/boost/functional/hash/detail/limits.hpp +++ b/include/boost/functional/hash/detail/limits.hpp @@ -58,4 +58,4 @@ namespace boost } } -#endif \ No newline at end of file +#endif From 26cf795fe0755d0d2c24c027f6855606bad5aea7 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 25 May 2009 14:27:00 +0000 Subject: [PATCH 35/82] Fix a couple of clumsy errors in the last commit. [SVN r53248] --- .../hash/detail/float_functions.hpp | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index df18a84..60dbb2a 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -117,42 +117,44 @@ namespace boost { \ BOOST_STATIC_CONSTANT(bool, c99 = \ sizeof(float_type(c99_func(x,y))) \ == sizeof(is)); \ + }; \ + \ + template \ + struct call_c99 : \ + boost::hash_detail::call_##cpp_func {}; \ + \ + template <> \ + struct call_c99 { \ + typedef type1 float_type; \ + \ + template \ + inline type1 operator()(type1 a, T b) const \ + { \ + return c99_func(a, b); \ + } \ + }; \ + \ + template \ + struct call_cpp : \ + call_c99< \ + ::boost::hash_detail::c99_func##_detect::check::c99 \ + > {}; \ + \ + template <> \ + struct call_cpp { \ + typedef type1 float_type; \ + \ + template \ + inline type1 operator()(type1 a, T b) const \ + { \ + return cpp_func(a, b); \ + } \ }; \ } \ \ - template \ - struct call_##c99_func##_c99 : \ - call_##cpp_func {}; \ - \ - template <> \ - struct call_##c99_func##_c99 { \ - typedef type1 float_type; \ - \ - inline type1 operator()(type1 a, type2 b) const \ - { \ - return c99_func(a, b); \ - } \ - }; \ - \ - template \ - struct call_##c99_func##_cpp : \ - call_##c99_func##_c99< \ - ::boost::hash_detail::c99_func##_detect::check::c99 \ - > {}; \ - \ - template <> \ - struct call_##c99_func##_cpp { \ - typedef type1 float_type; \ - \ - inline type1 operator()(type1 a, type2 b) const \ - { \ - return cpp_func(a, b); \ - } \ - }; \ - \ template <> \ struct call_##cpp_func : \ - call_##c99_func##_cpp< \ + c99_func##_detect::call_cpp< \ ::boost::hash_detail::c99_func##_detect::check::cpp \ > {}; \ } \ From 7284d54f19910e6ce3628321bf1d9eceaba44116 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 25 May 2009 19:44:52 +0000 Subject: [PATCH 36/82] Hash change log. [SVN r53254] --- hash/doc/changes.qbk | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hash/doc/changes.qbk b/hash/doc/changes.qbk index 1d4d6d2..5ee9150 100644 --- a/hash/doc/changes.qbk +++ b/hash/doc/changes.qbk @@ -84,4 +84,10 @@ * [@https://svn.boost.org/trac/boost/ticket/2957 Ticket 2957]: Fix configuration for vxworks. +[h2 Boost 1.40.0] + +* Automatically configure the float functions using template metaprogramming + instead of trying to configure every possibility manually. +* Workaround for when STLport doesn't support long double. + [endsect] From 37b84f9cbb05322dc75ad57b0081666b7958292c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 31 May 2009 15:53:09 +0000 Subject: [PATCH 37/82] Remove misplaced visual C++ warning pragma. [SVN r53506] --- include/boost/functional/hash/detail/hash_float.hpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/boost/functional/hash/detail/hash_float.hpp b/include/boost/functional/hash/detail/hash_float.hpp index 0137ab7..ea1bc25 100644 --- a/include/boost/functional/hash/detail/hash_float.hpp +++ b/include/boost/functional/hash/detail/hash_float.hpp @@ -10,14 +10,6 @@ # pragma once #endif -#if defined(BOOST_MSVC) -#pragma warning(push) -#if BOOST_MSVC >= 1400 -#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does - // not satisfy test. Loop body not executed -#endif -#endif - #include #include #include From f77c8ed57e94ae1e58267c256bfb2c94f1750270 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 1 Jun 2009 06:49:45 +0000 Subject: [PATCH 38/82] Test the hash functions for a couple of typedefs. [SVN r53522] --- hash/test/hash_number_test.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hash/test/hash_number_test.cpp b/hash/test/hash_number_test.cpp index 88e03bd..40febc7 100644 --- a/hash/test/hash_number_test.cpp +++ b/hash/test/hash_number_test.cpp @@ -157,6 +157,9 @@ int main() NUMERIC_TEST(float, float) NUMERIC_TEST(double, double) + NUMERIC_TEST(std::size_t, size_t) + NUMERIC_TEST(std::ptrdiff_t, ptrdiff_t) + bool_test(); return boost::report_errors(); From d84c5c9364853f428b876880285c5ed83588b583 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 12 Jun 2009 18:24:47 +0000 Subject: [PATCH 39/82] Try to avoid float to int warning when a float function doesn't exist. Refs #3171. [SVN r53828] --- include/boost/functional/hash/detail/float_functions.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 60dbb2a..9ec0dd2 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -99,7 +99,8 @@ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { #define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \ - boost::hash_detail::not_found c99_func(int, type2); \ + template \ + boost::hash_detail::not_found c99_func(Float, type2); \ } \ \ namespace boost { \ From 79f6dbfc9adce03ca4135da8e358ffa193a992d8 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 15 Jun 2009 07:37:42 +0000 Subject: [PATCH 40/82] Remove hash_complex_test's dependency on Boost.Random. Only test for a few values, but that should be okay as there isn't much to test. [SVN r53924] --- hash/test/hash_complex_test.cpp | 40 +++++++++++---------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/hash/test/hash_complex_test.cpp b/hash/test/hash_complex_test.cpp index dd519c9..686b25a 100644 --- a/hash/test/hash_complex_test.cpp +++ b/hash/test/hash_complex_test.cpp @@ -27,11 +27,6 @@ #pragma warning(disable:4512) // assignment operator could not be generated #endif -#include -#include -#include -#include - #if defined(BOOST_MSVC) #pragma warning(pop) #endif @@ -61,33 +56,24 @@ void generic_complex_tests(std::complex v) template void complex_float_tests(Float*) { - boost::mt19937 rng; - boost::uniform_real uniform; - boost::variate_generator > - uniform_generator(rng, uniform); - - for(int i = 0; i < 100; ++i) - { - std::complex v(uniform_generator(), uniform_generator()); - generic_complex_tests(v); - } + typedef std::complex complex; + generic_complex_tests(complex(0,0)); + generic_complex_tests(complex(0.5,0)); + generic_complex_tests(complex(25,0)); + generic_complex_tests(complex(25,0)); + generic_complex_tests(complex(-67.5324535,56.23578678)); } template void complex_integral_tests(Integer*) { - boost::mt19937 rng; - boost::uniform_int uniform( - (std::numeric_limits::min)(), - (std::numeric_limits::max)()); - boost::variate_generator > - uniform_generator(rng, uniform); - - for(int i = 0; i < 100; ++i) - { - std::complexv(uniform_generator(), uniform_generator()); - generic_complex_tests(v); - } + typedef std::complex complex; + generic_complex_tests(complex(0,0)); + generic_complex_tests(complex(15342,124)); + generic_complex_tests(complex(25,54356)); + generic_complex_tests(complex(5325,2346)); + generic_complex_tests(complex(-243897,-49923874)); + generic_complex_tests(complex(-543,763)); } int main() From 69882c3b5b466d793093a1e3ee3222c56480762c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 17 Jun 2009 21:22:49 +0000 Subject: [PATCH 41/82] Put the minimum amount of implementation in the same namespace as the 'using namespace' directives in order to avoid Visual C++ 8 bug. [SVN r54024] --- hash/test/Jamfile.v2 | 1 + hash/test/namespace_fail_test.cpp | 6 ++ .../hash/detail/float_functions.hpp | 68 ++++++++++--------- 3 files changed, 42 insertions(+), 33 deletions(-) create mode 100644 hash/test/namespace_fail_test.cpp diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index ff149a7..c91691f 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -38,6 +38,7 @@ test-suite functional/hash [ run link_ext_test.cpp link_no_ext_test.cpp ] [ run container_fwd_test.cpp ] [ compile-fail hash_no_ext_fail_test.cpp ] + [ compile-fail namespace_fail_test.cpp ] [ run hash_no_ext_macro_1.cpp ] [ run hash_no_ext_macro_2.cpp ] ; diff --git a/hash/test/namespace_fail_test.cpp b/hash/test/namespace_fail_test.cpp new file mode 100644 index 0000000..2e02d57 --- /dev/null +++ b/hash/test/namespace_fail_test.cpp @@ -0,0 +1,6 @@ +#include +#include + +typedef list foo; + +int main() {} \ No newline at end of file diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 9ec0dd2..f766ec9 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -118,44 +118,46 @@ namespace boost { \ BOOST_STATIC_CONSTANT(bool, c99 = \ sizeof(float_type(c99_func(x,y))) \ == sizeof(is)); \ - }; \ - \ - template \ - struct call_c99 : \ - boost::hash_detail::call_##cpp_func {}; \ - \ - template <> \ - struct call_c99 { \ - typedef type1 float_type; \ - \ - template \ - inline type1 operator()(type1 a, T b) const \ - { \ - return c99_func(a, b); \ - } \ - }; \ - \ - template \ - struct call_cpp : \ - call_c99< \ - ::boost::hash_detail::c99_func##_detect::check::c99 \ - > {}; \ - \ - template <> \ - struct call_cpp { \ - typedef type1 float_type; \ - \ - template \ - inline type1 operator()(type1 a, T b) const \ - { \ - return cpp_func(a, b); \ - } \ }; \ } \ \ + template \ + struct call_c99_##c99_func : \ + boost::hash_detail::call_##cpp_func {}; \ + \ + template <> \ + struct call_c99_##c99_func { \ + typedef type1 float_type; \ + \ + template \ + inline type1 operator()(type1 a, T b) const \ + { \ + using namespace std; \ + return c99_func(a, b); \ + } \ + }; \ + \ + template \ + struct call_cpp_##c99_func : \ + call_c99_##c99_func< \ + ::boost::hash_detail::c99_func##_detect::check::c99 \ + > {}; \ + \ + template <> \ + struct call_cpp_##c99_func { \ + typedef type1 float_type; \ + \ + template \ + inline type1 operator()(type1 a, T b) const \ + { \ + using namespace std; \ + return cpp_func(a, b); \ + } \ + }; \ + \ template <> \ struct call_##cpp_func : \ - c99_func##_detect::call_cpp< \ + call_cpp_##c99_func< \ ::boost::hash_detail::c99_func##_detect::check::cpp \ > {}; \ } \ From cf5f69c2161bca7a927db6f2ae4e2258c6874eac Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 17 Jun 2009 21:23:42 +0000 Subject: [PATCH 42/82] Try to avoid using special macro handling code. [SVN r54025] --- .../hash/detail/float_functions.hpp | 38 +------------------ 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index f766ec9..199123d 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -100,7 +100,8 @@ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { #define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \ template \ - boost::hash_detail::not_found c99_func(Float, type2); \ + boost::hash_detail::not_found c99_func \ + BOOST_PREVENT_MACRO_SUBSTITUTION (Float, type2); \ } \ \ namespace boost { \ @@ -163,48 +164,13 @@ namespace boost { \ } \ } -#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \ -namespace boost { \ - namespace hash_detail { \ - \ - template <> \ - struct call_##cpp_func { \ - typedef type1 float_type; \ - inline type1 operator()(type1 x, type2 y) const { \ - return c99_func(x, y); \ - } \ - }; \ - } \ -} - -#if defined(ldexpf) -BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int) -#else BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int) -#endif - -#if defined(ldexpl) -BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int) -#else BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int) -#endif - -#if defined(frexpf) -BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*) -#else BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*) -#endif - -#if defined(frexpl) -BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*) -#else BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*) -#endif -#undef BOOST_HASH_CALL_FLOAT_MACRO #undef BOOST_HASH_CALL_FLOAT_FUNC - namespace boost { namespace hash_detail From 48db3ff5691792f6bd0a77358e7b4fe208d071f7 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 17 Jun 2009 23:24:28 +0000 Subject: [PATCH 43/82] Add copyright to namespace_fail_test.cpp [SVN r54033] --- hash/test/namespace_fail_test.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hash/test/namespace_fail_test.cpp b/hash/test/namespace_fail_test.cpp index 2e02d57..d3c13aa 100644 --- a/hash/test/namespace_fail_test.cpp +++ b/hash/test/namespace_fail_test.cpp @@ -1,5 +1,13 @@ + +// Copyright 2009 Daniel James. +// 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) + +// Check that I haven't inadvertantly pulled namespace std into the global +// namespace. + #include -#include +#include typedef list foo; From ac31c7e33cbea88d442133a71107a64d682a8fd9 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 21 Jun 2009 09:41:11 +0000 Subject: [PATCH 44/82] A few more comments in boost::hash. [SVN r54139] --- include/boost/functional/hash/extensions.hpp | 17 +++++++++++--- include/boost/functional/hash/hash.hpp | 24 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/include/boost/functional/hash/extensions.hpp b/include/boost/functional/hash/extensions.hpp index d173314..02f8bbb 100644 --- a/include/boost/functional/hash/extensions.hpp +++ b/include/boost/functional/hash/extensions.hpp @@ -17,6 +17,12 @@ namespace boost { + // + // call_hash_impl + // + + // On compilers without function template ordering, this deals with arrays. + #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) namespace hash_detail { @@ -61,6 +67,11 @@ namespace boost } #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + // + // boost::hash + // + + #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct hash @@ -94,7 +105,7 @@ namespace boost // On compilers without partial specialization, boost::hash // has already been declared to deal with pointers, so just - // need to supply the non-pointer version. + // need to supply the non-pointer version of hash_impl. namespace hash_detail { @@ -126,8 +137,8 @@ namespace boost #else // Visual C++ 6.5 - // There's probably a more elegant way to Visual C++ 6.5 to work - // but I don't know what it is. + // Visual C++ 6.5 has problems with nested member functions and + // applying const to const types in templates. So we get this: template struct hash_impl_msvc diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 12283ff..6f8b313 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -378,6 +378,18 @@ namespace boost // // boost::hash // + + // Define the specializations required by the standard. The general purpose + // boost::hash is defined later in extensions.hpp if BOOST_HASH_NO_EXTENSIONS + // is not defined. + + // BOOST_HASH_SPECIALIZE - define a specialization for a type which is + // passed by copy. + // + // BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is + // passed by copy. + // + // These are undefined later. #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) #define BOOST_HASH_SPECIALIZE(type) \ @@ -465,7 +477,10 @@ namespace boost #undef BOOST_HASH_SPECIALIZE #undef BOOST_HASH_SPECIALIZE_REF +// Specializing boost::hash for pointers. + #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + template struct hash : public std::unary_function @@ -482,7 +497,15 @@ namespace boost #endif } }; + #else + + // For compilers without partial specialization, we define a + // boost::hash for all remaining types. But hash_impl is only defined + // for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS + // is defined there will still be a compile error for types not supported + // in the standard. + namespace hash_detail { template @@ -515,6 +538,7 @@ namespace boost ::BOOST_NESTED_TEMPLATE inner { }; + #endif } From ebf01f20cac8bbec8c1bbc1a11e89a5e5921e102 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 21 Jun 2009 09:41:30 +0000 Subject: [PATCH 45/82] Move includes to the header which they're used in. [SVN r54140] --- include/boost/functional/hash/extensions.hpp | 8 ++++++++ include/boost/functional/hash/hash.hpp | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/boost/functional/hash/extensions.hpp b/include/boost/functional/hash/extensions.hpp index 02f8bbb..c289056 100644 --- a/include/boost/functional/hash/extensions.hpp +++ b/include/boost/functional/hash/extensions.hpp @@ -14,6 +14,14 @@ # pragma once #endif +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) +#include +#endif + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +#include +#endif + namespace boost { diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 6f8b313..3654cbb 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -21,14 +21,6 @@ #include #endif -#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) -#include -#endif - -#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) -#include -#endif - namespace boost { std::size_t hash_value(bool); From a4a6778f73db5d8ec86925a578bfeba32c0b5656 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 21 Jun 2009 09:41:46 +0000 Subject: [PATCH 46/82] Revert [54025] "Try to avoid using special macro handling code." [SVN r54141] --- .../hash/detail/float_functions.hpp | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 199123d..f766ec9 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -100,8 +100,7 @@ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { #define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \ template \ - boost::hash_detail::not_found c99_func \ - BOOST_PREVENT_MACRO_SUBSTITUTION (Float, type2); \ + boost::hash_detail::not_found c99_func(Float, type2); \ } \ \ namespace boost { \ @@ -164,13 +163,48 @@ namespace boost { \ } \ } -BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int) -BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int) -BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*) -BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*) +#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \ +namespace boost { \ + namespace hash_detail { \ + \ + template <> \ + struct call_##cpp_func { \ + typedef type1 float_type; \ + inline type1 operator()(type1 x, type2 y) const { \ + return c99_func(x, y); \ + } \ + }; \ + } \ +} +#if defined(ldexpf) +BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int) +#else +BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int) +#endif + +#if defined(ldexpl) +BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int) +#else +BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int) +#endif + +#if defined(frexpf) +BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*) +#else +BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*) +#endif + +#if defined(frexpl) +BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*) +#else +BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*) +#endif + +#undef BOOST_HASH_CALL_FLOAT_MACRO #undef BOOST_HASH_CALL_FLOAT_FUNC + namespace boost { namespace hash_detail From 153971fcc3b747449c507d749b54255255c15082 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 21 Jun 2009 09:42:05 +0000 Subject: [PATCH 47/82] Get to work. [SVN r54142] --- hash/test/Jamfile.v2 | 1 + hash/test/extensions_hpp_test.cpp | 17 +++++++++++++++++ include/boost/functional/hash/extensions.hpp | 5 +++++ 3 files changed, 23 insertions(+) create mode 100644 hash/test/extensions_hpp_test.cpp diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index c91691f..0f43439 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -36,6 +36,7 @@ test-suite functional/hash [ run hash_complex_test.cpp ] [ run link_test.cpp link_test_2.cpp ] [ run link_ext_test.cpp link_no_ext_test.cpp ] + [ run extensions_hpp_test.cpp ] [ run container_fwd_test.cpp ] [ compile-fail hash_no_ext_fail_test.cpp ] [ compile-fail namespace_fail_test.cpp ] diff --git a/hash/test/extensions_hpp_test.cpp b/hash/test/extensions_hpp_test.cpp new file mode 100644 index 0000000..182ec01 --- /dev/null +++ b/hash/test/extensions_hpp_test.cpp @@ -0,0 +1,17 @@ + +// Copyright 2009 Daniel James. +// 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) + +// Check that boost/functional/hash/extensions.hpp works okay. +// +// It probably should be in boost/functional/hash/detail, but since it isn't it +// should work. + +#include + +int main() { + int x[2] = { 2, 3 }; + boost::hash hf; + hf(x); +} diff --git a/include/boost/functional/hash/extensions.hpp b/include/boost/functional/hash/extensions.hpp index c289056..7d416f1 100644 --- a/include/boost/functional/hash/extensions.hpp +++ b/include/boost/functional/hash/extensions.hpp @@ -7,6 +7,9 @@ // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf // issue 6.18. +// This implements the extensions to the standard. +// It's undocumented, so you shouldn't use it.... + #if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) #define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP @@ -14,6 +17,8 @@ # pragma once #endif +#include + #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) #include #endif From 0d9f68d607d80f012c48f2b712ff1c92a41303f4 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 21 Jun 2009 09:42:20 +0000 Subject: [PATCH 48/82] Move BOOST_HASH_CHAR_TRAITS from container_fwd into the hash headers, and undefine it. [SVN r54143] --- include/boost/functional/hash/hash.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 3654cbb..17cee1e 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -21,6 +21,12 @@ #include #endif +#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +#define BOOST_HASH_CHAR_TRAITS string_char_traits +#else +#define BOOST_HASH_CHAR_TRAITS char_traits +#endif + namespace boost { std::size_t hash_value(bool); @@ -534,6 +540,8 @@ namespace boost #endif } +#undef BOOST_HASH_CHAR_TRAITS + #endif // BOOST_FUNCTIONAL_HASH_HASH_HPP // Include this outside of the include guards in case the file is included From e661dbe988fd967fc0efeb9eadc5546587eddf69 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 21 Jun 2009 09:42:40 +0000 Subject: [PATCH 49/82] Move the support for hashing containers into the extension header, and improve the standard tests. [SVN r54144] --- hash/test/Jamfile.v2 | 13 ++- hash/test/config.hpp | 2 +- hash/test/hash_complex_test.cpp | 20 +++-- hash/test/hash_float_test.hpp | 20 ++++- hash/test/hash_fwd_test_2.cpp | 10 ++- hash/test/hash_no_ext_macro_1.cpp | 8 ++ hash/test/hash_no_ext_macro_2.cpp | 7 ++ hash/test/hash_range_test.cpp | 21 ++--- hash/test/link_ext_test.cpp | 9 ++ include/boost/functional/hash/extensions.hpp | 84 ++++++++++++++++++- include/boost/functional/hash/hash.hpp | 86 ++------------------ 11 files changed, 170 insertions(+), 110 deletions(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index 0f43439..9004724 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -44,4 +44,15 @@ test-suite functional/hash [ run hash_no_ext_macro_2.cpp ] ; -build-project ../examples ; +test-suite functional/hash_no_ext + : + [ run hash_number_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ] + [ run hash_pointer_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ] + [ run hash_function_pointer_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_function_pointer_test ] + [ run hash_float_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_float_test ] + [ run hash_long_double_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_long_double_test ] + [ run hash_string_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_string_test ] + [ run link_test.cpp link_test_2.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ] + ; + +# build-project ../examples ; diff --git a/hash/test/config.hpp b/hash/test/config.hpp index 0f84cc7..1fd0f5f 100644 --- a/hash/test/config.hpp +++ b/hash/test/config.hpp @@ -5,7 +5,7 @@ #if defined(TEST_STD) # define TEST_STD_INCLUDES -# define HASH_NAMESPACE std::tr1 +# define HASH_NAMESPACE std #else # define HASH_NAMESPACE boost # if !defined(BOOST_HASH_NO_EXTENSIONS) diff --git a/hash/test/hash_complex_test.cpp b/hash/test/hash_complex_test.cpp index 686b25a..f791391 100644 --- a/hash/test/hash_complex_test.cpp +++ b/hash/test/hash_complex_test.cpp @@ -5,18 +5,20 @@ #include "./config.hpp" -#ifdef TEST_EXTENSIONS -# ifdef TEST_STD_INCLUDES -# include -# else -# include -# endif +#if !defined(TEST_EXTENSIONS) + +int main() {} + +#else + +#ifdef TEST_STD_INCLUDES +# include +#else +# include #endif #include -#ifdef TEST_EXTENSIONS - #include #include #include @@ -91,4 +93,4 @@ int main() return boost::report_errors(); } -#endif +#endif // TEST_EXTENSIONS diff --git a/hash/test/hash_float_test.hpp b/hash/test/hash_float_test.hpp index 77c652c..b1c19fc 100644 --- a/hash/test/hash_float_test.hpp +++ b/hash/test/hash_float_test.hpp @@ -15,6 +15,8 @@ #include #include +#include +#include #include @@ -42,8 +44,6 @@ void float_tests(char const* name, T* = 0) <<"\n" <<"boost::hash_detail::call_ldexp::float_type = " <::float_type*)0)<<"\n" - <<"boost::call_frexp::float_type = " - <::float_type*)0)<<"\n" <<"boost::hash_detail::call_frexp::float_type = " <::float_type*)0)<<"\n" <<"boost::hash_detail::select_hash_type::type = " @@ -59,8 +59,10 @@ void float_tests(char const* name, T* = 0) BOOST_TEST(zero == minus_zero); BOOST_TEST(x1(zero) == x1(minus_zero)); +#if defined(TEST_EXTENSIONS) BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero)); BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero)); +#endif using namespace std; @@ -78,9 +80,11 @@ void float_tests(char const* name, T* = 0) T minus_infinity2 = (T) -1. / zero; T minus_infinity3 = (T) 1. / minus_zero; +#if defined(TEST_EXTENSIONS) BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity)); BOOST_TEST(x1(minus_infinity) == HASH_NAMESPACE::hash_value(minus_infinity)); +#endif if(infinity == infinity2) BOOST_TEST(x1(infinity) == x1(infinity2)); @@ -134,10 +138,12 @@ void float_tests(char const* name, T* = 0) BOOST_TEST(half_max != three_quarter_max); BOOST_TEST(quarter_max != three_quarter_max); +#if defined(TEST_EXTENSIONS) BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max)); BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max)); BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max)); BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max)); +#endif // The '!=' tests could legitimately fail, but with my hash it indicates a bug. BOOST_TEST(x1(max) == x1(max)); @@ -159,12 +165,18 @@ void float_tests(char const* name, T* = 0) T v2 = acos((T) 0); if(v1 == v2) BOOST_TEST(x1(v1) == x1(v2)); + +#if defined(TEST_EXTENSIONS) BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1)); BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2)); #endif + +#endif +#if defined(TEST_EXTENSIONS) BOOST_TEST(x1(boost::hash_detail::limits::epsilon()) == HASH_NAMESPACE::hash_value(boost::hash_detail::limits::epsilon())); +#endif BOOST_TEST(boost::hash_detail::limits::epsilon() != (T) 0); if(x1(boost::hash_detail::limits::epsilon()) == x1((T) 0)) @@ -195,7 +207,7 @@ void float_tests(char const* name, T* = 0) if(x1(boost::hash_detail::limits::denorm_min()) == x1(zero)) { std::cerr<<"x1(denorm_min) == x1(zero) == "<::has_quiet_NaN) { if(x1(boost::hash_detail::limits::quiet_NaN()) == x1(1.0)) { std::cerr<<"x1(quiet_NaN) == x1(1.0) == "< template void unused(T const&) {} @@ -30,10 +35,11 @@ void fwd_test() unused(y1); unused(y2); unused(y3); } - int main() { fwd_test(); + return boost::report_errors(); } +#endif // defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES) diff --git a/hash/test/hash_no_ext_macro_1.cpp b/hash/test/hash_no_ext_macro_1.cpp index 640c36a..1d238c0 100644 --- a/hash/test/hash_no_ext_macro_1.cpp +++ b/hash/test/hash_no_ext_macro_1.cpp @@ -4,9 +4,17 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #define HASH_NAMESPACE boost + +// Include header without BOOST_HASH_NO_EXTENSIONS defined +#if defined(BOOST_HASH_NO_EXTENSIONS) +#undef BOOST_HASH_NO_EXTENSIONS +#endif #include + +// Include header with BOOST_HASH_NO_EXTENSIONS defined #define BOOST_HASH_NO_EXTENSIONS #include + #include #include #include diff --git a/hash/test/hash_no_ext_macro_2.cpp b/hash/test/hash_no_ext_macro_2.cpp index 2f53779..6ab083e 100644 --- a/hash/test/hash_no_ext_macro_2.cpp +++ b/hash/test/hash_no_ext_macro_2.cpp @@ -4,10 +4,17 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #define HASH_NAMESPACE boost + +// Include header with BOOST_HASH_NO_EXTENSIONS defined +#if !defined(BOOST_HASH_NO_EXTENSIONS) #define BOOST_HASH_NO_EXTENSIONS +#endif #include + +// Include header without BOOST_HASH_NO_EXTENSIONS defined #undef BOOST_HASH_NO_EXTENSIONS #include + #include #include diff --git a/hash/test/hash_range_test.cpp b/hash/test/hash_range_test.cpp index 66aad26..7d71f45 100644 --- a/hash/test/hash_range_test.cpp +++ b/hash/test/hash_range_test.cpp @@ -5,18 +5,20 @@ #include "./config.hpp" -#ifdef TEST_EXTENSIONS -# ifdef TEST_STD_INCLUDES -# include -# else -# include -# endif +#if !defined(TEST_EXTENSIONS) + +int main() {} + +#else + +#ifdef TEST_STD_INCLUDES +# include +#else +# include #endif #include -#ifdef TEST_EXTENSIONS - #include #include #include @@ -74,8 +76,6 @@ void hash_range_tests() BOOST_TEST(seed == HASH_NAMESPACE::hash_range(values5.begin(), values5.end())); } -#endif - int main() { hash_range_tests(); @@ -83,3 +83,4 @@ int main() return boost::report_errors(); } +#endif // TEST_EXTESNIONS diff --git a/hash/test/link_ext_test.cpp b/hash/test/link_ext_test.cpp index ca4c8f3..d334035 100644 --- a/hash/test/link_ext_test.cpp +++ b/hash/test/link_ext_test.cpp @@ -9,14 +9,23 @@ #include int f(std::size_t hash1, int* x1) { + // Check that HASH_NAMESPACE::hash works in both files. HASH_NAMESPACE::hash ptr_hasher; BOOST_TEST(hash1 == ptr_hasher(x1)); +#if defined(TEST_EXTENSIONS) + // Check that std::vector is avaiable in this file. std::vector x; x.push_back(*x1); HASH_NAMESPACE::hash > vector_hasher; return vector_hasher(x) != HASH_NAMESPACE::hash_value(x); + +#else + + return 0; + +#endif } diff --git a/include/boost/functional/hash/extensions.hpp b/include/boost/functional/hash/extensions.hpp index 7d416f1..3c587a3 100644 --- a/include/boost/functional/hash/extensions.hpp +++ b/include/boost/functional/hash/extensions.hpp @@ -13,12 +13,13 @@ #if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) #define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP +#include +#include + #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif -#include - #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) #include #endif @@ -29,6 +30,85 @@ namespace boost { + template + std::size_t hash_value(std::pair const&); + template + std::size_t hash_value(std::vector const&); + template + std::size_t hash_value(std::list const& v); + template + std::size_t hash_value(std::deque const& v); + template + std::size_t hash_value(std::set const& v); + template + std::size_t hash_value(std::multiset const& v); + template + std::size_t hash_value(std::map const& v); + template + std::size_t hash_value(std::multimap const& v); + + template + std::size_t hash_value(std::complex const&); + + template + std::size_t hash_value(std::pair const& v) + { + std::size_t seed = 0; + hash_combine(seed, v.first); + hash_combine(seed, v.second); + return seed; + } + + template + std::size_t hash_value(std::vector const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::list const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::deque const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::set const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::multiset const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::map const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::multimap const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::complex const& v) + { + boost::hash hasher; + std::size_t seed = hasher(v.imag()); + seed ^= hasher(v.real()) + (seed<<6) + (seed>>2); + return seed; + } // // call_hash_impl diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 17cee1e..89196bc 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -70,26 +69,6 @@ namespace boost template std::size_t hash_value(std::basic_string, A> const&); - template - std::size_t hash_value(std::pair const&); - template - std::size_t hash_value(std::vector const&); - template - std::size_t hash_value(std::list const& v); - template - std::size_t hash_value(std::deque const& v); - template - std::size_t hash_value(std::set const& v); - template - std::size_t hash_value(std::multiset const& v); - template - std::size_t hash_value(std::map const& v); - template - std::size_t hash_value(std::multimap const& v); - - template - std::size_t hash_value(std::complex const&); - // Implementation namespace hash_detail @@ -313,66 +292,6 @@ namespace boost return boost::hash_detail::float_hash_value(v); } - template - std::size_t hash_value(std::pair const& v) - { - std::size_t seed = 0; - hash_combine(seed, v.first); - hash_combine(seed, v.second); - return seed; - } - - template - std::size_t hash_value(std::vector const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::list const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::deque const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::set const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::multiset const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::map const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::multimap const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::complex const& v) - { - boost::hash hasher; - std::size_t seed = hasher(v.imag()); - seed ^= hasher(v.real()) + (seed<<6) + (seed>>2); - return seed; - } - // // boost::hash // @@ -472,6 +391,11 @@ namespace boost BOOST_HASH_SPECIALIZE_REF(std::wstring) #endif +#if defined(BOOST_HAS_LONG_LONG) + BOOST_HASH_SPECIALIZE(boost::long_long_type); + BOOST_HASH_SPECIALIZE(boost::ulong_long_type); +#endif + #undef BOOST_HASH_SPECIALIZE #undef BOOST_HASH_SPECIALIZE_REF From 0f9879abbe82e984c84b32becf3718ce660fc338 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 21 Jun 2009 09:51:59 +0000 Subject: [PATCH 50/82] I didn't mean to comment this out. [SVN r54145] --- hash/test/Jamfile.v2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index 9004724..ea19365 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -55,4 +55,4 @@ test-suite functional/hash_no_ext [ run link_test.cpp link_test_2.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ] ; -# build-project ../examples ; +build-project ../examples ; From f2dd570ee9574f8244aa68882f19e86a1cde5c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Hunold?= Date: Sun, 21 Jun 2009 14:38:19 +0000 Subject: [PATCH 51/82] Fix gcc -pedantic warning: remove extra ";". [SVN r54146] --- include/boost/functional/hash/hash.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 89196bc..6784f3e 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -392,8 +392,8 @@ namespace boost #endif #if defined(BOOST_HAS_LONG_LONG) - BOOST_HASH_SPECIALIZE(boost::long_long_type); - BOOST_HASH_SPECIALIZE(boost::ulong_long_type); + BOOST_HASH_SPECIALIZE(boost::long_long_type) + BOOST_HASH_SPECIALIZE(boost::ulong_long_type) #endif #undef BOOST_HASH_SPECIALIZE From 4936095357ac13d933ae0f992f10e9b0f66196a7 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 27 Jun 2009 07:39:12 +0000 Subject: [PATCH 52/82] Add am implementation note about the Visual C++ problems. [SVN r54399] --- include/boost/functional/hash/detail/float_functions.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index f766ec9..01cac09 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -96,6 +96,11 @@ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { // Then the call_* functions select an appropriate implementation. // // I used c99_func in a few places just to get a unique name. +// +// Important: when using 'using namespace' at namespace level, include as +// little as possible in that namespace, as Visual C++ has an odd bug which +// can cause the namespace to be imported at the global level. This seems to +// happen mainly when there's a template in the same namesapce. #define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \ From 166f4b10797d094a5af69da3356b6eeee914b4e8 Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Sun, 26 Jul 2009 00:49:56 +0000 Subject: [PATCH 53/82] Copyrights on CMakeLists.txt to keep them from clogging up the inspect reports. This is essentially the same commit as r55095 on the release branch. [SVN r55159] --- CMakeLists.txt | 6 ++++++ hash/doc/CMakeLists.txt | 6 ++++++ hash/examples/CMakeLists.txt | 6 ++++++ hash/test/CMakeLists.txt | 6 ++++++ test/CMakeLists.txt | 6 ++++++ 5 files changed, 30 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index bcd5130..6a28765 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# #---------------------------------------------------------------------------- # This file was automatically generated from the original CMakeLists.txt file # Add a variable to hold the headers for the library diff --git a/hash/doc/CMakeLists.txt b/hash/doc/CMakeLists.txt index cd83029..f9e29c0 100644 --- a/hash/doc/CMakeLists.txt +++ b/hash/doc/CMakeLists.txt @@ -1,2 +1,8 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# message(STATUS "functional/hash docs need love") diff --git a/hash/examples/CMakeLists.txt b/hash/examples/CMakeLists.txt index 9a5efc8..347a9b2 100644 --- a/hash/examples/CMakeLists.txt +++ b/hash/examples/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# #------------------------------------------------------------------------- #-- Needed include directories for the tests boost_additional_test_dependencies(config BOOST_DEPENDS test) diff --git a/hash/test/CMakeLists.txt b/hash/test/CMakeLists.txt index a4e132b..8e90152 100644 --- a/hash/test/CMakeLists.txt +++ b/hash/test/CMakeLists.txt @@ -1,3 +1,9 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# #project hash-tests # : requirements # gcc:_GLIBCXX_DEBUG diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 79691c3..2bd7a7d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1 +1,7 @@ +# +# Copyright Troy D. Straszheim +# +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt +# boost_test_run(function_test function_test.cpp) From f40913cd44e12f20771429f18213c5e9f28c4b0e Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 5 Oct 2009 21:29:39 +0000 Subject: [PATCH 54/82] Various inspect fixes. [SVN r56603] --- hash/test/namespace_fail_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hash/test/namespace_fail_test.cpp b/hash/test/namespace_fail_test.cpp index d3c13aa..711ddd0 100644 --- a/hash/test/namespace_fail_test.cpp +++ b/hash/test/namespace_fail_test.cpp @@ -11,4 +11,4 @@ typedef list foo; -int main() {} \ No newline at end of file +int main() {} From ccaec4eb947f60b00a357136baa306cf45070787 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 10 Oct 2009 15:09:02 +0000 Subject: [PATCH 55/82] Copy the unordered and hash CMake files from release. [SVN r56704] --- hash/test/CMakeLists.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hash/test/CMakeLists.txt b/hash/test/CMakeLists.txt index 8e90152..ca45f5d 100644 --- a/hash/test/CMakeLists.txt +++ b/hash/test/CMakeLists.txt @@ -22,12 +22,13 @@ endif(GCC) #------------------------------------------------------------------------- SET(tests -hash_float_test hash_fwd_test_1 hash_fwd_test_2 hash_number_test hash_pointer_test hash_function_pointer_test +hash_float_test +hash_long_double_test hash_string_test hash_range_test hash_custom_test @@ -40,18 +41,18 @@ hash_list_test hash_deque_test hash_set_test hash_map_test +hash_complex_test container_fwd_test hash_no_ext_macro_1 hash_no_ext_macro_2 ) boost_test_run(link_test link_test.cpp link_test_2.cpp) -boost_test_run(link_ext_test link_ext_test.cpp link_no_ext_test.cpp) - +boost_test_run(link_ext_test link_ext_test.cpp link_no_ext_test.cpp +) foreach(test ${tests}) boost_test_run(${test}) endforeach(test ${tests}) boost_test_compile_fail(hash_no_ext_fail_test) -# build-project ../examples ; From d108788cf6098bad43d19f39b46f34a6b964dbb2 Mon Sep 17 00:00:00 2001 From: "Troy D. Straszheim" Date: Sat, 17 Oct 2009 02:07:38 +0000 Subject: [PATCH 56/82] rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back [SVN r56942] --- CMakeLists.txt | 28 ----------------- hash/doc/CMakeLists.txt | 8 ----- hash/examples/CMakeLists.txt | 15 ---------- hash/test/CMakeLists.txt | 58 ------------------------------------ module.cmake | 1 - test/CMakeLists.txt | 7 ----- 6 files changed, 117 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 hash/doc/CMakeLists.txt delete mode 100644 hash/examples/CMakeLists.txt delete mode 100644 hash/test/CMakeLists.txt delete mode 100644 module.cmake delete mode 100644 test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 6a28765..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -#---------------------------------------------------------------------------- -# This file was automatically generated from the original CMakeLists.txt file -# Add a variable to hold the headers for the library -set (lib_headers - functional.hpp - functional -) - -# Add a library target to the build system -boost_library_project( - functional - # SRCDIRS - TESTDIRS test hash/test hash/examples - HEADERS ${lib_headers} - DOCDIRS hash/doc - # DESCRIPTION - MODULARIZED - # AUTHORS - # MAINTAINERS -) - - diff --git a/hash/doc/CMakeLists.txt b/hash/doc/CMakeLists.txt deleted file mode 100644 index f9e29c0..0000000 --- a/hash/doc/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -message(STATUS "functional/hash docs need love") - diff --git a/hash/examples/CMakeLists.txt b/hash/examples/CMakeLists.txt deleted file mode 100644 index 347a9b2..0000000 --- a/hash/examples/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -#------------------------------------------------------------------------- -#-- Needed include directories for the tests -boost_additional_test_dependencies(config BOOST_DEPENDS test) -#------------------------------------------------------------------------- -boost_test_run(books) -boost_test_run(point) -boost_test_run(portable) - - diff --git a/hash/test/CMakeLists.txt b/hash/test/CMakeLists.txt deleted file mode 100644 index ca45f5d..0000000 --- a/hash/test/CMakeLists.txt +++ /dev/null @@ -1,58 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -#project hash-tests -# : requirements -# gcc:_GLIBCXX_DEBUG -# ; -if (GCC) - ADD_DEFINITIONS(-D_GLIBCXX_DEBUG) -endif(GCC) - -# [ run .cpp : : : always_show_run_output ] - - - -#------------------------------------------------------------------------- -#-- Needed include directories for the tests - boost_additional_test_dependencies(functional BOOST_DEPENDS test) -#------------------------------------------------------------------------- - -SET(tests -hash_fwd_test_1 -hash_fwd_test_2 -hash_number_test -hash_pointer_test -hash_function_pointer_test -hash_float_test -hash_long_double_test -hash_string_test -hash_range_test -hash_custom_test -hash_global_namespace_test -hash_friend_test -hash_built_in_array_test -hash_value_array_test -hash_vector_test -hash_list_test -hash_deque_test -hash_set_test -hash_map_test -hash_complex_test -container_fwd_test -hash_no_ext_macro_1 -hash_no_ext_macro_2 -) - -boost_test_run(link_test link_test.cpp link_test_2.cpp) -boost_test_run(link_ext_test link_ext_test.cpp link_no_ext_test.cpp -) -foreach(test ${tests}) - boost_test_run(${test}) -endforeach(test ${tests}) - -boost_test_compile_fail(hash_no_ext_fail_test) - diff --git a/module.cmake b/module.cmake deleted file mode 100644 index f10d82e..0000000 --- a/module.cmake +++ /dev/null @@ -1 +0,0 @@ -boost_module(functional DEPENDS integer) \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index 2bd7a7d..0000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# -# Copyright Troy D. Straszheim -# -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt -# -boost_test_run(function_test function_test.cpp) From ed8c404ca6fae957e581d40d9ca3f5d358cdfce3 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 10 Nov 2009 08:15:55 +0000 Subject: [PATCH 57/82] Stricter warnings for unordered and hash. There are still warnings in hash_complex_test. [SVN r57537] --- hash/test/Jamfile.v2 | 18 +++++++++++++----- hash/test/hash_no_ext_fail_test.cpp | 3 +++ include/boost/functional/hash/hash.hpp | 13 +++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index ea19365..e261cff 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -7,9 +7,16 @@ import testing ; project hash-tests : requirements + all + intel:on + intel:-strict-ansi + gcc:"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter" + darwin:"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter" gcc:_GLIBCXX_DEBUG - gcc:-Wsign-promo - #gcc:-Wextra + darwin:_GLIBCXX_DEBUG + msvc:on + gcc:on + darwin:on ; test-suite functional/hash @@ -33,13 +40,14 @@ test-suite functional/hash [ run hash_deque_test.cpp ] [ run hash_set_test.cpp ] [ run hash_map_test.cpp ] - [ run hash_complex_test.cpp ] + [ run hash_complex_test.cpp : : : off ] [ run link_test.cpp link_test_2.cpp ] [ run link_ext_test.cpp link_no_ext_test.cpp ] [ run extensions_hpp_test.cpp ] [ run container_fwd_test.cpp ] - [ compile-fail hash_no_ext_fail_test.cpp ] - [ compile-fail namespace_fail_test.cpp ] + # Don't want compile-fail tests to fail because of warnings. + [ compile-fail hash_no_ext_fail_test.cpp : : : off ] + [ compile-fail namespace_fail_test.cpp : : : off ] [ run hash_no_ext_macro_1.cpp ] [ run hash_no_ext_macro_2.cpp ] ; diff --git a/hash/test/hash_no_ext_fail_test.cpp b/hash/test/hash_no_ext_fail_test.cpp index ef7ae96..a29f8d5 100644 --- a/hash/test/hash_no_ext_fail_test.cpp +++ b/hash/test/hash_no_ext_fail_test.cpp @@ -12,8 +12,11 @@ #include #include +template void ignore(T const&) {} + int main() { HASH_NAMESPACE::hash< int[10] > hasher; + ignore(hasher); return 0; } diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 6784f3e..ce1ce94 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -197,6 +197,15 @@ namespace boost return x + (x >> 3); } +#if defined(BOOST_MSVC) +#pragma warning(push) +#if BOOST_MSVC == 1400 +#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to 'unsigned int', + // possible loss of data + // A misguided attempt to detect 64-bit incompatability. +#endif +#endif + #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) template inline void hash_combine(std::size_t& seed, T& v) @@ -209,6 +218,10 @@ namespace boost seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); } +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + template inline std::size_t hash_range(It first, It last) { From 84c30e4fd70c22239a33bd80c62a968716c3872a Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 11 Nov 2009 14:03:44 +0000 Subject: [PATCH 58/82] Remove 'warnings-as-errors' flag that was breaking the build. [SVN r57564] --- hash/test/Jamfile.v2 | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index e261cff..f4e1fff 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -14,9 +14,6 @@ project hash-tests darwin:"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter" gcc:_GLIBCXX_DEBUG darwin:_GLIBCXX_DEBUG - msvc:on - gcc:on - darwin:on ; test-suite functional/hash @@ -40,14 +37,13 @@ test-suite functional/hash [ run hash_deque_test.cpp ] [ run hash_set_test.cpp ] [ run hash_map_test.cpp ] - [ run hash_complex_test.cpp : : : off ] + [ run hash_complex_test.cpp ] [ run link_test.cpp link_test_2.cpp ] [ run link_ext_test.cpp link_no_ext_test.cpp ] [ run extensions_hpp_test.cpp ] [ run container_fwd_test.cpp ] - # Don't want compile-fail tests to fail because of warnings. - [ compile-fail hash_no_ext_fail_test.cpp : : : off ] - [ compile-fail namespace_fail_test.cpp : : : off ] + [ compile-fail hash_no_ext_fail_test.cpp ] + [ compile-fail namespace_fail_test.cpp ] [ run hash_no_ext_macro_1.cpp ] [ run hash_no_ext_macro_2.cpp ] ; From 32917c2bd147c58d59cad631ad0f95782af9787f Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 16 Nov 2009 23:56:56 +0000 Subject: [PATCH 59/82] Turn on warnings as errors for the hash tests. [SVN r57720] --- hash/test/Jamfile.v2 | 3 +++ hash/test/hash_complex_test.cpp | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index f4e1fff..bff1622 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -14,6 +14,9 @@ project hash-tests darwin:"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter" gcc:_GLIBCXX_DEBUG darwin:_GLIBCXX_DEBUG + msvc:on + gcc:on + darwin:on ; test-suite functional/hash diff --git a/hash/test/hash_complex_test.cpp b/hash/test/hash_complex_test.cpp index f791391..80b8974 100644 --- a/hash/test/hash_complex_test.cpp +++ b/hash/test/hash_complex_test.cpp @@ -80,13 +80,17 @@ void complex_integral_tests(Integer*) int main() { + // I've comments out the short and unsigned short tests + // as they cause warnings and don't really test + // anything that the other tests already deal with. + complex_float_tests((float*) 0); complex_float_tests((double*) 0); complex_float_tests((long double*) 0); - complex_integral_tests((short*) 0); + //complex_integral_tests((short*) 0); complex_integral_tests((int*) 0); complex_integral_tests((long*) 0); - complex_integral_tests((unsigned short*) 0); + //complex_integral_tests((unsigned short*) 0); complex_integral_tests((unsigned int*) 0); complex_integral_tests((unsigned long*) 0); From b647aba2cdbb28a5b1ac5cd09586e46c8eb6a357 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 21 Nov 2009 19:40:54 +0000 Subject: [PATCH 60/82] Fix some hash /W4 warnings. Fixes #3648 [SVN r57839] --- hash/examples/books.cpp | 1 + hash/test/hash_complex_test.cpp | 14 ++++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/hash/examples/books.cpp b/hash/examples/books.cpp index d54b353..40feae3 100644 --- a/hash/examples/books.cpp +++ b/hash/examples/books.cpp @@ -20,6 +20,7 @@ int main() boost::hash book_hasher; std::size_t knife_hash_value = book_hasher(knife); + (void)knife_hash_value; // suppress unused variable warning // If std::unordered_set was available: // diff --git a/hash/test/hash_complex_test.cpp b/hash/test/hash_complex_test.cpp index 80b8974..7adffd9 100644 --- a/hash/test/hash_complex_test.cpp +++ b/hash/test/hash_complex_test.cpp @@ -19,19 +19,17 @@ int main() {} #include -#include -#include -#include - #if defined(BOOST_MSVC) -#pragma warning(push) #pragma warning(disable:4244) // conversion from 'unsigned long' to 'unsigned short', possible loss of data +#pragma warning(disable:4245) // conversion from 'int' to 'const unsigned short', signed/unsigned mismatch +#pragma warning(disable:4305) // truncation from 'double' to 'const std::complex::_Ty' +#pragma warning(disable:4309) // truncation of constant value #pragma warning(disable:4512) // assignment operator could not be generated #endif -#if defined(BOOST_MSVC) -#pragma warning(pop) -#endif +#include +#include +#include template void generic_complex_tests(std::complex v) From 4c4ba633c3a52d0c766f2c7a1a015436299901a6 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Thu, 26 Nov 2009 23:15:30 +0000 Subject: [PATCH 61/82] Suppress a warning that's in the windows mobile system headers. [SVN r57963] --- hash/test/config.hpp | 6 ++++++ hash/test/container_fwd_test.cpp | 2 ++ hash/test/extensions_hpp_test.cpp | 2 ++ hash/test/hash_custom_test.cpp | 1 + hash/test/hash_friend_test.cpp | 2 ++ hash/test/hash_fwd_test_1.cpp | 2 ++ hash/test/hash_fwd_test_2.cpp | 2 ++ hash/test/hash_global_namespace_test.cpp | 2 ++ hash/test/hash_no_ext_fail_test.cpp | 14 ++++++++++---- hash/test/hash_no_ext_macro_1.cpp | 20 ++++++++++++-------- hash/test/hash_no_ext_macro_2.cpp | 19 ++++++++++++------- hash/test/link_ext_test.cpp | 2 ++ hash/test/link_no_ext_test.cpp | 2 ++ hash/test/link_test.cpp | 2 ++ hash/test/link_test_2.cpp | 2 ++ hash/test/namespace_fail_test.cpp | 2 ++ 16 files changed, 63 insertions(+), 19 deletions(-) diff --git a/hash/test/config.hpp b/hash/test/config.hpp index 1fd0f5f..893f456 100644 --- a/hash/test/config.hpp +++ b/hash/test/config.hpp @@ -12,3 +12,9 @@ # define TEST_EXTENSIONS # endif #endif + +#if defined(_WIN32_WCE) +// The standard windows mobile headers trigger this warning so I disable it +// before doing anything else. +#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union +#endif diff --git a/hash/test/container_fwd_test.cpp b/hash/test/container_fwd_test.cpp index 87f5b90..a63c086 100644 --- a/hash/test/container_fwd_test.cpp +++ b/hash/test/container_fwd_test.cpp @@ -3,6 +3,8 @@ // 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) +#include "./config.hpp" + #include #if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) diff --git a/hash/test/extensions_hpp_test.cpp b/hash/test/extensions_hpp_test.cpp index 182ec01..c27981a 100644 --- a/hash/test/extensions_hpp_test.cpp +++ b/hash/test/extensions_hpp_test.cpp @@ -8,6 +8,8 @@ // It probably should be in boost/functional/hash/detail, but since it isn't it // should work. +#include "./config.hpp" + #include int main() { diff --git a/hash/test/hash_custom_test.cpp b/hash/test/hash_custom_test.cpp index 9943d0c..fb37d91 100644 --- a/hash/test/hash_custom_test.cpp +++ b/hash/test/hash_custom_test.cpp @@ -3,6 +3,7 @@ // 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) +#include "./config.hpp" #include #include diff --git a/hash/test/hash_friend_test.cpp b/hash/test/hash_friend_test.cpp index cac4c7f..8a493e2 100644 --- a/hash/test/hash_friend_test.cpp +++ b/hash/test/hash_friend_test.cpp @@ -3,6 +3,8 @@ // 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) +#include "./config.hpp" + #include #include diff --git a/hash/test/hash_fwd_test_1.cpp b/hash/test/hash_fwd_test_1.cpp index e9a1cd8..6c7f8d3 100644 --- a/hash/test/hash_fwd_test_1.cpp +++ b/hash/test/hash_fwd_test_1.cpp @@ -5,6 +5,8 @@ // This checks that template code implemented using hash_fwd will work. +#include "./config.hpp" + #include "./hash_fwd_test.hpp" #include diff --git a/hash/test/hash_fwd_test_2.cpp b/hash/test/hash_fwd_test_2.cpp index cf6e163..869f67b 100644 --- a/hash/test/hash_fwd_test_2.cpp +++ b/hash/test/hash_fwd_test_2.cpp @@ -6,6 +6,8 @@ // This test just makes sure a header which uses hash_fwd can compile without // the main hash headers. +#include "./config.hpp" + #if !defined(TEST_EXTENSIONS) || defined(TEST_STD_INCLUDES) int main() {} diff --git a/hash/test/hash_global_namespace_test.cpp b/hash/test/hash_global_namespace_test.cpp index a45278c..ccb99e7 100644 --- a/hash/test/hash_global_namespace_test.cpp +++ b/hash/test/hash_global_namespace_test.cpp @@ -6,6 +6,8 @@ // This test demonstrates an ADL bug in Borland 5.5 where ADL isn't performed // in the global namespace. +#include "./config.hpp" + #include #include diff --git a/hash/test/hash_no_ext_fail_test.cpp b/hash/test/hash_no_ext_fail_test.cpp index a29f8d5..22f6f5a 100644 --- a/hash/test/hash_no_ext_fail_test.cpp +++ b/hash/test/hash_no_ext_fail_test.cpp @@ -3,14 +3,19 @@ // 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) -#define HASH_NAMESPACE boost +#include "./config.hpp" // Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions // (or at least one of them). -#define BOOST_HASH_NO_EXTENSIONS +#if !defined(BOOST_HASH_NO_EXTENSIONS) +# define BOOST_HASH_NO_EXTENSIONS +#endif -#include -#include +#ifdef TEST_STD_INCLUDES +# include +#else +# include +#endif template void ignore(T const&) {} @@ -18,5 +23,6 @@ int main() { HASH_NAMESPACE::hash< int[10] > hasher; ignore(hasher); + return 0; } diff --git a/hash/test/hash_no_ext_macro_1.cpp b/hash/test/hash_no_ext_macro_1.cpp index 1d238c0..ea727bb 100644 --- a/hash/test/hash_no_ext_macro_1.cpp +++ b/hash/test/hash_no_ext_macro_1.cpp @@ -3,24 +3,27 @@ // 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) -#define HASH_NAMESPACE boost +#include "./config.hpp" + +#if defined(TEST_EXTENSIONS) // Include header without BOOST_HASH_NO_EXTENSIONS defined -#if defined(BOOST_HASH_NO_EXTENSIONS) -#undef BOOST_HASH_NO_EXTENSIONS -#endif -#include +# if defined(BOOST_HASH_NO_EXTENSIONS) +# undef BOOST_HASH_NO_EXTENSIONS +# endif +# include // Include header with BOOST_HASH_NO_EXTENSIONS defined -#define BOOST_HASH_NO_EXTENSIONS -#include +# define BOOST_HASH_NO_EXTENSIONS +# include +#endif #include #include -#include int main() { +#if defined(TEST_EXTENSIONS) std::deque x; x.push_back(1); @@ -28,6 +31,7 @@ int main() HASH_NAMESPACE::hash > hasher; BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x)); +#endif return boost::report_errors(); } diff --git a/hash/test/hash_no_ext_macro_2.cpp b/hash/test/hash_no_ext_macro_2.cpp index 6ab083e..a8d8c65 100644 --- a/hash/test/hash_no_ext_macro_2.cpp +++ b/hash/test/hash_no_ext_macro_2.cpp @@ -3,23 +3,27 @@ // 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) -#define HASH_NAMESPACE boost +#include "./config.hpp" + +#if defined(TEST_EXTENSIONS) // Include header with BOOST_HASH_NO_EXTENSIONS defined -#if !defined(BOOST_HASH_NO_EXTENSIONS) -#define BOOST_HASH_NO_EXTENSIONS -#endif -#include +# if !defined(BOOST_HASH_NO_EXTENSIONS) +# define BOOST_HASH_NO_EXTENSIONS +# endif +# include // Include header without BOOST_HASH_NO_EXTENSIONS defined -#undef BOOST_HASH_NO_EXTENSIONS -#include +# undef BOOST_HASH_NO_EXTENSIONS +# include +#endif #include #include int main() { +#if defined(TEST_EXTENSIONS) std::map x; x.insert(std::map::value_type(53, -42)); @@ -27,6 +31,7 @@ int main() HASH_NAMESPACE::hash > hasher; BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x)); +#endif return boost::report_errors(); } diff --git a/hash/test/link_ext_test.cpp b/hash/test/link_ext_test.cpp index d334035..c0e224c 100644 --- a/hash/test/link_ext_test.cpp +++ b/hash/test/link_ext_test.cpp @@ -3,6 +3,8 @@ // 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) +#include "./config.hpp" + #define HASH_NAMESPACE boost #include #include diff --git a/hash/test/link_no_ext_test.cpp b/hash/test/link_no_ext_test.cpp index 7f46984..c2e6869 100644 --- a/hash/test/link_no_ext_test.cpp +++ b/hash/test/link_no_ext_test.cpp @@ -3,6 +3,8 @@ // 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) +#include "./config.hpp" + #define HASH_NAMESPACE boost #define BOOST_HASH_NO_EXTENSIONS #include diff --git a/hash/test/link_test.cpp b/hash/test/link_test.cpp index 37f9ee1..bdae262 100644 --- a/hash/test/link_test.cpp +++ b/hash/test/link_test.cpp @@ -3,6 +3,8 @@ // 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) +#include "./config.hpp" + #include extern int f(); diff --git a/hash/test/link_test_2.cpp b/hash/test/link_test_2.cpp index f32065c..1beffc8 100644 --- a/hash/test/link_test_2.cpp +++ b/hash/test/link_test_2.cpp @@ -3,6 +3,8 @@ // 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) +#include "./config.hpp" + #include int f() { return 0; } diff --git a/hash/test/namespace_fail_test.cpp b/hash/test/namespace_fail_test.cpp index 711ddd0..1db9fc6 100644 --- a/hash/test/namespace_fail_test.cpp +++ b/hash/test/namespace_fail_test.cpp @@ -6,6 +6,8 @@ // Check that I haven't inadvertantly pulled namespace std into the global // namespace. +#include "./config.hpp" + #include #include From ec3632c322c701462a3dab25c203e1997ecabd80 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 27 Nov 2009 19:43:26 +0000 Subject: [PATCH 62/82] Try to suppress some more Visual C++ warnings. [SVN r57976] --- hash/test/hash_complex_test.cpp | 3 +++ hash/test/hash_float_test.hpp | 4 ++++ include/boost/functional/hash/hash.hpp | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/hash/test/hash_complex_test.cpp b/hash/test/hash_complex_test.cpp index 7adffd9..3d7c200 100644 --- a/hash/test/hash_complex_test.cpp +++ b/hash/test/hash_complex_test.cpp @@ -25,6 +25,9 @@ int main() {} #pragma warning(disable:4305) // truncation from 'double' to 'const std::complex::_Ty' #pragma warning(disable:4309) // truncation of constant value #pragma warning(disable:4512) // assignment operator could not be generated +#if BOOST_MSVC < 1400 +#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int', possible loss of data +#endif #endif #include diff --git a/hash/test/hash_float_test.hpp b/hash/test/hash_float_test.hpp index b1c19fc..ab3cbf2 100644 --- a/hash/test/hash_float_test.hpp +++ b/hash/test/hash_float_test.hpp @@ -23,6 +23,10 @@ #if defined(BOOST_MSVC) #pragma warning(push) #pragma warning(disable:4127) // conditional expression is constant +#pragma warning(disable:4723) // conditional expression is constant +#if BOOST_MSVC < 1400 +#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int', possible loss of data +#endif #endif char const* float_type(float*) { return "float"; } diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index ce1ce94..697cb41 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -199,7 +199,7 @@ namespace boost #if defined(BOOST_MSVC) #pragma warning(push) -#if BOOST_MSVC == 1400 +#if BOOST_MSVC <= 1400 #pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to 'unsigned int', // possible loss of data // A misguided attempt to detect 64-bit incompatability. From 33e7610ed78958341800f14231cfac3c4db98922 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 1 Dec 2009 08:52:10 +0000 Subject: [PATCH 63/82] Suppress another warning. [SVN r58078] --- hash/test/hash_map_test.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hash/test/hash_map_test.hpp b/hash/test/hash_map_test.hpp index 3b52a50..6e85dcf 100644 --- a/hash/test/hash_map_test.hpp +++ b/hash/test/hash_map_test.hpp @@ -11,6 +11,7 @@ #if defined(BOOST_MSVC) #pragma warning(push) +#pragma warning(disable:4244) // conversion from 'int' to 'float' #pragma warning(disable:4245) // signed/unsigned mismatch #endif From fbd3e1c7ead902b997df1581bd961a4b62945681 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 15 Dec 2009 13:16:32 +0000 Subject: [PATCH 64/82] Turn off warnings as errors on gcc/darwin because the integer library currently causes some warnings. [SVN r58394] --- hash/test/Jamfile.v2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index bff1622..00b9021 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -15,8 +15,8 @@ project hash-tests gcc:_GLIBCXX_DEBUG darwin:_GLIBCXX_DEBUG msvc:on - gcc:on - darwin:on + #gcc:on + #darwin:on ; test-suite functional/hash From 7fc5d819337b0a8bc0a4752203a9d89ba42a1822 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 15 Dec 2009 13:16:50 +0000 Subject: [PATCH 65/82] Only use gcc debug containers on the container_fwd_test. [SVN r58395] --- hash/test/Jamfile.v2 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index 00b9021..f977fa9 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -12,8 +12,6 @@ project hash-tests intel:-strict-ansi gcc:"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter" darwin:"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter" - gcc:_GLIBCXX_DEBUG - darwin:_GLIBCXX_DEBUG msvc:on #gcc:on #darwin:on @@ -45,6 +43,7 @@ test-suite functional/hash [ run link_ext_test.cpp link_no_ext_test.cpp ] [ run extensions_hpp_test.cpp ] [ run container_fwd_test.cpp ] + [ run container_fwd_test.cpp : : : _GLIBCXX_DEBUG : container_fwd_gcc_debug ] [ compile-fail hash_no_ext_fail_test.cpp ] [ compile-fail namespace_fail_test.cpp ] [ run hash_no_ext_macro_1.cpp ] From 109b4d8258c59f95732f15a5910cfacaef237503 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 29 Dec 2009 18:06:41 +0000 Subject: [PATCH 66/82] Only use _GLIBCXX_DEBUG on gcc/darwin. It looks like pathscale also uses the gcc library but debug mode doesn't work on it. [SVN r58567] --- hash/test/Jamfile.v2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index f977fa9..21594ee 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -43,7 +43,10 @@ test-suite functional/hash [ run link_ext_test.cpp link_no_ext_test.cpp ] [ run extensions_hpp_test.cpp ] [ run container_fwd_test.cpp ] - [ run container_fwd_test.cpp : : : _GLIBCXX_DEBUG : container_fwd_gcc_debug ] + [ run container_fwd_test.cpp : : + : gcc:_GLIBCXX_DEBUG + darwin:_GLIBCXX_DEBUG + : container_fwd_gcc_debug ] [ compile-fail hash_no_ext_fail_test.cpp ] [ compile-fail namespace_fail_test.cpp ] [ run hash_no_ext_macro_1.cpp ] From 6fe052f27e0895dcb3755f0dae9ef5dcfd5299c7 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 2 Jan 2010 11:12:23 +0000 Subject: [PATCH 67/82] Rename namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS to lower case for consistency. [SVN r58632] --- include/boost/functional/hash/detail/float_functions.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index 01cac09..ae03ff0 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -84,7 +84,7 @@ namespace boost { // the boost namespace they'll always be preferable to any other function // (since the arguments are built in types, ADL can't be used). -namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { +namespace boost_hash_detect_float_functions { template boost::hash_detail::not_found ldexp(Float, int); template boost::hash_detail::not_found frexp(Float, int*); } @@ -103,7 +103,7 @@ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { // happen mainly when there's a template in the same namesapce. #define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \ -namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \ +namespace boost_hash_detect_float_functions { \ template \ boost::hash_detail::not_found c99_func(Float, type2); \ } \ @@ -112,7 +112,7 @@ namespace boost { \ namespace hash_detail { \ namespace c99_func##_detect { \ using namespace std; \ - using namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS; \ + using namespace boost_hash_detect_float_functions; \ \ struct check { \ static type1 x; \ From a3cabbe60184b91f0439820535b671cd51460e3e Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 4 Jan 2010 22:49:39 +0000 Subject: [PATCH 68/82] Formatting changes, mostly to fit within 80 characters. Also, some C casts converted to static_cast. [SVN r58692] --- hash/test/config.hpp | 3 +- hash/test/container_fwd_test.cpp | 9 +- hash/test/hash_complex_test.cpp | 17 ++-- hash/test/hash_custom_test.cpp | 4 +- hash/test/hash_float_test.hpp | 121 +++++++++++++++-------- hash/test/hash_friend_test.cpp | 4 +- hash/test/hash_fwd_test.hpp | 6 +- hash/test/hash_fwd_test_1.cpp | 7 +- hash/test/hash_global_namespace_test.cpp | 4 +- hash/test/hash_number_test.cpp | 5 +- hash/test/hash_range_test.cpp | 6 +- include/boost/functional/hash/hash.hpp | 20 ++-- 12 files changed, 135 insertions(+), 71 deletions(-) diff --git a/hash/test/config.hpp b/hash/test/config.hpp index 893f456..216d9c4 100644 --- a/hash/test/config.hpp +++ b/hash/test/config.hpp @@ -16,5 +16,6 @@ #if defined(_WIN32_WCE) // The standard windows mobile headers trigger this warning so I disable it // before doing anything else. -#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) // nonstandard extension used : + // nameless struct/union #endif diff --git a/hash/test/container_fwd_test.cpp b/hash/test/container_fwd_test.cpp index a63c086..ec8cc54 100644 --- a/hash/test/container_fwd_test.cpp +++ b/hash/test/container_fwd_test.cpp @@ -7,14 +7,17 @@ #include -#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +#if BOOST_WORKAROUND(__GNUC__, < 3) && \ + !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) template -static void test(std::basic_string, Allocator> const&) +static void test( + std::basic_string, Allocator> const&) { } #else template -static void test(std::basic_string, Allocator> const&) +static void test( + std::basic_string, Allocator> const&) { } #endif diff --git a/hash/test/hash_complex_test.cpp b/hash/test/hash_complex_test.cpp index 3d7c200..a2a2dc2 100644 --- a/hash/test/hash_complex_test.cpp +++ b/hash/test/hash_complex_test.cpp @@ -20,13 +20,18 @@ int main() {} #include #if defined(BOOST_MSVC) -#pragma warning(disable:4244) // conversion from 'unsigned long' to 'unsigned short', possible loss of data -#pragma warning(disable:4245) // conversion from 'int' to 'const unsigned short', signed/unsigned mismatch -#pragma warning(disable:4305) // truncation from 'double' to 'const std::complex::_Ty' -#pragma warning(disable:4309) // truncation of constant value -#pragma warning(disable:4512) // assignment operator could not be generated +#pragma warning(disable:4244) // conversion from 'unsigned long' to + // 'unsigned short', possible loss of data +#pragma warning(disable:4245) // conversion from 'int' to + // 'const unsigned short', + // signed/unsigned mismatch +#pragma warning(disable:4305) // truncation from 'double' to + // 'const std::complex::_Ty' +#pragma warning(disable:4309) // truncation of constant value +#pragma warning(disable:4512) // assignment operator could not be generated #if BOOST_MSVC < 1400 -#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int', possible loss of data +#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int', + // possible loss of data #endif #endif diff --git a/hash/test/hash_custom_test.cpp b/hash/test/hash_custom_test.cpp index fb37d91..966df09 100644 --- a/hash/test/hash_custom_test.cpp +++ b/hash/test/hash_custom_test.cpp @@ -84,8 +84,8 @@ void custom_tests() HASH_NAMESPACE::hash_combine(seed2, 250u); HASH_NAMESPACE::hash_combine(seed2, 350u); - BOOST_TEST(seed == - HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end())); + BOOST_TEST(seed == HASH_NAMESPACE::hash_range( + custom_vector.begin(), custom_vector.end())); BOOST_TEST(seed == seed2); } diff --git a/hash/test/hash_float_test.hpp b/hash/test/hash_float_test.hpp index ab3cbf2..2818bb2 100644 --- a/hash/test/hash_float_test.hpp +++ b/hash/test/hash_float_test.hpp @@ -22,10 +22,11 @@ #if defined(BOOST_MSVC) #pragma warning(push) -#pragma warning(disable:4127) // conditional expression is constant -#pragma warning(disable:4723) // conditional expression is constant +#pragma warning(disable:4127) // conditional expression is constant +#pragma warning(disable:4723) // conditional expression is constant #if BOOST_MSVC < 1400 -#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int', possible loss of data +#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int', + // possible loss of data #endif #endif @@ -36,23 +37,33 @@ char const* float_type(long double*) { return "long double"; } template void float_tests(char const* name, T* = 0) { - std::cerr<<"\n" - <<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"<\n" - <<"\n" - <<"boost::hash_detail::limits::digits = " - <::digits<<"\n" - <<"boost::hash_detail::limits::digits = " - <::digits<<"\n" - <<"boost::hash_detail::limits::digits = " - <::digits<<"\n" - <<"\n" - <<"boost::hash_detail::call_ldexp::float_type = " - <::float_type*)0)<<"\n" - <<"boost::hash_detail::call_frexp::float_type = " - <::float_type*)0)<<"\n" - <<"boost::hash_detail::select_hash_type::type = " - <::type*)0)<<"\n" - <<"\n" + std::cerr + << "\n" + << "Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<" + << name + << ">\n" + << "\n" + << "boost::hash_detail::limits::digits = " + << boost::hash_detail::limits::digits<< "\n" + << "boost::hash_detail::limits::digits = " + << boost::hash_detail::limits::digits<< "\n" + << "boost::hash_detail::limits::digits = " + << boost::hash_detail::limits::digits + << "\n" + << "\n" + << "boost::hash_detail::call_ldexp::float_type = " + << float_type(static_cast::float_type*>(0)) + << "\n" + << "boost::hash_detail::call_frexp::float_type = " + << float_type(static_cast::float_type*>(0)) + << "\n" + << "boost::hash_detail::select_hash_type::type = " + << float_type(static_cast::type*>(0)) + << "\n" + << "\n" ; HASH_NAMESPACE::hash x1; @@ -72,7 +83,9 @@ void float_tests(char const* name, T* = 0) // Doing anything with infinity causes borland to crash. #if defined(__BORLANDC__) - std::cerr<<"Not running infinity checks on Borland, as it causes it to crash.\n"; + std::cerr + << "Not running infinity checks on Borland, as it causes it to crash." + "\n"; #else if(boost::hash_detail::limits::has_infinity) { T infinity = -log(zero); @@ -111,19 +124,40 @@ void float_tests(char const* name, T* = 0) // This should really be 'has_denorm == denorm_present' but some // compilers don't have 'denorm_present'. See also a later use. if(boost::hash_detail::limits::has_denorm) { - if(x1(boost::hash_detail::limits::denorm_min()) == x1(infinity)) { - std::cerr<<"x1(denorm_min) == x1(infinity) == "<::denorm_min()) == x1(infinity)) + { + std::cerr + << "x1(denorm_min) == x1(infinity) == " + << x1(infinity) + << "\n"; } - if(x1(boost::hash_detail::limits::denorm_min()) == x1(minus_infinity)) { - std::cerr<<"x1(denorm_min) == x1(-infinity) == "<::denorm_min()) == + x1(minus_infinity)) + { + std::cerr + << "x1(denorm_min) == x1(-infinity) == " + << x1(minus_infinity) + << "\n"; } } + if(boost::hash_detail::limits::has_quiet_NaN) { - if(x1(boost::hash_detail::limits::quiet_NaN()) == x1(infinity)) { - std::cerr<<"x1(quiet_NaN) == x1(infinity) == "<::quiet_NaN()) == x1(infinity)) + { + std::cerr + << "x1(quiet_NaN) == x1(infinity) == " + << x1(infinity) + << "\n"; } - if(x1(boost::hash_detail::limits::quiet_NaN()) == x1(minus_infinity)) { - std::cerr<<"x1(quiet_NaN) == x1(-infinity) == "<::quiet_NaN()) == + x1(minus_infinity)) + { + std::cerr + << "x1(quiet_NaN) == x1(-infinity) == " + << x1(minus_infinity) + << "\n"; } } } @@ -146,10 +180,12 @@ void float_tests(char const* name, T* = 0) BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max)); BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max)); BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max)); - BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max)); + BOOST_TEST(x1(three_quarter_max) == + HASH_NAMESPACE::hash_value(three_quarter_max)); #endif - // The '!=' tests could legitimately fail, but with my hash it indicates a bug. + // The '!=' tests could legitimately fail, but with my hash it indicates a + // bug. BOOST_TEST(x1(max) == x1(max)); BOOST_TEST(x1(max) != x1(quarter_max)); BOOST_TEST(x1(max) != x1(half_max)); @@ -179,7 +215,8 @@ void float_tests(char const* name, T* = 0) #if defined(TEST_EXTENSIONS) BOOST_TEST(x1(boost::hash_detail::limits::epsilon()) == - HASH_NAMESPACE::hash_value(boost::hash_detail::limits::epsilon())); + HASH_NAMESPACE::hash_value( + boost::hash_detail::limits::epsilon())); #endif BOOST_TEST(boost::hash_detail::limits::epsilon() != (T) 0); @@ -216,14 +253,19 @@ void float_tests(char const* name, T* = 0) // specialization of boost::hash_detail::limits::denorm_min() for long // doubles which causes this test to fail. if(x1(boost::hash_detail::limits::denorm_min()) != - HASH_NAMESPACE::hash_value(boost::hash_detail::limits::denorm_min())) + HASH_NAMESPACE::hash_value( + boost::hash_detail::limits::denorm_min())) { - std::cerr<<"x1(boost::hash_detail::limits::denorm_min()) = " - << x1(boost::hash_detail::limits::denorm_min()) - << "\nhash_value(boost::hash_detail::limits::denorm_min()) = " - << HASH_NAMESPACE::hash_value( + std::cerr + << "x1(boost::hash_detail::limits::denorm_min()) = " + << x1(boost::hash_detail::limits::denorm_min()) + << "\nhash_value(boost::hash_detail::limits::denorm_min())" + " = " + << HASH_NAMESPACE::hash_value( boost::hash_detail::limits::denorm_min()) - << "\nx1(0) = "<::quiet_NaN()) == - HASH_NAMESPACE::hash_value(boost::hash_detail::limits::quiet_NaN())); + HASH_NAMESPACE::hash_value( + boost::hash_detail::limits::quiet_NaN())); } #endif } diff --git a/hash/test/hash_friend_test.cpp b/hash/test/hash_friend_test.cpp index 8a493e2..9d84570 100644 --- a/hash/test/hash_friend_test.cpp +++ b/hash/test/hash_friend_test.cpp @@ -87,8 +87,8 @@ void custom_tests() HASH_NAMESPACE::hash_combine(seed2, 250u); HASH_NAMESPACE::hash_combine(seed2, 350u); - BOOST_TEST(seed == - HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end())); + BOOST_TEST(seed == HASH_NAMESPACE::hash_range( + custom_vector.begin(), custom_vector.end())); BOOST_TEST(seed == seed2); } diff --git a/hash/test/hash_fwd_test.hpp b/hash/test/hash_fwd_test.hpp index 2438abf..09ef3b3 100644 --- a/hash/test/hash_fwd_test.hpp +++ b/hash/test/hash_fwd_test.hpp @@ -60,7 +60,8 @@ namespace test { template std::size_t hash_value(test_type3 const& x) { - std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end()); + std::size_t seed = + HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end()); HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end()); return seed; } @@ -91,7 +92,8 @@ namespace boost template std::size_t hash_value(test::test_type3 const& x) { - std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end()); + std::size_t seed = + HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end()); HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end()); return seed; } diff --git a/hash/test/hash_fwd_test_1.cpp b/hash/test/hash_fwd_test_1.cpp index 6c7f8d3..1f27f65 100644 --- a/hash/test/hash_fwd_test_1.cpp +++ b/hash/test/hash_fwd_test_1.cpp @@ -68,10 +68,12 @@ void fwd_test3() test::test_type3 x(values1.begin(), values1.end()); test::test_type3 y(values2.begin(), values2.end()); - std::size_t seed1 = HASH_NAMESPACE::hash_range(values1.begin(), values1.end()); + std::size_t seed1 = + HASH_NAMESPACE::hash_range(values1.begin(), values1.end()); HASH_NAMESPACE::hash_range(seed1, values1.begin(), values1.end()); - std::size_t seed2 = HASH_NAMESPACE::hash_range(values2.begin(), values2.end()); + std::size_t seed2 = + HASH_NAMESPACE::hash_range(values2.begin(), values2.end()); HASH_NAMESPACE::hash_range(seed2, values2.begin(), values2.end()); HASH_NAMESPACE::hash > hasher_test_int; @@ -92,4 +94,3 @@ int main() #endif return boost::report_errors(); } - diff --git a/hash/test/hash_global_namespace_test.cpp b/hash/test/hash_global_namespace_test.cpp index ccb99e7..d1d504d 100644 --- a/hash/test/hash_global_namespace_test.cpp +++ b/hash/test/hash_global_namespace_test.cpp @@ -85,8 +85,8 @@ void custom_tests() HASH_NAMESPACE::hash_combine(seed2, 250u); HASH_NAMESPACE::hash_combine(seed2, 350u); - BOOST_TEST(seed == - HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end())); + BOOST_TEST(seed == HASH_NAMESPACE::hash_range( + custom_vector.begin(), custom_vector.end())); BOOST_TEST(seed == seed2); } diff --git a/hash/test/hash_number_test.cpp b/hash/test/hash_number_test.cpp index 40febc7..b1a52b3 100644 --- a/hash/test/hash_number_test.cpp +++ b/hash/test/hash_number_test.cpp @@ -55,8 +55,11 @@ void numeric_test(T*) if (limits::is_integer) { - if(limits::is_signed || limits::digits <= boost::hash_detail::limits::digits) + if(limits::is_signed || + limits::digits <= boost::hash_detail::limits::digits) + { BOOST_TEST(HASH_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5)); + } BOOST_TEST(HASH_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u)); BOOST_TEST(HASH_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u)); BOOST_TEST(HASH_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u)); diff --git a/hash/test/hash_range_test.cpp b/hash/test/hash_range_test.cpp index 7d71f45..8743e1e 100644 --- a/hash/test/hash_range_test.cpp +++ b/hash/test/hash_range_test.cpp @@ -70,10 +70,12 @@ void hash_range_tests() BOOST_TEST(HASH_NAMESPACE::hash_range(values3.begin(), values3.end()) == HASH_NAMESPACE::hash_range(x.begin(), x.end())); - std::size_t seed = HASH_NAMESPACE::hash_range(values3.begin(), values3.end()); + std::size_t seed = + HASH_NAMESPACE::hash_range(values3.begin(), values3.end()); HASH_NAMESPACE::hash_range(seed, values4.begin(), values4.end()); HASH_NAMESPACE::hash_range(seed, x.begin(), x.end()); - BOOST_TEST(seed == HASH_NAMESPACE::hash_range(values5.begin(), values5.end())); + BOOST_TEST(seed == + HASH_NAMESPACE::hash_range(values5.begin(), values5.end())); } int main() diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 697cb41..1f33b9e 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -20,7 +20,8 @@ #include #endif -#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +#if BOOST_WORKAROUND(__GNUC__, < 3) \ + && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) #define BOOST_HASH_CHAR_TRAITS string_char_traits #else #define BOOST_HASH_CHAR_TRAITS char_traits @@ -67,7 +68,8 @@ namespace boost std::size_t hash_value(long double v); template - std::size_t hash_value(std::basic_string, A> const&); + std::size_t hash_value( + std::basic_string, A> const&); // Implementation @@ -200,9 +202,10 @@ namespace boost #if defined(BOOST_MSVC) #pragma warning(push) #if BOOST_MSVC <= 1400 -#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to 'unsigned int', - // possible loss of data - // A misguided attempt to detect 64-bit incompatability. +#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to + // 'unsigned int', possible loss of data + // A misguided attempt to detect 64-bit + // incompatability. #endif #endif @@ -285,7 +288,8 @@ namespace boost #endif template - inline std::size_t hash_value(std::basic_string, A> const& v) + inline std::size_t hash_value( + std::basic_string, A> const& v) { return hash_range(v.begin(), v.end()); } @@ -310,8 +314,8 @@ namespace boost // // Define the specializations required by the standard. The general purpose - // boost::hash is defined later in extensions.hpp if BOOST_HASH_NO_EXTENSIONS - // is not defined. + // boost::hash is defined later in extensions.hpp if + // BOOST_HASH_NO_EXTENSIONS is not defined. // BOOST_HASH_SPECIALIZE - define a specialization for a type which is // passed by copy. From 9d114a5021b5dafb55daf3ed913ef7429702f612 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 6 Jan 2010 08:43:47 +0000 Subject: [PATCH 69/82] Explicitly cast values to avoid warning on Visual C++ 10 [SVN r58745] --- hash/test/hash_map_test.hpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/hash/test/hash_map_test.hpp b/hash/test/hash_map_test.hpp index 6e85dcf..bd0255f 100644 --- a/hash/test/hash_map_test.hpp +++ b/hash/test/hash_map_test.hpp @@ -22,19 +22,21 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests) { const int number_of_containers = 10; T containers[number_of_containers]; - typedef typename T::value_type pair; + typedef BOOST_DEDUCED_TYPENAME T::value_type pair; + typedef BOOST_DEDUCED_TYPENAME T::key_type key; + typedef BOOST_DEDUCED_TYPENAME T::mapped_type value; for(int i = 0; i < 5; ++i) { for(int j = 0; j < i; ++j) - containers[i].insert(pair(0, 0)); + containers[i].insert(pair(key(0), value(0))); } - containers[6].insert(pair(1,0)); - containers[7].insert(pair(1,0)); - containers[7].insert(pair(1,0)); - containers[8].insert(pair(-1,1)); - containers[9].insert(pair(-1,3)); - containers[9].insert(pair(-1,3)); + containers[6].insert(pair(key(1),value(0))); + containers[7].insert(pair(key(1),value(0))); + containers[7].insert(pair(key(1),value(0))); + containers[8].insert(pair(key(-1),value(1))); + containers[9].insert(pair(key(-1),value(3))); + containers[9].insert(pair(key(-1),value(3))); HASH_NAMESPACE::hash hasher; From 1274aafb87ed584919cfe2b2d32b4a07e256ea34 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Fri, 8 Jan 2010 06:43:57 +0000 Subject: [PATCH 70/82] Update changelogs and slightly improved reference documentation for new release. [SVN r58805] --- hash/doc/changes.qbk | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hash/doc/changes.qbk b/hash/doc/changes.qbk index 5ee9150..9d7e26b 100644 --- a/hash/doc/changes.qbk +++ b/hash/doc/changes.qbk @@ -90,4 +90,10 @@ instead of trying to configure every possibility manually. * Workaround for when STLport doesn't support long double. +[h2 Boost 1.42.0] + +* Reduce the number of warnings for Visual C++ warning level 4. +* Some code formatting changes to fit lines into 80 characters. +* Rename an internal namespace. + [endsect] From 6f2d424287f8d8c45fc929eda7f55f01a5fb324c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 12 Jan 2010 18:51:59 +0000 Subject: [PATCH 71/82] Turn warnings as errors back on. [SVN r58949] --- hash/test/Jamfile.v2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index 21594ee..9c428b0 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -13,8 +13,8 @@ project hash-tests gcc:"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter" darwin:"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter" msvc:on - #gcc:on - #darwin:on + gcc:on + darwin:on ; test-suite functional/hash From 828a9c862c38286cf1eb659a30757acd23b3a307 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 12 Jan 2010 18:52:43 +0000 Subject: [PATCH 72/82] Fix link to example file. Fixes #3836. Thanks for reporting this. [SVN r58951] --- hash/doc/tutorial.qbk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hash/doc/tutorial.qbk b/hash/doc/tutorial.qbk index b2f79f5..81c1b15 100644 --- a/hash/doc/tutorial.qbk +++ b/hash/doc/tutorial.qbk @@ -110,7 +110,7 @@ And you can now use [classref boost::hash] with book: assert(books.find(dandelion) == books.end()); The full example can be found in: -[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.hpp] +[@boost:/libs/functional/hash/examples/books.hpp /libs/functional/hash/examples/books.hpp] and [@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp]. From d6e254a03bc9fc68660405f689c35d86766749c3 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 27 Jan 2010 19:32:39 +0000 Subject: [PATCH 73/82] Don't foward declare containers when using gcc's parallel library and add a macro to disable forward declaration. Fixes #3866. [SVN r59282] --- hash/test/Jamfile.v2 | 1 + hash/test/container_no_fwd_test.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 hash/test/container_no_fwd_test.cpp diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index 9c428b0..13a29a9 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -47,6 +47,7 @@ test-suite functional/hash : gcc:_GLIBCXX_DEBUG darwin:_GLIBCXX_DEBUG : container_fwd_gcc_debug ] + [ run container_no_fwd_test.cpp ] [ compile-fail hash_no_ext_fail_test.cpp ] [ compile-fail namespace_fail_test.cpp ] [ run hash_no_ext_macro_1.cpp ] diff --git a/hash/test/container_no_fwd_test.cpp b/hash/test/container_no_fwd_test.cpp new file mode 100644 index 0000000..cc6f6fa --- /dev/null +++ b/hash/test/container_no_fwd_test.cpp @@ -0,0 +1,14 @@ + +// Copyright 2010 Daniel James. +// 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) + +#define BOOST_DETAIL_NO_CONTAINER_FWD + +#include + +int main() +{ + std::set x; + std::vector y; +} \ No newline at end of file From 19197eabe1b7270addb688f05f833b73395c165c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 30 Jan 2010 09:30:04 +0000 Subject: [PATCH 74/82] Missing newline. [SVN r59365] --- hash/test/container_no_fwd_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hash/test/container_no_fwd_test.cpp b/hash/test/container_no_fwd_test.cpp index cc6f6fa..9da09da 100644 --- a/hash/test/container_no_fwd_test.cpp +++ b/hash/test/container_no_fwd_test.cpp @@ -11,4 +11,4 @@ int main() { std::set x; std::vector y; -} \ No newline at end of file +} From cfc0494e33861aa786ed4e5de15d6f4e41a82eb1 Mon Sep 17 00:00:00 2001 From: Tobias Schwinger Date: Sat, 6 Feb 2010 14:20:05 +0000 Subject: [PATCH 75/82] checks for write permission on working copy :-) [SVN r59524] --- include/boost/functional/forward_adapter.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/functional/forward_adapter.hpp b/include/boost/functional/forward_adapter.hpp index 0a4bc36..c6e61a9 100644 --- a/include/boost/functional/forward_adapter.hpp +++ b/include/boost/functional/forward_adapter.hpp @@ -3,7 +3,7 @@ Use modification and distribution are subject to 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). + http://www.boost.org/LICENSE_1_0.txt). ==============================================================================*/ #ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED From 09dee31f61b6a0b205490493bd9b0dd9c09408d9 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 15 Feb 2010 23:01:06 +0000 Subject: [PATCH 76/82] Stop using the deprecated BOOST_HAS_ macros in unordered and hash. [SVN r59697] --- include/boost/functional/hash/hash.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 1f33b9e..e85ca5a 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -44,7 +44,7 @@ namespace boost std::size_t hash_value(wchar_t); #endif -#if defined(BOOST_HAS_LONG_LONG) +#if !defined(BOOST_NO_LONG_LONG) std::size_t hash_value(boost::long_long_type); std::size_t hash_value(boost::ulong_long_type); #endif @@ -174,7 +174,7 @@ namespace boost } #endif -#if defined(BOOST_HAS_LONG_LONG) +#if !defined(BOOST_NO_LONG_LONG) inline std::size_t hash_value(boost::long_long_type v) { return hash_detail::hash_value_signed(v); @@ -408,7 +408,7 @@ namespace boost BOOST_HASH_SPECIALIZE_REF(std::wstring) #endif -#if defined(BOOST_HAS_LONG_LONG) +#if !defined(BOOST_NO_LONG_LONG) BOOST_HASH_SPECIALIZE(boost::long_long_type) BOOST_HASH_SPECIALIZE(boost::ulong_long_type) #endif From a98423d2c8eba3c81b5da2e48bb8df31ba11dc26 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 16 Feb 2010 22:32:49 +0000 Subject: [PATCH 77/82] Take advantage of the simplified parameters. [SVN r59707] --- hash/doc/Jamfile.v2 | 3 --- 1 file changed, 3 deletions(-) diff --git a/hash/doc/Jamfile.v2 b/hash/doc/Jamfile.v2 index acdf5ec..c21c881 100644 --- a/hash/doc/Jamfile.v2 +++ b/hash/doc/Jamfile.v2 @@ -5,10 +5,7 @@ xml hash : hash.qbk ; boostbook standalone : hash : - html.stylesheet=../../../../../doc/html/boostbook.css boost.root=../../../../.. - boost.libraries=../../../../libraries.htm - navig.graphics=1 chunk.first.sections=1 chunk.section.depth=2 From 9ad43cf51ffbe624bf47b7177a4da32e5c8495ee Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 16 Feb 2010 22:33:10 +0000 Subject: [PATCH 78/82] Remove deprecated macros for hash and unordered's tests. [SVN r59708] --- hash/test/hash_number_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hash/test/hash_number_test.cpp b/hash/test/hash_number_test.cpp index b1a52b3..91b9b92 100644 --- a/hash/test/hash_number_test.cpp +++ b/hash/test/hash_number_test.cpp @@ -152,7 +152,7 @@ int main() NUMERIC_TEST(long, hash_long) NUMERIC_TEST(unsigned long, ulong) -#if defined(BOOST_HAS_LONG_LONG) +#if !defined(BOOST_NO_LONG_LONG) NUMERIC_TEST_NO_LIMITS(boost::long_long_type, long_long) NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long) #endif From be0a60760c29bc2ff84b5071812bd22e91338d98 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 24 Feb 2010 00:14:19 +0000 Subject: [PATCH 79/82] Quick hack to deal with title tags in doxygen descriptions. [SVN r59859] --- forward/test/forward_adapter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/forward/test/forward_adapter.cpp b/forward/test/forward_adapter.cpp index 6956d4e..2317ce7 100644 --- a/forward/test/forward_adapter.cpp +++ b/forward/test/forward_adapter.cpp @@ -92,6 +92,7 @@ int main() BOOST_TEST(( is_same< result_of< f const (int&, int&) >::type, char >::value )); } + { using boost::noncopyable; using boost::forward_adapter; From a7d58c92b39cd995ce120ad844b72c1024385665 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Wed, 24 Mar 2010 08:49:00 +0000 Subject: [PATCH 80/82] Remove optimization which causes 0.5 to hash to 0. Refs #4038. I have an internal requirement the 0 hashes to 0, a better solution might be to remove that, put the optimization back and hash 0 to another value. Or alternatively, use the main combine function instead. [SVN r60805] --- hash/test/hash_float_test.hpp | 17 +++++++++++++++++ .../hash/detail/hash_float_generic.hpp | 8 +++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/hash/test/hash_float_test.hpp b/hash/test/hash_float_test.hpp index 2818bb2..dd1358e 100644 --- a/hash/test/hash_float_test.hpp +++ b/hash/test/hash_float_test.hpp @@ -79,6 +79,11 @@ void float_tests(char const* name, T* = 0) BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero)); #endif + BOOST_TEST(x1(zero) != x1(0.5)); + BOOST_TEST(x1(minus_zero) != x1(0.5)); + BOOST_TEST(x1(0.5) != x1(-0.5)); + BOOST_TEST(x1(1) != x1(-1)); + using namespace std; // Doing anything with infinity causes borland to crash. @@ -176,6 +181,12 @@ void float_tests(char const* name, T* = 0) BOOST_TEST(half_max != three_quarter_max); BOOST_TEST(quarter_max != three_quarter_max); + BOOST_TEST(max != -max); + BOOST_TEST(half_max != -half_max); + BOOST_TEST(quarter_max != -quarter_max); + BOOST_TEST(three_quarter_max != -three_quarter_max); + + #if defined(TEST_EXTENSIONS) BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max)); BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max)); @@ -197,6 +208,12 @@ void float_tests(char const* name, T* = 0) BOOST_TEST(x1(half_max) != x1(three_quarter_max)); BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max)); + BOOST_TEST(x1(max) != x1(-max)); + BOOST_TEST(x1(half_max) != x1(-half_max)); + BOOST_TEST(x1(quarter_max) != x1(-quarter_max)); + BOOST_TEST(x1(three_quarter_max) != x1(-three_quarter_max)); + + // Intel with gcc stdlib sometimes segfaults on calls to asin and acos. #if !((defined(__INTEL_COMPILER) || defined(__ICL) || \ defined(__ICC) || defined(__ECC)) && \ diff --git a/include/boost/functional/hash/detail/hash_float_generic.hpp b/include/boost/functional/hash/detail/hash_float_generic.hpp index f9acee9..fdbf53f 100644 --- a/include/boost/functional/hash/detail/hash_float_generic.hpp +++ b/include/boost/functional/hash/detail/hash_float_generic.hpp @@ -51,17 +51,15 @@ namespace boost limits::min_exponent; } - // The result of frexp is always between 0.5 and 1, so its - // top bit will always be 1. Subtract by 0.5 to remove that. - v -= T(0.5); - v = ldexp(v, limits::digits + 1); + v = ldexp(v, limits::digits); std::size_t seed = static_cast(v); v -= seed; // ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1; std::size_t const length = (limits::digits * - boost::static_log2::radix>::value - 1) + boost::static_log2::radix>::value + + limits::digits - 1) / limits::digits; for(std::size_t i = 0; i != length; ++i) From fc35014a87c52d50d279c748dafb6c05d36395fb Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 6 Apr 2010 20:14:12 +0000 Subject: [PATCH 81/82] Give up on warnings-as-errors for gcc for now. [SVN r61113] --- hash/test/Jamfile.v2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index 13a29a9..4435dd2 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -13,8 +13,8 @@ project hash-tests gcc:"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter" darwin:"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter" msvc:on - gcc:on - darwin:on + #gcc:on + #darwin:on ; test-suite functional/hash From 2f112825b909d124c119a80bfaeaf43776964c4b Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sun, 18 Apr 2010 13:20:45 +0000 Subject: [PATCH 82/82] Unordered/hash release notes. [SVN r61356] --- hash/doc/changes.qbk | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hash/doc/changes.qbk b/hash/doc/changes.qbk index 9d7e26b..4e0d0a9 100644 --- a/hash/doc/changes.qbk +++ b/hash/doc/changes.qbk @@ -96,4 +96,14 @@ * Some code formatting changes to fit lines into 80 characters. * Rename an internal namespace. +[h2 Boost 1.43.0] + +* [@https://svn.boost.org/trac/boost/ticket/3866 Ticket 3866]: + Don't foward declare containers when using gcc's parallel library, + allow user to stop forward declaration by defining the + `BOOST_DETAIL_NO_CONTAINER_FWD` macro. +* [@https://svn.boost.org/trac/boost/ticket/4038 Ticket 4038]: + Avoid hashing 0.5 and 0 to the same number. +* Stop using deprecated `BOOST_HAS_*` macros. + [endsect]