From 314dbcae33da300f9b669f74efc6ac864bbf2efa Mon Sep 17 00:00:00 2001 From: Raoul Gough Date: Thu, 9 Oct 2003 00:07:41 +0000 Subject: [PATCH] Move container_proxy iterator into separate proxy_iterator.hpp [SVN r20317] --- .../python/suite/indexing/container_proxy.hpp | 101 +++++++-------- .../python/suite/indexing/proxy_iterator.hpp | 120 ++++++++++++++++++ 2 files changed, 164 insertions(+), 57 deletions(-) create mode 100755 include/boost/python/suite/indexing/proxy_iterator.hpp diff --git a/include/boost/python/suite/indexing/container_proxy.hpp b/include/boost/python/suite/indexing/container_proxy.hpp index b3d7b945..537c3de0 100755 --- a/include/boost/python/suite/indexing/container_proxy.hpp +++ b/include/boost/python/suite/indexing/container_proxy.hpp @@ -18,6 +18,7 @@ #ifndef container_proxy_rmg_20030826_included #define container_proxy_rmg_20030826_included +#include #include #include @@ -64,6 +65,7 @@ namespace boost { namespace python { namespace indexing { typedef std::iterator_traits raw_iterator_traits; template friend class shared_proxy_impl; + template friend class proxy_iterator; public: typedef typename Holder::held_type held_type; @@ -81,63 +83,7 @@ namespace boost { namespace python { namespace indexing { typedef const_element_proxy const_value_type; typedef const_value_type const_reference; // Ref. semantics - public: - struct iterator - { - typedef typename raw_iterator_traits::difference_type difference_type; - typedef std::random_access_iterator_tag iterator_category; - typedef typename container_proxy::value_type value_type; - typedef value_type *pointer; - typedef value_type reference; // Already has reference semantics - - iterator (container_proxy *p, size_type i) : ptr (p), index (i) { } - - iterator (container_proxy *p, raw_iterator iter) - : ptr (p), index (iter - p->raw_container().begin()) - { - } - - reference operator*() const { return ptr->at(index); } - pointer operator->() const { return &ptr->at(index); } - reference operator[](size_type s) { return ptr->at (index + s); } - - iterator &operator++ () { ++index; return *this; } - iterator operator++ (int) { iterator temp(*this); ++index; return temp; } - iterator &operator+= (size_type s) { index += s; return *this; } - - iterator &operator-- () { --index; return *this; } - iterator operator-- (int) { iterator temp(*this); --index; return temp; } - iterator &operator-= (size_type s) { index -= s; return *this; } - - iterator operator+ (size_type s) const { return iterator(*this) += s; } - iterator operator- (size_type s) const { return iterator(*this) -= s; } - difference_type operator- (iterator i) const { return index - i.index; } - - bool operator== (iterator const &other) const { - return (ptr == other.ptr) && (index == other.index); - } - - bool operator!= (iterator const &other) const { return !(*this == other); } - - bool operator< (iterator const &other) const { - return index < other.index; - } - - bool operator> (iterator const &other) const { - return index > other.index; - } - - // public: - // Extensions to the normal iterator interface - // void replace (value_type const ©) { ptr->replace (index, copy); } - - public: - friend class container_proxy; - container_proxy *ptr; - size_type index; - }; - - friend struct iterator; + typedef proxy_iterator iterator; public: // Constructors @@ -190,6 +136,8 @@ namespace boost { namespace python { namespace indexing { void replace (size_type index, raw_value_type const &); template void replace (size_type index, Iter, Iter); + void swap_elements (size_type index1, size_type index2); + private: // Overloads for insertions with/without useful std::distance template @@ -342,6 +290,45 @@ namespace boost { namespace python { namespace indexing { } } + template + void + container_proxy + ::swap_elements (size_type index1, size_type index2) + { + MapIterator iter1 = myMap.find (index1); + MapIterator iter2 = myMap.find (index2); + + long distance = static_cast(index2) - static_cast(index1); + + if ((iter1 == myMap.end()) && (iter2 == myMap.end())) + { + // No proxies exist for these indexes. + } + + else if ((iter1 != myMap.end()) && (iter2 == myMap.end())) + { + // Proxy for the first index only + MapIterator temp (iter1); + adjustIndexes (iter1, ++temp, distance); + } + + else if ((iter1 == myMap.end()) && (iter2 != myMap.end())) + { + // Proxy for the second index only + MapIterator temp (iter2); + adjustIndexes (iter2, ++temp, -distance); + } + + else + { + // Proxies for both indexes + std::swap (iter1->second->myIndex, iter2->second->myIndex); + std::swap (iter1->second, iter2->second); + } + + std::swap (raw_container()[index1], raw_container()[index2]); + } + template typename container_proxy::iterator container_proxy diff --git a/include/boost/python/suite/indexing/proxy_iterator.hpp b/include/boost/python/suite/indexing/proxy_iterator.hpp new file mode 100755 index 00000000..7b176204 --- /dev/null +++ b/include/boost/python/suite/indexing/proxy_iterator.hpp @@ -0,0 +1,120 @@ +// -*- mode:c++ -*- +// +// Header file proxy_iterator.hpp +// +// 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/10/ 8 rmg File creation +// +// $Id$ +// + +#ifndef proxy_iterator_rmg_20031008_included +#define proxy_iterator_rmg_20031008_included + +#include + +namespace boost { namespace python { namespace indexing { + template + struct proxy_iterator + { + template friend class container_proxy; + + typedef ContainerProxy container_proxy_; + typedef typename container_proxy_::raw_iterator_traits raw_iterator_traits; + typedef typename raw_iterator_traits::difference_type difference_type; + typedef typename container_proxy_::size_type size_type; + typedef typename container_proxy_::value_type value_type; + typedef typename container_proxy_::raw_iterator raw_iterator; + typedef value_type *pointer; + typedef value_type reference; // Already has reference semantics + typedef std::random_access_iterator_tag iterator_category; + + proxy_iterator (container_proxy_ *p, size_type i) : ptr (p), index (i) { } + + proxy_iterator (container_proxy_ *p, raw_iterator iter) + : ptr (p), index (iter - p->raw_container().begin()) + { + } + + reference operator*() const { return ptr->at(index); } + pointer operator->() const { return &ptr->at(index); } + reference operator[](size_type s) { return ptr->at (index + s); } + + proxy_iterator &operator++ () { ++index; return *this; } + proxy_iterator &operator+= (size_type s) { index += s; return *this; } + + proxy_iterator &operator-- () { --index; return *this; } + + proxy_iterator operator++ (int) { + proxy_iterator temp(*this); + ++index; + return temp; + } + + proxy_iterator operator-- (int) { + proxy_iterator temp(*this); + --index; + return temp; + } + + proxy_iterator &operator-= (size_type s) { index -= s; return *this; } + + proxy_iterator operator+ (size_type s) const { + return proxy_iterator(*this) += s; + } + + proxy_iterator operator- (size_type s) const { + return proxy_iterator(*this) -= s; + } + + difference_type operator- (proxy_iterator i) const { + return index - i.index; + } + + bool operator== (proxy_iterator const &other) const { + return (ptr == other.ptr) && (index == other.index); + } + + bool operator!= (proxy_iterator const &other) const { + return !(*this == other); + } + + bool operator< (proxy_iterator const &other) const { + return index < other.index; + } + + bool operator> (proxy_iterator const &other) const { + return index > other.index; + } + + void iter_swap (proxy_iterator const &other) const { + ptr->swap_elements (index, other.index); + } + + // public: + // Extensions to the normal iterator interface + // void replace (value_type const ©) { ptr->replace (index, copy); } + + public: + container_proxy_ *ptr; + size_type index; + }; +} } } + +namespace std { + template + void iter_swap (boost::python::indexing::proxy_iterator const &first + , boost::python::indexing::proxy_iterator const &second) + { + first.iter_swap (second); + } +} + +#endif // proxy_iterator_rmg_20031008_included