// (C) Copyright 2008-2009 SDML (www.sdml.info) // // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include #include using namespace origin; using std::cout; // TODO: Cleverness that nees to exported somewhere useful. This segment // adapts several STL iterators to the Origin.ForwardIterator concept. namespace origin { template struct ForwardIterator<__gnu_cxx::__normal_iterator> : Tautology, InputIterator<__gnu_cxx::__normal_iterator> { ORIGIN_CONCEPT_MAP_IMPL(); }; template struct ForwardIterator> : Tautology, InputIterator> { ORIGIN_CONCEPT_MAP_IMPL(); }; template struct ForwardIterator> : Tautology, InputIterator> { ORIGIN_CONCEPT_MAP_IMPL(); }; } // namespace origin // NOTE: Printing the type as an argument to a function will cause the type // string to preserve references. // TODO: I could actually parse the resulting string to generate the actual // type. All I would have to do is find everything between the 2nd ( and the // last ). struct viz { }; template std::string str() { return typestr(); } template < typename X, typename = typename concept_assert>::type> void test_iterator() { typedef Iterator Model; cout << typestr() << "\n"; cout << " reference:\t" << str() << "\n"; cout << " postincr:\t" << str() << "\n"; } template < typename X, typename = typename concept_assert>::type> void test_input_iterator() { typedef InputIterator Model; cout << typestr() << "\n"; cout << " value:\t\t" << str() << "\n"; cout << " reference:\t" << str() << "\n"; cout << " pointer:\t" << str() << "\n"; cout << " difference:\t" << str() << "\n"; cout << " postincr:\t" << str() << "\n"; } template < typename X, typename = typename concept_assert>::type> void test_output_iterator() { } template < typename X, typename = typename concept_assert>::type> void test_forward_iterator() { typedef ForwardIterator Model; cout << typestr() << "\n"; cout << " value:\t\t" << str() << "\n"; cout << " reference:\t" << str() << "\n"; cout << " pointer:\t" << str() << "\n"; cout << " difference:\t" << str() << "\n"; cout << " postincr:\t" << str() << "\n"; } template < typename X, typename = typename concept_assert>::type> void test_bidirectional_iterator() { typedef BidirectionalIterator Model; cout << typestr() << "\n"; cout << " value:\t\t" << str() << "\n"; cout << " reference:\t" << str() << "\n"; cout << " pointer:\t" << str() << "\n"; cout << " difference:\t" << str() << "\n"; cout << " postincr:\t" << str() << "\n"; cout << " postdecr:\t" << str() << "\n"; } template < typename X, typename = typename concept_assert>::type> void test_random_access_iterator() { typedef RandomAccessIterator Model; cout << typestr() << "\n"; cout << " value:\t\t" << str() << "\n"; cout << " reference:\t" << str() << "\n"; cout << " pointer:\t" << str() << "\n"; cout << " difference:\t" << str() << "\n"; cout << " postincr:\t" << str() << "\n"; cout << " postdecr:\t" << str() << "\n"; cout << " subscript:\t" << str() << "\n"; } template < typename X, typename = typename concept_assert>::type> void test_shuffle_iterator() { } void test_concepts() { BOOST_ASSERT(( !concept_check< Iterator >::value )); BOOST_ASSERT(( concept_check< Iterator >::value )); BOOST_ASSERT(( concept_check< Iterator >::value )); BOOST_ASSERT(( concept_check< Iterator::iterator> >::value )); BOOST_ASSERT(( concept_check< Iterator::const_iterator> >::value )); test_iterator(); test_iterator(); test_iterator::iterator>(); test_iterator::const_iterator>(); // test_iterator(); // OK test_input_iterator(); test_input_iterator(); test_input_iterator::iterator>(); test_input_iterator::const_iterator>(); test_forward_iterator(); test_forward_iterator::iterator>(); BOOST_ASSERT(( concept_check< BidirectionalIterator >::value )); BOOST_ASSERT(( concept_check< BidirectionalIterator >::value )); BOOST_ASSERT(( concept_check< BidirectionalIterator::iterator> >::value )); BOOST_ASSERT(( concept_check< BidirectionalIterator::const_iterator> >::value )); BOOST_ASSERT(( !concept_check< BidirectionalIterator::iterator> >::value )); test_bidirectional_iterator(); test_bidirectional_iterator::iterator>(); // test_bidirectional_iterator::iterator>(); // OK BOOST_ASSERT(( concept_check< RandomAccessIterator >::value )); BOOST_ASSERT(( concept_check< RandomAccessIterator >::value )); BOOST_ASSERT(( concept_check< RandomAccessIterator::iterator> >::value )); BOOST_ASSERT(( concept_check< RandomAccessIterator::const_iterator> >::value )); BOOST_ASSERT(( !concept_check< RandomAccessIterator::iterator> >::value )); test_random_access_iterator(); test_random_access_iterator::iterator>(); // test_random_access_iterator::iterator>(); // OK BOOST_ASSERT(( concept_check< OutputIterator >::value )); BOOST_ASSERT(( !concept_check< OutputIterator >::value )); } int main() { test_concepts(); return 0; }