Avoid 'reference to reference' error in C++03.

Some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
  'reference-to-reference' in the template and typedef which described
  in CWG DR106 [1].

  In such situations, iterator_facade rejects reference type as a value
  type and some special iterators will become ill-formed:
  the test libs/range/test/join.hpp might be descriptive.

  [1] http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106

Signed-off-by: Kohei Takahashi <flast@flast.jp>
This commit is contained in:
Kohei Takahashi
2014-09-18 16:37:28 +09:00
parent adee905c51
commit 3d3560c12d
4 changed files with 77 additions and 5 deletions

View File

@ -9,6 +9,7 @@
#include <boost/detail/workaround.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/iterator/detail/any_conversion_eater.hpp>
// should be the last #includes
@ -52,7 +53,7 @@ namespace detail
// convertible to Value const&
struct conversion_eater
{
conversion_eater(Value&);
conversion_eater(typename add_lvalue_reference<Value>::type);
};
static char tester(conversion_eater, int);

View File

@ -6,6 +6,7 @@
#include <boost/mpl/bool.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/type_traits/detail/bool_trait_def.hpp>
#include <boost/iterator/detail/any_conversion_eater.hpp>
@ -26,7 +27,7 @@ namespace detail
template <class Value>
struct is_readable_iterator_impl
{
static char tester(Value&, int);
static char tester(typename add_lvalue_reference<Value>::type, int);
static char (& tester(any_conversion_eater, ...) )[2];
template <class It>

View File

@ -22,6 +22,7 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_convertible.hpp>
@ -284,7 +285,15 @@ namespace iterators {
: mpl::eval_if<
mpl::and_<
// A proxy is only needed for readable iterators
is_convertible<Reference,Value const&>
is_convertible<
Reference
// Use add_lvalue_reference to form `reference to Value` due to
// some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
// 'reference-to-reference' in the template which described in CWG
// DR106.
// http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
, typename add_lvalue_reference<Value const>::type
>
// No multipass iterator can have values that disappear
// before positions can be re-visited