//===----------------------------------------------------------------------===// // // 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. // //===----------------------------------------------------------------------===// // // // __libcpp_is_trivial_iterator // __libcpp_is_trivial_iterator determines if an iterator is a "trivial" one, // that can be used w/o worrying about its operations throwing exceptions. // Pointers are trivial iterators. Libc++ has three "iterator wrappers": // reverse_iterator, move_iterator, and __wrap_iter. If the underlying iterator // is trivial, then those are as well. // #include #include #include #include #include #include "test_macros.h" #include "test_iterators.h" #if TEST_STD_VER >= 11 #define DELETE_FUNCTION = delete #else #define DELETE_FUNCTION #endif class T; // incomplete class my_input_iterator_tag : public std::input_iterator_tag {}; template class my_input_iterator { It it_; template friend class my_input_iterator; public: typedef my_input_iterator_tag iterator_category; typedef typename std::iterator_traits::value_type value_type; typedef typename std::iterator_traits::difference_type difference_type; typedef It pointer; typedef typename std::iterator_traits::reference reference; It base() const {return it_;} my_input_iterator() : it_() {} explicit my_input_iterator(It it) : it_(it) {} template my_input_iterator(const my_input_iterator& u) :it_(u.it_) {} reference operator*() const {return *it_;} pointer operator->() const {return it_;} my_input_iterator& operator++() {++it_; return *this;} my_input_iterator operator++(int) {my_input_iterator tmp(*this); ++(*this); return tmp;} friend bool operator==(const my_input_iterator& x, const my_input_iterator& y) {return x.it_ == y.it_;} friend bool operator!=(const my_input_iterator& x, const my_input_iterator& y) {return !(x == y);} template void operator,(T const &) DELETE_FUNCTION; }; template inline bool operator==(const my_input_iterator& x, const my_input_iterator& y) { return x.base() == y.base(); } template inline bool operator!=(const my_input_iterator& x, const my_input_iterator& y) { return !(x == y); } int main() { // basic tests static_assert(( std::__libcpp_is_trivial_iterator::value), ""); static_assert(( std::__libcpp_is_trivial_iterator::value), ""); static_assert(( std::__libcpp_is_trivial_iterator::value), ""); static_assert(( std::__libcpp_is_trivial_iterator::value), ""); static_assert(( std::__libcpp_is_trivial_iterator > ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator >::value), ""); static_assert(( std::__libcpp_is_trivial_iterator > ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator > ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator > ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator >::value), ""); static_assert(( std::__libcpp_is_trivial_iterator > ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator > ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator > ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator >::value), ""); static_assert(( std::__libcpp_is_trivial_iterator > ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator > ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator > > ::value), ""); // iterators in the libc++ test suite static_assert((!std::__libcpp_is_trivial_iterator >::value), ""); static_assert((!std::__libcpp_is_trivial_iterator >::value), ""); static_assert((!std::__libcpp_is_trivial_iterator >::value), ""); static_assert((!std::__libcpp_is_trivial_iterator >::value), ""); static_assert((!std::__libcpp_is_trivial_iterator >::value), ""); static_assert((!std::__libcpp_is_trivial_iterator >::value), ""); static_assert((!std::__libcpp_is_trivial_iterator >::value), ""); // Iterator classification static_assert(( std::__is_input_iterator ::value), "" ); static_assert(( std::__is_forward_iterator ::value), "" ); static_assert(( std::__is_bidirectional_iterator::value), "" ); static_assert(( std::__is_random_access_iterator::value), "" ); static_assert((!std::__is_exactly_input_iterator::value), "" ); static_assert(( std::__is_input_iterator >::value), "" ); static_assert((!std::__is_forward_iterator >::value), "" ); static_assert((!std::__is_bidirectional_iterator >::value), "" ); static_assert((!std::__is_random_access_iterator >::value), "" ); static_assert(( std::__is_exactly_input_iterator >::value), "" ); static_assert(( std::__is_input_iterator >::value), "" ); static_assert(( std::__is_forward_iterator >::value), "" ); static_assert((!std::__is_bidirectional_iterator >::value), "" ); static_assert((!std::__is_random_access_iterator >::value), "" ); static_assert((!std::__is_exactly_input_iterator >::value), "" ); static_assert(( std::__is_input_iterator >::value), "" ); static_assert(( std::__is_forward_iterator >::value), "" ); static_assert(( std::__is_bidirectional_iterator >::value), "" ); static_assert((!std::__is_random_access_iterator >::value), "" ); static_assert((!std::__is_exactly_input_iterator >::value), "" ); static_assert(( std::__is_input_iterator >::value), "" ); static_assert(( std::__is_forward_iterator >::value), "" ); static_assert(( std::__is_bidirectional_iterator >::value), "" ); static_assert(( std::__is_random_access_iterator >::value), "" ); static_assert((!std::__is_exactly_input_iterator >::value), "" ); static_assert(( std::__is_input_iterator >::value), "" ); static_assert((!std::__is_forward_iterator >::value), "" ); static_assert((!std::__is_bidirectional_iterator >::value), "" ); static_assert((!std::__is_random_access_iterator >::value), "" ); static_assert(( std::__is_exactly_input_iterator >::value), "" ); // // iterators from libc++'s containers // // string static_assert(( std::__libcpp_is_trivial_iterator::iterator> ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator::const_iterator> ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator::reverse_iterator> ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator::const_reverse_iterator>::value), ""); // vector static_assert(( std::__libcpp_is_trivial_iterator::iterator> ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator::const_iterator> ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator::reverse_iterator> ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator::const_reverse_iterator>::value), ""); #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS // Initializer list (which has no reverse iterators) static_assert(( std::__libcpp_is_trivial_iterator::iterator> ::value), ""); static_assert(( std::__libcpp_is_trivial_iterator::const_iterator> ::value), ""); #endif }