// -*- mode:c++ -*-
//
// Header file iterator_traits.hpp
//
// Traits information about iterators for use in determining what
// Python methods to support for a container.
//
// Copyright (c) 2003 Raoul M. Gough
//
// 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)
//
// History
// =======
// 2003/ 8/23 rmg File creation as iterator_suite.hpp
// 2003/ 9/12 rmg Renamed iterator_traits.hpp
// 2008/12/08 Roman Change indexing suite layout
//
// $Id: iterator_traits.hpp,v 1.1.2.14 2004/02/08 18:57:42 raoulgough Exp $
//
#ifndef BOOST_PYTHON_INDEXING_ITERATOR_TRAITS_HPP
#define BOOST_PYTHON_INDEXING_ITERATOR_TRAITS_HPP
#include <indexing_suite/suite_utils.hpp>
#include <indexing_suite/methods.hpp>
//#include <indexing_suite/workaround.hpp>
//#include <boost/call_traits.hpp>
//#include <boost/type_traits.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/iterator/iterator_categories.hpp>
namespace boost { namespace python { namespace indexing {
//////////////////////////////////////////////////////////////////////////
// Indexing traits common base class
//////////////////////////////////////////////////////////////////////////
template<typename Iterator>
struct base_iterator_traits
{
private:
typedef ::boost::detail::iterator_traits<Iterator> std_traits;
typedef typename std_traits::reference reference;
public:
// typedef Iterator iterator;
// typedef typename std_traits::value_type value_type;
// typedef typename std_traits::difference_type difference_type;
BOOST_STATIC_CONSTANT(
bool, has_mutable_ref = is_mutable_ref<reference>::value);
};
//////////////////////////////////////////////////////////////////////////
// Indexing traits for input iterators
//////////////////////////////////////////////////////////////////////////
template<typename Iterator>
struct input_iterator_traits : base_iterator_traits<Iterator>
{
BOOST_STATIC_CONSTANT(
method_set_type,
supported_methods = (
method_iter
));
};
//////////////////////////////////////////////////////////////////////////
// Indexing traits for forward iterators
//////////////////////////////////////////////////////////////////////////
template<typename Iterator>
struct forward_iterator_traits
: public base_iterator_traits<Iterator>
{
BOOST_STATIC_CONSTANT(
method_set_type,
supported_methods = (
method_len
| method_iter
));
};
//////////////////////////////////////////////////////////////////////////
// Indexing traits for bidirectional iterators
//////////////////////////////////////////////////////////////////////////
template<typename Iterator>
struct bidirectional_iterator_traits
: public forward_iterator_traits<Iterator>
{
typedef forward_iterator_traits<Iterator> base_class;
BOOST_STATIC_CONSTANT(
method_set_type,
supported_methods = (
base_class::supported_methods
| detail::method_set_if<
base_class::has_mutable_ref,
method_reverse
>::value
));
};
//////////////////////////////////////////////////////////////////////////
// Indexing traits for random access iterators
//////////////////////////////////////////////////////////////////////////
template<typename Iterator>
struct random_access_iterator_traits
: public bidirectional_iterator_traits<Iterator>
{
typedef bidirectional_iterator_traits<Iterator> base_class;
BOOST_STATIC_CONSTANT(
method_set_type,
supported_methods = (
(base_class::supported_methods & ~method_iter)
| method_getitem
| method_getitem_slice
| detail::method_set_if<
base_class::has_mutable_ref,
method_setitem
| method_setitem_slice
>::value
| method_index // Assumes value is equality_comparable
| method_contains // Assumes value is equality_comparable
| method_count // Assumes value is equality_comparable
| detail::method_set_if<
base_class::has_mutable_ref,
method_sort
>::value // Assumes value is less_than_comparable
));
};
namespace iterator_detail {
// Some meta-progamming machinery to select the right
// indexing::iterator_traits template on the basis of
// BOOST_ITERATOR_CATEGORY
typedef char basic_iter_sizer[1];
typedef char forward_iter_sizer[2];
typedef char bidirectional_iter_sizer[3];
typedef char random_access_iter_sizer[4];
basic_iter_sizer &sizer (void *);
forward_iter_sizer &sizer (std::forward_iterator_tag *);
bidirectional_iter_sizer &sizer (std::bidirectional_iterator_tag *);
random_access_iter_sizer &sizer (std::random_access_iterator_tag *);
template<size_t Size> struct traits_by_size {
// Default implementation gives only the most basic support
template<typename Iterator>
struct traits {
typedef input_iterator_traits<Iterator> type;
};
};
template<>
struct traits_by_size<sizeof(forward_iter_sizer)> {
template<typename Iterator>
struct traits {
typedef forward_iterator_traits<Iterator> type;
};
};
template<>
struct traits_by_size<sizeof(bidirectional_iter_sizer)> {
template<typename Iterator>
struct traits {
typedef bidirectional_iterator_traits<Iterator> type;
};
};
template<>
struct traits_by_size<sizeof(random_access_iter_sizer)> {
template<typename Iterator>
struct traits {
typedef random_access_iterator_traits<Iterator> type;
};
};
template<typename Iterator>
class deduced_traits {
typedef typename ::boost::BOOST_ITERATOR_CATEGORY<Iterator>::type
category;
BOOST_STATIC_CONSTANT(
size_t, sizer_result = sizeof (sizer (new category)));
public:
typedef typename traits_by_size<sizer_result>
::BOOST_NESTED_TEMPLATE traits<Iterator>::type type;
};
}
template<typename Iterator>
struct iterator_traits
: public iterator_detail::deduced_traits<Iterator>::type
{
};
} } }
#endif // BOOST_PYTHON_INDEXING_ITERATOR_TRAITS_HPP