From 88f5ca0bfd4ef45df658ddda6011f41a6adf584f Mon Sep 17 00:00:00 2001 From: John Maddock Date: Fri, 17 Sep 2010 12:12:03 +0000 Subject: [PATCH] Add declval and common type from Vicente J. Botet Escriba. Regenerate docs. [SVN r65443] --- doc/declval.qbk | 104 ++++++++++++++++++++++++++++++ include/boost/utility/declval.hpp | 44 +++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 doc/declval.qbk create mode 100644 include/boost/utility/declval.hpp diff --git a/doc/declval.qbk b/doc/declval.qbk new file mode 100644 index 0000000..67e82d2 --- /dev/null +++ b/doc/declval.qbk @@ -0,0 +1,104 @@ +[/ + / Copyright (c) 2008 Howard Hinnant + / Copyright (c) 2008 Beman Dawes + / Copyright (c) 2009-20010 Vicente J. Botet Escriba + / + / 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) + /] + +[article Declval + [quickbook 1.5] + [authors [Hinnant, Howard]] + [authors [Dawes, Beman]] + [authors [Botet Escriba, Vicente J.]] + [copyright 2008 Howard Hinnant] + [copyright 2008 Beman Dawes] + [copyright 2009-2010 Vicente J. Botet Escriba] + [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]) + ] +] + +[/===============] +[section Overview] +[/===============] + +The motivation for `declval` was introduced in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value N2958: +Moving Swap Forward]. Here follows a rewording of this chapter. + +With the provision of decltype, late-specified return types, and default template-arguments for function templates a +new generation of SFINAE patterns will emerge to at least partially compensate the lack of concepts on the C++0x timescale. +Using this technique, it is sometimes necessary to obtain an object of a known type in a non-using context, e.g. given the declaration + + template + T&& declval(); // not used + +as part of the function template declaration + + template + decltype(static_cast(declval())) convert(From&&); + +or as part of a class template definition + + template class result_of; + + template + struct result_of + { + typedef decltype(declval()(declval()...)) type; + }; + +The role of the function template declval() is a transformation of a type T into a value without using or evaluating this function. +The name is supposed to direct the reader's attention to the fact that the expression `declval()` is an lvalue if and only if +T is an lvalue-reference, otherwise an rvalue. To extend the domain of this function we can do a bit better by changing its declaration to + + template + typename std::add_rvalue_reference::type declval(); // not used + +which ensures that we can also use cv void as template parameter. The careful reader might have noticed that `declval()` +already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C==0x standard. + +The provision of a new library component that allows the production of values in unevaluated expressions is considered as +important to realize constrained templates in C++0x where concepts are not available. +This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer. + +[endsect] + + +[/=================] +[section:reference Reference ] +[/=================] + +`#include ` + + namespace boost { + + template + typename add_rvalue_reference::type declval(); //noexcept; // as unevaluated operand + + } // namespace boost + + +The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands. + + template + typename add_rvalue_reference::type declval(); + +[*Remarks:] If this function is used, the program is ill-formed. + +[*Remarks:] The template parameter T of declval may be an incomplete type. + +[*Example:] + + template + decltype(static_cast(declval())) convert(From&&); + +Declares a function template convert which only participats in overloading if the type From can be explicitly converted to type To. + +[endsect] + + + diff --git a/include/boost/utility/declval.hpp b/include/boost/utility/declval.hpp new file mode 100644 index 0000000..41ec3dc --- /dev/null +++ b/include/boost/utility/declval.hpp @@ -0,0 +1,44 @@ +// common_type.hpp ---------------------------------------------------------// + +// Copyright 2010 Vicente J. Botet Escriba + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP +#define BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP + +#include + +//----------------------------------------------------------------------------// + +#include + +//----------------------------------------------------------------------------// +// // +// C++03 implementation of // +// Written by Vicente J. Botet Escriba // +//~ 20.3.4 Function template declval [declval] +//~ 1 The library provides the function template declval to simplify the definition of expressions which occur as +//~ unevaluated operands. +//~ 2 Remarks: If this function is used, the program is ill-formed. +//~ 3 Remarks: The template parameter T of declval may be an incomplete type. +//~ [ Example: + +//~ template +//~ decltype(static_cast(declval())) convert(From&&); + +//~ declares a function template convert which only participats in overloading if the type From can be +//~ explicitly converted to type To. For another example see class template common_type (20.7.6.6). —end +//~ example ] +// // +//----------------------------------------------------------------------------// + +namespace boost { + + template + typename add_rvalue_reference::type declval(); //noexcept; // as unevaluated operand + +} // namespace boost + +#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP