diff --git a/include/boost/python/suite/indexing/container_traits.hpp b/include/boost/python/suite/indexing/container_traits.hpp new file mode 100755 index 00000000..04b4abff --- /dev/null +++ b/include/boost/python/suite/indexing/container_traits.hpp @@ -0,0 +1,281 @@ +// -*- mode:c++ -*- +// +// Header file container_traits.hpp +// +// Copyright (c) 2003 Raoul M. Gough +// +// This material is provided "as is", with absolutely no warranty expressed +// or implied. Any use is at your own risk. +// +// Permission to use or copy this material for any purpose is hereby +// granted without fee, provided the above notices are retained on all +// copies. Permission to modify the material and to distribute modified +// versions is granted, provided the above notices are retained, and a +// notice that the material was modified is included with the above +// copyright notice. +// +// History +// ======= +// 2003/ 8/23 rmg File creation as container_suite.hpp +// 2003/ 9/ 8 rmg Renamed container_traits.hpp +// +// $Id$ +// + +#ifndef container_traits_rmg_20030823_included +#define container_traits_rmg_20030823_included + +#include "suite_utils.hpp" +#include "iterator_suite.hpp" +#include + +#include "iterator_pair.hpp" +#include +#include +#include +#include +#include + +namespace indexing { + ///////////////////////////////////////////////////////////////////////// + // Traits for the iterator_pair container emulator + ///////////////////////////////////////////////////////////////////////// + + template + struct iterator_pair_traits + : public + iterator_detail::traits_by_category::type + { + typedef IteratorPair container; + typedef typename IteratorPair::size_type size_type; + typedef typename IteratorPair::size_type index_type; // at() + + static bool const has_insert = false; + static bool const has_erase = false; + static bool const has_pop_back = false; + static bool const has_push_back = false; + + // Default implementations of support functions + typedef container_algorithms algorithms; + }; + + ///////////////////////////////////////////////////////////////////////// + // Lowest common denominator (almost all "real" containers would + // meet at least these requirements) + ///////////////////////////////////////////////////////////////////////// + + template + struct default_container_traits + { + protected: + static bool const is_mutable = ! boost::is_const::value; + + public: + typedef Container container; + + // *FIXME* should use value_type const and const_reference if !is_mutable + typedef typename Container::value_type value_type; + typedef typename Container::reference reference; + + typedef typename Container::difference_type difference_type; + typedef typename Container::size_type size_type; + typedef typename Container::size_type index_type; // at() + typedef value_type key_type; // find, count, ... + + // Should probably select iterator or const_iterator on the + // basis of is_mutable + typedef typename Container::iterator iterator; + typedef typename Container::const_iterator const_iterator; + + static bool const has_copyable_iter = true; + + static IndexStyle const index_style + = ::indexing::iterator_traits::index_style; + + static bool const has_mutable_ref + = is_mutable && is_mutable_ref::value; + + // has_mutable_ref basically means that the container supports + // in-place replacement of values (e.g. the associative containers + // *don't*) + + static bool const is_reversible = has_mutable_ref; + + static bool const has_insert = is_mutable; + static bool const has_erase = is_mutable; + static bool const has_pop_back = false; + static bool const has_push_back = false; + + // Default implementations of support functions + typedef container_algorithms algorithms; + }; + + ///////////////////////////////////////////////////////////////////////// + // Sequences (list, deque, vector) + ///////////////////////////////////////////////////////////////////////// + + template + struct default_sequence_traits : public default_container_traits + { + static bool const has_pop_back = is_mutable; + static bool const has_push_back = is_mutable; + }; + + template + struct list_traits : public default_sequence_traits + { + // Some special algo's for list (using member functions) + typedef list_algorithms algorithms; + }; + + ///////////////////////////////////////////////////////////////////////// + // Associative containers set and multiset + ///////////////////////////////////////////////////////////////////////// + + template + struct set_traits : public default_container_traits + { + static IndexStyle const index_style = index_style_nonlinear; + + // Special algo's for set types (using member functions) + typedef assoc_algorithms algorithms; + }; + + ///////////////////////////////////////////////////////////////////////// + // Associative containers map and multimap + ///////////////////////////////////////////////////////////////////////// + + template + struct map_traits : public default_container_traits + { + // *FIXME* handle const maps + typedef typename Container::mapped_type value_type; + typedef value_type & reference; + typedef typename Container::key_type index_type; // at() + typedef typename Container::key_type key_type; // find, count, ... + + static IndexStyle const index_style = index_style_nonlinear; + + // Special algo's for map types (using member functions) + typedef assoc_algorithms algorithms; + }; + + ///////////////////////////////////////////////////////////////////////// + // Automated trait selection + ///////////////////////////////////////////////////////////////////////// + + namespace container_details { + template struct traits_by_type; + + // traits_by_type instances should include two typedefs, one for + // the non-const version of the container, and one for the + // const version. This saves having to have two specializations + // of traits_by_type for every kind of container. + + // std::set + template + class traits_by_type > + { + typedef std::set Container; + + public: + typedef set_traits mutable_type; + typedef set_traits const_type; + }; + + // std::multiset + template + class traits_by_type > + { + typedef std::multiset Container; + + public: + typedef set_traits mutable_type; + typedef set_traits const_type; + }; + + // std::map + template + class traits_by_type > + { + typedef std::map Container; + + public: + typedef map_traits mutable_type; + typedef map_traits const_type; + }; + + // std::multimap + template + class traits_by_type > + { + typedef std::multimap Container; + + public: + typedef map_traits mutable_type; + typedef map_traits const_type; + }; + + // std::vector + template + class traits_by_type > + { + typedef std::vector Container; + + public: + typedef default_sequence_traits mutable_type; + typedef default_sequence_traits const_type; + }; + + // std::deque + template + class traits_by_type > + { + typedef std::deque Container; + + public: + typedef default_sequence_traits mutable_type; + typedef default_sequence_traits const_type; + }; + + // std::list + template + class traits_by_type > + { + typedef std::list Container; + + public: + typedef list_traits mutable_type; + typedef list_traits const_type; + }; + + // Iterator ranges + template + class traits_by_type > + { + typedef ::indexing::iterator_pair Container; + + public: + typedef iterator_pair_traits mutable_type; + typedef iterator_pair_traits const_type; // ? + }; + } + + // Select the right traits for each supported kind of container + + // Generic version (mutable containers) + template + struct container_traits + : public container_details::traits_by_type::mutable_type + { + }; + + // Partial specialization for const containers + template + struct container_traits + : public container_details::traits_by_type::const_type + { + }; +} + +#endif // container_suite_rmg_20030823_included