diff --git a/include/iterator b/include/iterator index aed0525db..bda177e11 100644 --- a/include/iterator +++ b/include/iterator @@ -437,6 +437,23 @@ struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_t struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {}; +template +struct __has_iterator_typedefs +{ +private: + struct __two {char __lx; char __lxx;}; + template static __two __test(...); + template static char __test(typename std::__void_t::type* = 0, + typename std::__void_t::type* = 0, + typename std::__void_t::type* = 0, + typename std::__void_t::type* = 0, + typename std::__void_t::type* = 0 + ); +public: + static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1; +}; + + template struct __has_iterator_category { @@ -479,7 +496,7 @@ struct __iterator_traits<_Iter, true> template struct _LIBCPP_TEMPLATE_VIS iterator_traits - : __iterator_traits<_Iter, __has_iterator_category<_Iter>::value> {}; + : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> {}; template struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> diff --git a/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp b/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp new file mode 100644 index 000000000..021523481 --- /dev/null +++ b/test/std/iterators/iterator.primitives/iterator.traits/empty.fail.cpp @@ -0,0 +1,122 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// struct iterator_traits +// { +// }; + +#include +#include "test_macros.h" + +struct A {}; +struct NotAnIteratorEmpty {}; + +struct NotAnIteratorNoDifference +{ +// typedef int difference_type; + typedef A value_type; + typedef A* pointer; + typedef A& reference; + typedef std::forward_iterator_tag iterator_category; +}; + +struct NotAnIteratorNoValue +{ + typedef int difference_type; +// typedef A value_type; + typedef A* pointer; + typedef A& reference; + typedef std::forward_iterator_tag iterator_category; +}; + +struct NotAnIteratorNoPointer +{ + typedef int difference_type; + typedef A value_type; +// typedef A* pointer; + typedef A& reference; + typedef std::forward_iterator_tag iterator_category; +}; + +struct NotAnIteratorNoReference +{ + typedef int difference_type; + typedef A value_type; + typedef A* pointer; +// typedef A& reference; + typedef std::forward_iterator_tag iterator_category; +}; + +struct NotAnIteratorNoCategory +{ + typedef int difference_type; + typedef A value_type; + typedef A* pointer; + typedef A& reference; +// typedef std::forward_iterator_tag iterator_category; +}; + +int main() +{ + { + typedef std::iterator_traits T; + typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}} + } + + { + typedef std::iterator_traits T; + typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}} + } + + { + typedef std::iterator_traits T; + typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}} + } + + { + typedef std::iterator_traits T; + typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}} + } + + { + typedef std::iterator_traits T; + typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}} + } + + { + typedef std::iterator_traits T; + typedef T::difference_type DT; // expected-error-re {{no type named 'difference_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::value_type VT; // expected-error-re {{no type named 'value_type' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::pointer PT; // expected-error-re {{no type named 'pointer' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::reference RT; // expected-error-re {{no type named 'reference' in 'std::__1::iterator_traits<{{.+}}>}} + typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std::__1::iterator_traits<{{.+}}>}} + } +} diff --git a/test/std/iterators/iterator.primitives/iterator.traits/iterator.pass.cpp b/test/std/iterators/iterator.primitives/iterator.traits/iterator.pass.cpp index 38f7c0b6b..34f430ff3 100644 --- a/test/std/iterators/iterator.primitives/iterator.traits/iterator.pass.cpp +++ b/test/std/iterators/iterator.primitives/iterator.traits/iterator.pass.cpp @@ -39,5 +39,6 @@ int main() static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); + static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); }