Header boost/utility.hpp Documentation

# Header boost/utility.hpp

The entire contents of the header `<boost/utility.hpp>` are in `namespace boost`.

## Contents

- Class templates supporting the base-from-member idiom
- Function templates checked_delete() and checked_array_delete() (moved to the Boost.Core library)
- Function templates next() and prior() (moved to the Boost.Iterator library)
- Class noncopyable (moved to the Boost.Core library)
- Function template addressof() (moved to the Boost.Core library)
- Class template result_of
- Macro BOOST_BINARY
- Other utilities not part of `utility.hpp`

##

## Class template result_of

The class template `result_of` helps determine the type of a call expression. For example, given an lvalue `f` of type `F` and lvalues `t1`, `t2`, ..., `tN` of types `T1`, `T2`, ..., `TN`, respectively, the type `result_of<F(T1, T2, ..., TN)>::type` defines the result type of the expression `f(t1, t2, ...,tN)`. This implementation permits the type `F` to be a function pointer, function reference, member function pointer, or class type. By default, N may be any value between 0 and 16. To change the upper limit, define the macro `BOOST_RESULT_OF_NUM_ARGS` to the maximum value for N. Class template `result_of` resides in the header `<boost/utility/result_of.hpp>`.

If your compiler's support for `decltype` is adequate, `result_of` automatically uses it to deduce the type of the call expression, in which case `result_of<F(T1, T2, ..., TN)>::type` names the type `decltype(boost::declval<F>()(boost::declval<T1>(), boost::declval<T2>(), ..., boost::declval<TN>()))`, as in the following example.

>     struct functor {
>         template<class T>
>         T operator()(T x)
>         {
>             return x;
>         }
>     };

>     typedef boost::result_of<
>         functor(int)
>     >::type type; // type is int

You can test whether `result_of` is using `decltype` by checking if the macro `BOOST_RESULT_OF_USE_DECLTYPE` is defined after including `result_of.hpp`. You can also force `result_of` to use `decltype` by defining `BOOST_RESULT_OF_USE_DECLTYPE` prior to including `result_of.hpp`.

If `decltype` is not used, then automatic result type deduction of function objects is not possible. Instead, `result_of` uses the following protocol to allow the programmer to specify a type. When `F` is a class type with a member type `result_type`, `result_of<F(T1, T2, ..., TN)>::type` is `F::result_type`. When `F` does not contain `result_type`, `result_of<F(T1, T2, ..., TN)>::type` is `F::result<F(T1, T2, ..., TN)>::type` when `N > 0` or `void` when `N = 0`. 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.

>     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

Since `decltype` is a new language feature recently standardized in C++11, if you are writing a function object to be used with `result_of`, for maximum portability, you might consider following the above protocol even if your compiler has proper `decltype` support. If you wish to continue to use the protocol on compilers that support `decltype`, there are two options: You can use `boost::tr1_result_of`, which is also defined in `<boost/utility/result_of.hpp>`. Alternatively, you can define the macro `BOOST_RESULT_OF_USE_TR1`, which causes `result_of` to use the protocol described above instead of `decltype`. If you choose to follow the protocol, take care to ensure that the `result_type` and `result<>` members accurately represent the return type of `operator()` given a call expression.

Additionally, `boost::result_of` provides a third mode of operation, which some users may find convenient. When `BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK` is defined, `boost::result_of` behaves as follows. If the function object has a member type `result_type` or member template `result<>`, then `boost::result_of` will use the TR1 protocol. Otherwise, `boost::result_of` will use `decltype`. Using TR1 with a `declytpe` fallback may workaround certain problems at the cost of portability. For example:

- Deficient compiler: If your code requires `boost::result_of` to work with incomplete return types but your compiler's `decltype` 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 N3276) and is not implemented by some compilers.
- Deficient legacy code: If your existing TR1 function object advertises a different type than the actual result type deduced by `decltype`, then using TR1 with a `decltype` 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 differences between `boost::result_of` and TR1.

