123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583 |
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <title>Header boost/utility.hpp Documentation</title>
- </head>
- <body bgcolor="#FFFFFF" text="#000000">
- <h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" WIDTH="277" HEIGHT="86">Header
- <a href="../../boost/utility.hpp">boost/utility.hpp</a></h1>
- <p>The entire contents of the header <code><a href="../../boost/utility.hpp"><boost/utility.hpp></a></code>
- are in <code>namespace boost</code>.</p>
- <h2>Contents</h2>
- <ul>
- <li>
- Class templates supporting the <a href="doc/html/base_from_member.html">
- base-from-member idiom</a></li>
- <li>
- Function templates <a href="../core/doc/html/core/checked_delete.html">checked_delete() and
- checked_array_delete()</a> (moved to the Boost.Core library)</li>
- <li>
- Function templates <a href="../iterator/doc/html/iterator/algorithms/next_prior.html">next() and prior()</a> (moved to the Boost.Iterator library)</li>
- <li>
- Class <a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)</li>
- <li>
- Function template <a href="../core/doc/html/core/addressof.html">addressof()</a> (moved to the Boost.Core library)</li>
- <li>Class template <a href="#result_of">result_of</a></li>
- <li>
- Macro <a href="#BOOST_BINARY">BOOST_BINARY</a></li>
- <li><a href="index.html">Other utilities not part of <code>utility.hpp</code></a></li>
- </ul>
- <h2>
- <h2><a name="result_of">Class template
- result_of</a></h2> <p>The class template
- <code>result_of</code> helps determine the type of a
- call expression. For example, given an lvalue <code>f</code> of
- type <code>F</code> and lvalues <code>t1</code>,
- <code>t2</code>, ..., <code>t<em>N</em></code> of
- types <code>T1</code>, <code>T2</code>, ...,
- <code>T<em>N</em></code>, respectively, the type
- <code>result_of<F(T1, T2, ...,
- T<em>N</em>)>::type</code> defines the result type
- of the expression <code>f(t1, t2,
- ...,t<em>N</em>)</code>. This implementation permits
- the type <code>F</code> to be a function pointer,
- function reference, member function pointer, or class
- type. By default, <em>N</em> may be any value between 0 and
- 16. To change the upper limit, define the macro
- <code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
- value for <em>N</em>. Class template <code>result_of</code>
- resides in the header <code><<a
- href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.</p>
- <p>If your compiler's support for <code>decltype</code> is
- adequate, <code>result_of</code> automatically uses it to
- deduce the type of the call expression, in which case
- <code>result_of<F(T1, T2, ...,
- T<em>N</em>)>::type</code> names the type
- <code>decltype(boost::declval<F>()(boost::declval<T1>(),
- boost::declval<T2>(), ...,
- boost::declval<T<em>N</em>>()))</code>, as in the
- following example.</p>
- <blockquote>
- <pre>struct functor {
- template<class T>
- T operator()(T x)
- {
- return x;
- }
- };
- typedef boost::result_of<
- functor(int)
- >::type type; // type is int</pre>
- </blockquote>
- <p>You can test whether <code>result_of</code> is using
- <code>decltype</code> by checking if the macro
- <code>BOOST_RESULT_OF_USE_DECLTYPE</code> is defined after
- including <code>result_of.hpp</code>. You can also force
- <code>result_of</code> to use <code>decltype</code> by
- defining <code>BOOST_RESULT_OF_USE_DECLTYPE</code> prior
- to including <code>result_of.hpp</code>.</p>
- <p>If <code>decltype</code> is not used,
- then automatic result type deduction of function
- objects is not possible. Instead, <code>result_of</code>
- uses the following protocol to allow the programmer to
- specify a type. When <code>F</code> is a class type with a
- member type <code>result_type</code>,
- <code>result_of<F(T1, T2, ...,
- T<em>N</em>)>::type</code> is
- <code>F::result_type</code>. When <code>F</code> does
- not contain <code>result_type</code>,
- <code>result_of<F(T1, T2, ...,
- T<em>N</em>)>::type</code> is <code>F::result<F(T1,
- T2, ..., T<em>N</em>)>::type</code> when
- <code><em>N</em> > 0</code> or <code>void</code>
- when <code><em>N</em> = 0</code>. Note that it is the
- responsibility of the programmer to ensure that
- function objects accurately advertise their result
- type via this protocol, as in the following
- example.</p>
- <blockquote>
- <pre>struct functor {
- template<class> struct result;
- template<class F, class T>
- struct result<F(T)> {
- typedef T type;
- };
- template<class T>
- T operator()(T x)
- {
- return x;
- }
- };
- typedef boost::result_of<
- functor(int)
- >::type type; // type is int</pre>
- </blockquote>
- <p>Since <code>decltype</code> is a new language
- feature recently standardized in C++11,
- if you are writing a function object
- to be used with <code>result_of</code>, for
- maximum portability, you might consider following
- the above protocol even if your compiler has
- proper <code>decltype</code> support. If you wish to continue to
- use the protocol on compilers that
- support <code>decltype</code>, there are two options:
- You can use <code>boost::tr1_result_of</code>, which is also
- defined in <code><<a href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.
- Alternatively, you can define the macro
- <code>BOOST_RESULT_OF_USE_TR1</code>, which causes
- <code>result_of</code> to use the protocol described
- above instead of <code>decltype</code>. If you choose to
- follow the protocol, take care to ensure that the
- <code>result_type</code> and
- <code>result<></code> members accurately
- represent the return type of
- <code>operator()</code> given a call expression.</p>
- <p>Additionally, <code>boost::result_of</code>
- provides a third mode of operation, which some users
- may find convenient. When
- <code>BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK</code>
- is defined, <code>boost::result_of</code> behaves as
- follows. If the function object has a member
- type <code>result_type</code> or member
- template <code>result<></code>, then
- <code>boost::result_of</code> will use the TR1
- protocol. Otherwise,
- <code>boost::result_of</code> will
- use <code>decltype</code>. Using TR1 with
- a <code>declytpe</code> fallback may workaround
- certain problems at the cost of portability. For
- example:
- <ul>
- <li>Deficient compiler: If your code
- requires <code>boost::result_of</code> to work
- with incomplete return types but your
- compiler's <code>decltype</code> implementation
- does not support incomplete return types, then you
- can use the TR1 protocol as a workaround. Support
- for incomplete return types was added late in the
- C++11 standardization process
- (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf">N3276</a>)
- and is not implemented by some compilers.</li>
- <li>Deficient legacy code: If your existing TR1
- function object advertises a different type than
- the actual result type deduced
- by <code>decltype</code>, then using TR1 with a
- <code>decltype</code> fallback will allow you to
- work with both your existing TR1 function objects
- and new C++11 function object. This situation
- could occur if your legacy function objects
- misused the TR1 protocol. See the documentation on
- known <a href="#result_of_tr1_diff">differences</a>
- between <code>boost::result_of</code> and TR1.</li>
- </ul>
- <a name="BOOST_NO_RESULT_OF"></a>
- <p>This implementation of <code>result_of</code>
- requires class template partial specialization, the
- ability to parse function types properly, and support
- for SFINAE. If <code>result_of</code> is not supported
- by your compiler, including the header
- <code>boost/utility/result_of.hpp</code> will
- define the macro <code>BOOST_NO_RESULT_OF</code>.</p>
- <p>For additional information
- about <code>result_of</code>, see the C++ Library
- Technical Report,
- <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
- or, for motivation and design rationale,
- the <code>result_of</code> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
- <a name="result_of_guidelines">
- <h3>Usage guidelines for boost::result_of</h3>
- </a>
- <p>The following are general suggestions about when
- and how to use <code>boost::result_of</code>.</p>
- <ol>
- <li> If you are targeting C++11 and are not concerned
- about portability to non-compliant compilers or
- previous versions of the standard, then use
- <code>std::result_of</code>. If <code>std::result_of</code>
- meets your needs, then there's no reason to stop using
- it.</li>
- <li> If you are targeting C++11 but may port your code
- to legacy compilers at some time in the future, then
- use <code>boost::result_of</code> with
- <code>decltype</code>. When <code>decltype</code> is
- used <code>boost::result_of</code>
- and <code>std::result_of</code> are usually
- interchangeable. See the documentation on
- known <a href="#result_of_cxx11_diff">differences</a>
- between boost::result_of and C++11 result_of.</li>
- <li> If compiler portability is required,
- use <code>boost::result_of</code> with the TR1 protocol.</li>
- </ol>
- <p>Regardless of how you
- configure <code>boost::result_of</code>, it is
- important to bear in mind that the return type of a
- function may change depending on its arguments, and
- additionally, the return type of a member function may
- change depending on the cv-qualification of the
- object. <code>boost::result_of</code> must be passed
- the appropriately cv-qualified types in order to
- deduce the corresponding return type. For example:
- <blockquote>
- <pre>struct functor {
- int& operator()(int);
- int const& operator()(int) const;
- float& operator()(float&);
- float const& operator()(float const&);
- };
- typedef boost::result_of<
- functor(int)
- >::type type1; // type1 is int &
- typedef boost::result_of<
- const functor(int)
- >::type type2; // type2 is int const &
- typedef boost::result_of<
- functor(float&)
- >::type type3; // type3 is float &
- typedef boost::result_of<
- functor(float const&)
- >::type type4; // type4 is float const &</pre>
- </blockquote>
- <a name="result_of_tr1_protocol_guidelines">
- <h3>Usage guidelines for the TR1 result_of protocol</h3>
- </a>
- <p>On compliant C++11
- compilers, <code>boost::result_of</code> can
- use <code>decltype</code> to deduce the type of any
- call expression, including calls to function
- objects. However, on pre-C++11 compilers or on
- compilers without adequate decltype support,
- additional scaffolding is needed from function
- objects as described above. The following are
- suggestions about how to use the TR1 protocol.</p>
- <ul>
- <li>When the return type does not depend on the
- argument types or the cv-qualification of the
- function object, simply
- define <code>result_type</code>. There is no need
- to use the <code>result</code> template unless the
- return type varies.</li>
- <li>Use the protocol specified type when defining
- function prototypes. This can help ensure the
- actual return type does not get out of sync with
- the protocol specification. For example:
- <blockquote>
- <pre>struct functor {
- typedef int result_type;
- result_type operator()(int);
- };</pre>
- </blockquote> </li>
- <li>Always specify the <code>result</code>
- specialization near the corresponding
- <code>operator()</code> overload. This can make it
- easier to keep the specializations in sync with the
- overloads. For example:
- <blockquote>
- <pre>struct functor {
- template<class> struct result;
- template<class F>
- struct result<F(int)> {
- typedef int& type;
- };
- result<functor(int)>::type operator()(int);
- template<class F>
- struct result<const F(int)> {
- typedef int const& type;
- };
- result<const functor(int)>::type operator()(int) const;
- };</pre>
- </blockquote> </li>
- <li>Use type transformations to simplify
- the <code>result</code> template specialization. For
- example, the following uses
- <a href="../type_traits/doc/html/index.html">Boost.TypeTraits</a>
- to specialize the <code>result</code> template for
- a single <code>operator()</code> that can be called on
- both a const and non-const function object with
- either an lvalue or rvalue argument.
- <blockquote>
- <pre>struct functor {
- template<class> struct result;
- template<class F, class T>
- struct result<F(T)>
- : boost::remove_cv<
- typename boost::remove_reference<T>::type
- >
- {};
- template<class T>
- T operator()(T const& x) const;
- };</pre>
- </blockquote></li>
- </ul>
- <a name="result_of_tr1_diff">
- <h3>Known differences between boost::result_of and TR1 result_of</h3>
- </a>
- When using <code>decltype</code>, <code>boost::result_of</code>
- ignores the TR1 protocol and instead deduces the
- return type of function objects directly
- via <code>decltype</code>. In most situations, users
- will not notice a difference, so long as they use the
- protocol correctly. The following are situations in
- which the type deduced
- by <code>boost::result_of</code> is known to differ depending on
- whether <code>decltype</code> or the TR1 protocol is
- used.
- <ul>
- <li> TR1 protocol misusage
- <p>When using the TR1
- protocol, <code>boost::result_of</code> cannot
- detect whether the actual type of a call to a
- function object is the same as the type specified
- by the protocol, which allows for the possibility
- of inadvertent mismatches between the specified
- type and the actual type. When
- using <code>decltype</code>, these subtle bugs
- may result in compilation errors. For example:</p>
- <blockquote>
- <pre>struct functor {
- typedef short result_type;
- int operator()(short);
- };
- #ifdef BOOST_RESULT_OF_USE_DECLTYPE
- BOOST_STATIC_ASSERT((
- boost::is_same<boost::result_of<functor(short)>::type, int>::value
- ));
- #else
- BOOST_STATIC_ASSERT((
- boost::is_same<boost::result_of<functor(short)>::type, short>::value
- ));
- #endif</pre>
- </blockquote>
- <p>Note that the user can
- force <code>boost::result_of</code> to use the TR1
- protocol even on platforms that
- support <code>decltype</code> by
- defining <code>BOOST_RESULT_OF_USE_TR1</code>.</p></li>
- <li> Nullary function objects
- <p>When using the TR1 protocol, <code>boost::result_of</code>
- cannot always deduce the type of calls to
- nullary function objects, in which case the
- type defaults to void. When using <code>decltype</code>,
- <code>boost::result_of</code> always gives the actual type of the
- call expression. For example:</p>
- <blockquote>
- <pre>struct functor {
- template<class> struct result {
- typedef int type;
- };
- int operator()();
- };
- #ifdef BOOST_RESULT_OF_USE_DECLTYPE
- BOOST_STATIC_ASSERT((
- boost::is_same<boost::result_of<functor()>::type, int>::value
- ));
- #else
- BOOST_STATIC_ASSERT((
- boost::is_same<boost::result_of<functor()>::type, void>::value
- ));
- #endif</pre>
- </blockquote>
- <p>Note that there are some workarounds for the
- nullary function problem. So long as the return
- type does not vary,
- <code>result_type</code> can always be used to
- specify the return type regardless of arity. If the
- return type does vary, then the user can
- specialize <code>boost::result_of</code> itself for
- nullary calls.</p></li>
- <li> Non-class prvalues and cv-qualification
- <p>When using the TR1
- protocol, <code>boost::result_of</code> will
- report the cv-qualified type specified
- by <code>result_type</code> or
- the <code>result</code> template regardless of
- the actual cv-qualification of the call
- expression. When using
- <code>decltype</code>, <code>boost::result_of</code>
- will report the actual type of the call expression,
- which is not cv-qualified when the expression is a
- non-class prvalue. For example:</p>
- <blockquote>
- <pre>struct functor {
- template<class> struct result;
- template<class F, class T> struct result<F(const T)> {
- typedef const T type;
- };
- const short operator()(const short);
- int const & operator()(int const &);
- };
- // Non-prvalue call expressions work the same with or without decltype.
- BOOST_STATIC_ASSERT((
- boost::is_same<
- boost::result_of<functor(int const &)>::type,
- int const &
- ::value
- ));
- // Non-class prvalue call expressions are not actually cv-qualified,
- // but only the decltype-based result_of reports this accurately.
- #ifdef BOOST_RESULT_OF_USE_DECLTYPE
- BOOST_STATIC_ASSERT((
- boost::is_same<
- boost::result_of<functor(const short)>::type,
- short
- ::value
- ));
- #else
- BOOST_STATIC_ASSERT((
- boost::is_same<
- boost::result_of<functor(const short)>::type,
- const short
- ::value
- ));
- #endif</pre>
- </blockquote></li>
- </ul>
- <a name="result_of_cxx11_diff">
- <h3>Known differences between boost::result_of and C++11 result_of</h3>
- </a>
- <p>When using <code>decltype</code>, <code>boost::result_of</code>
- implements most of the C++11 result_of
- specification. One known exception is that
- <code>boost::result_of</code> does not implement the
- requirements regarding pointers to member data.</p>
- <p>Created by Doug Gregor. Contributions from Daniel Walker, Eric Niebler, Michel Morin and others</p>
- <h2><a name="BOOST_BINARY">Macro BOOST_BINARY</a></h2>
- <p>The macro <code>BOOST_BINARY</code> is used for the
- representation of binary literals. It takes as an argument
- a binary number arranged as an arbitrary amount of 1s and 0s in
- groupings of length 1 to 8, with groups separated
- by spaces. The type of the literal yielded is determined by
- the same rules as those of hex and octal
- literals (<i>2.13.1p1</i>). By implementation, this macro
- expands directly to an octal literal during preprocessing, so
- there is no overhead at runtime and the result is useable in
- any place that an octal literal would be.</p>
- <p>In order to directly support binary literals with suffixes,
- additional macros of the form BOOST_BINARY_XXX are also
- provided, where XXX is a standard integer suffix in all capital
- letters. In addition, LL and ULL suffixes may be used for representing
- long long and unsigned long long types in compilers which provide
- them as an extension.</p>
- <p>The BOOST_BINARY family of macros resides in the header
- <a
- href="../../boost/utility/binary.hpp"><boost/utility/binary.hpp></a>
- which is automatically included by
- <a
- href="../../boost/utility.hpp"><boost/utility.hpp></a>.
- <p>Contributed by Matt Calabrese.</p><p>
- </p><h3>Example</h3>
- <blockquote>
- <pre>
- void foo( int );
- void foo( unsigned long );
- void bar()
- {
- int value1 = BOOST_BINARY( 100 111000 01 1 110 );
- unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned long
- long long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported
- assert( BOOST_BINARY( 10010 )
- & BOOST_BINARY( 11000 )
- == BOOST_BINARY( 10000 )
- );
- foo( BOOST_BINARY( 1010 ) ); // calls the first foo
- foo( BOOST_BINARY_LU( 1010 ) ); // calls the second foo
- }
- </pre></blockquote>
- <hr>
- <p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
- -->04 September, 2008<!--webbot bot="Timestamp" endspan i-checksum="39369"
- -->
- </p>
- <p>© Copyright Beman Dawes 1999-2003.</p>
- <p>Distributed under the Boost Software License, Version 1.0. See
- <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
- </body>
- </html>
|