This implementation of `result_of` requires class template partial specialization, the ability to parse function types properly, and support for SFINAE. If `result_of` is not supported by your compiler, including the header `boost/utility/result_of.hpp` will define the macro `BOOST_NO_RESULT_OF`.

For additional information about `result_of`, see the C++ Library Technical Report, N1836, or, for motivation and design rationale, the `result_of` proposal.

### Usage guidelines for boost::result_of

The following are general suggestions about when and how to use `boost::result_of`.

1. If you are targeting C++11 and are not concerned about portability to non-compliant compilers or previous versions of the standard, then use `std::result_of`. If `std::result_of` meets your needs, then there's no reason to stop using it.
2. If you are targeting C++11 but may port your code to legacy compilers at some time in the future, then use `boost::result_of` with `decltype`. When `decltype` is used `boost::result_of` and `std::result_of` are usually interchangeable. See the documentation on known differences between boost::result_of and C++11 result_of.
3. If compiler portability is required, use `boost::result_of` with the TR1 protocol.

Regardless of how you configure `boost::result_of`, 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. `boost::result_of` must be passed the appropriately cv-qualified types in order to deduce the corresponding return type. For example:

>     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 &

### Usage guidelines for the TR1 result_of protocol

On compliant C++11 compilers, `boost::result_of` can use `decltype` 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.

- When the return type does not depend on the argument types or the cv-qualification of the function object, simply define `result_type`. There is no need to use the `result` template unless the return type varies.
- 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:

  >     struct functor {
  >         typedef int result_type;
  >         result_type operator()(int);
  >     };

- Always specify the `result` specialization near the corresponding `operator()` overload. This can make it easier to keep the specializations in sync with the overloads. For example:

  >     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;
  >     };

- Use type transformations to simplify the `result` template specialization. For example, the following uses Boost.TypeTraits to specialize the `result` template for a single `operator()` that can be called on both a const and non-const function object with either an lvalue or rvalue argument.

  >     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;
  >     };

### Known differences between boost::result_of and TR1 result_of

When using `decltype`, `boost::result_of` ignores the TR1 protocol and instead deduces the return type of function objects directly via `decltype`. 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 `boost::result_of` is known to differ depending on whether `decltype` or the TR1 protocol is used.

- TR1 protocol misusage

  When using the TR1 protocol, `boost::result_of` 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 `decltype`, these subtle bugs may result in compilation errors. For example:

  >     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

  Note that the user can force `boost::result_of` to use the TR1 protocol even on platforms that support `decltype` by defining `BOOST_RESULT_OF_USE_TR1`.

- Nullary function objects

  When using the TR1 protocol, `boost::result_of` cannot always deduce the type of calls to nullary function objects, in which case the type defaults to void. When using `decltype`, `boost::result_of` always gives the actual type of the call expression. For example:

  >     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

  Note that there are some workarounds for the nullary function problem. So long as the return type does not vary, `result_type` can always be used to specify the return type regardless of arity. If the return type does vary, then the user can specialize `boost::result_of` itself for nullary calls.

- Non-class prvalues and cv-qualification

  When using the TR1 protocol, `boost::result_of` will report the cv-qualified type specified by `result_type` or the `result` template regardless of the actual cv-qualification of the call expression. When using `decltype`, `boost::result_of` will report the actual type of the call expression, which is not cv-qualified when the expression is a non-class prvalue. For example:

  >     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

### Known differences between boost::result_of and C++11 result_of

When using `decltype`, `boost::result_of` implements most of the C++11 result_of specification. One known exception is that `boost::result_of` does not implement the requirements regarding pointers to member data.

Created by Doug Gregor. Contributions from Daniel Walker, Eric Niebler, Michel Morin and others

## Macro BOOST_BINARY

The macro `BOOST_BINARY` 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 (2.13.1p1). 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.

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.

The BOOST_BINARY family of macros resides in the header <boost/utility/binary.hpp> which is automatically included by <boost/utility.hpp>.

Contributed by Matt Calabrese.

### Example

>     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
>     }

Revised 04 September, 2008

© Copyright Beman Dawes 1999-2003.

Distributed under the Boost Software License, Version 1.0. See www.boost.org/LICENSE_1_0.txt