31 #ifndef BOOST_PYTHON_INDEXING_CONTAINER_PROXY_HPP
32 #define BOOST_PYTHON_INDEXING_CONTAINER_PROXY_HPP
34 #include <indexing_suite/proxy_iterator.hpp>
35 #include <indexing_suite/shared_proxy_impl.hpp>
36 #include <indexing_suite/element_proxy.hpp>
37 #include <indexing_suite/element_proxy_traits.hpp>
38 #include <indexing_suite/workaround.hpp>
39 #include <indexing_suite/methods.hpp>
43 #include <boost/shared_ptr.hpp>
44 #include <boost/mpl/apply.hpp>
45 #include <boost/iterator/iterator_traits.hpp>
46 #include <indexing_suite/container_traits.hpp>
47 #include <indexing_suite/container_suite.hpp>
48 #include <indexing_suite/algorithms.hpp>
50 namespace boost {
namespace python {
namespace indexing {
55 static T &
get(T & obj) {
return obj; }
56 static T
const &
get(T
const & obj) {
return obj; }
58 static T create () {
return T(); }
59 static T copy (T
const ©) {
return copy; }
60 static void assign (T &to, T
const &from) { to = from; }
61 static void pre_destruction (T &) { }
62 static void swap (T &one, T &two) { std::swap (one, two); }
65 template<
typename P>
struct deref {
68 typedef typename boost::iterator_value<P>::type value;
70 static value &
get (P & ptr) {
return *ptr; }
71 static value
const &
get (P
const & ptr) {
return *ptr; }
73 static P create () {
return P(); }
74 static P copy (P
const ©) {
return copy; }
75 static void assign (P &to, P
const &from) { to = from; }
76 static void pre_destruction (P &) { }
77 static void swap (P &one, P &two) { std::swap (one, two); }
82 template<
typename Element>
struct apply {
83 typedef std::vector<Element> type;
87 #if BOOST_WORKAROUND (BOOST_MSVC, == 1200)
90 template<
typename Container>
struct msvc6_iterator {
91 typedef Container::iterator type;
94 template<>
struct msvc6_iterator<int> {
100 template<
class Container,
101 class Holder = identity<Container>,
102 class Generator = vector_generator>
106 typedef typename Container::iterator raw_iterator;
107 typedef ::boost::detail::iterator_traits<raw_iterator> raw_iterator_traits;
109 #if !defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
111 template<
class C,
typename E,
typename T,
typename S,
typename I>
116 typedef typename Holder::held_type held_type;
118 typedef typename Container::size_type size_type;
119 typedef typename Container::difference_type difference_type;
123 typedef typename Container::value_type raw_value_type;
131 typedef proxy_iterator <self_type, value_type, raw_iterator_traits,
139 : m_held_obj (Holder::create()),
142 insert (begin(), start, finish);
152 Container
const &raw_container()
const;
154 reference at (size_type index);
155 const_reference at (size_type index)
const;
157 reference operator[] (size_type index) {
return at(index); }
158 const_reference operator[] (size_type index)
const {
return at(index); }
160 size_type size ()
const {
return raw_container().size(); }
161 size_type capacity ()
const {
return raw_container().capacity(); }
162 void reserve (size_type s);
165 iterator begin() {
return iterator (
this, static_cast<size_type>(0)); }
166 iterator end() {
return iterator (
this, raw_container().size()); }
168 iterator erase (iterator);
169 iterator erase (iterator, iterator);
170 iterator insert (iterator, raw_value_type
const &);
172 template<
typename Iter>
void insert (iterator iter, Iter from, Iter to)
176 typedef typename BOOST_ITERATOR_CATEGORY<Iter>::type category;
177 insert (iter, from, to, category());
180 void push_back (raw_value_type
const ©) { insert (end(), copy); }
182 value_type pop_back () {
183 value_type result = at (size() - 1);
195 void detach_proxy (size_type index);
196 void detach_proxies (size_type from, size_type to);
199 void prepare_erase (size_type from, size_type to);
202 void notify_insertion (size_type from, size_type to);
207 void replace (size_type index, raw_value_type
const &);
210 void swap_elements (size_type index1, size_type index2);
212 bool is_valid ()
const;
216 template<
typename Iter>
217 void insert (iterator iter, Iter from, Iter to, std::forward_iterator_tag)
220 assert (iter.ptr ==
this);
221 size_type count = std::distance (from, to);
224 m_proxies.insert (m_proxies.begin() + iter.index, count, pointer_impl());
229 raw_container().insert(
230 raw_container().begin() + iter.index,
237 write_proxies (iter.index, iter.index + count);
242 raw_container().erase(
243 raw_container().begin() + iter.index,
244 raw_container().begin() + iter.index + count);
253 m_proxies.begin() + iter.index,
254 m_proxies.begin() + iter.index + count);
261 m_proxies.begin() + iter.index + count,
263 static_cast<difference_type
> (count));
266 template<
typename Iter>
267 void insert (iterator iter, Iter from, Iter to, std::input_iterator_tag)
274 iter = insert (iter, *from++) + 1;
279 typedef boost::shared_ptr<shared_proxy> pointer_impl;
281 typedef typename mpl::apply1<Generator, pointer_impl>::type
284 #if BOOST_WORKAROUND (BOOST_MSVC, == 1200)
285 typedef detail::msvc6_iterator<pointer_container>::type pointer_iterator;
287 typedef typename pointer_container::iterator pointer_iterator;
290 #if defined (BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
294 Container &raw_container();
297 void adjust_proxies (pointer_iterator, pointer_iterator, difference_type);
298 void write_proxies (size_type, size_type);
299 bool clear_proxy (pointer_impl &);
300 void clear_proxies (size_type, size_type);
301 void claim_all_proxies ();
304 held_type m_held_obj;
305 pointer_container m_proxies;
308 template<
class Container,
class Holder,
class Generator>
311 : m_held_obj (Holder::create()),
317 template<
class Container,
class Holder,
class Generator>
318 container_proxy<Container, Holder, Generator>
319 ::container_proxy (held_type
const &held)
320 : m_held_obj (Holder::copy (held)),
323 write_proxies (0, size());
326 template<
class Container,
class Holder,
class Generator>
327 container_proxy<Container, Holder, Generator>
328 ::container_proxy (container_proxy
const ©)
329 : m_held_obj (Holder::copy (copy.m_held_obj)),
332 write_proxies (0, size());
335 template<
class Container,
class Holder,
class Generator>
336 container_proxy<Container, Holder, Generator> &
337 container_proxy<Container, Holder, Generator>
338 ::operator= (container_proxy
const ©)
340 container_proxy<Container, Holder, Generator> temp (copy);
343 Holder::swap (m_held_obj, temp.m_held_obj);
344 std::swap (m_proxies, temp.m_proxies);
346 claim_all_proxies ();
347 temp.claim_all_proxies ();
353 template<
class Container,
class Holder,
class Generator>
354 container_proxy<Container, Holder, Generator>
355 ::~container_proxy ()
358 clear_proxies (0, size());
359 Holder::pre_destruction (m_held_obj);
362 template<
class Container,
class Holder,
class Generator>
364 container_proxy<Container, Holder, Generator>
367 return Holder::get (m_held_obj);
370 template<
class Container,
class Holder,
class Generator>
372 container_proxy<Container, Holder, Generator>
373 ::raw_container ()
const
375 return Holder::get (m_held_obj);
378 template<
class Container,
class Holder,
class Generator>
379 void container_proxy<Container, Holder, Generator>::reserve (size_type size)
381 raw_container().reserve (size);
382 m_proxies.reserve (size);
385 template<
class Container,
class Holder,
class Generator>
386 BOOST_DEDUCED_TYPENAME container_proxy<Container, Holder, Generator>::reference
387 container_proxy<Container, Holder, Generator>
388 ::at (size_type index)
390 pointer_impl
const &ptr = m_proxies.BOOST_PYTHON_INDEXING_AT (index);
391 assert (ptr->owner() ==
this);
392 assert (ptr->index() == index);
393 return reference (ptr);
396 template<
class Container,
class Holder,
class Generator>
397 BOOST_DEDUCED_TYPENAME container_proxy<Container, Holder, Generator>::const_reference
398 container_proxy<Container, Holder, Generator>
399 ::at (size_type index)
const
401 pointer_impl
const &ptr = m_proxies.BOOST_PYTHON_INDEXING_AT (index);
402 assert (ptr->owner() ==
this);
403 assert (ptr->index() == index);
404 return const_reference (ptr);
407 template<
class Container,
class Holder,
class Generator>
409 container_proxy<Container, Holder, Generator>
410 ::replace (size_type index, raw_value_type
const ©)
412 detach_proxy (index);
413 raw_container().BOOST_PYTHON_INDEXING_AT (index) = copy;
414 write_proxies (index, index + 1);
417 template<
class Container,
class Holder,
class Generator>
419 container_proxy<Container, Holder, Generator>
420 ::swap_elements (size_type index1, size_type index2)
422 pointer_impl &ptr1 = m_proxies[index1];
423 pointer_impl &ptr2 = m_proxies[index2];
425 assert (ptr1->owner() ==
this);
426 assert (ptr2->owner() ==
this);
427 assert (ptr1->index() == index1);
428 assert (ptr2->index() == index2);
446 std::swap (ptr1->m_index, ptr2->m_index);
447 std::swap (ptr1, ptr2);
448 std::swap (raw_container()[index1], raw_container()[index2]);
450 assert (m_proxies[index1]->index() == index1);
451 assert (m_proxies[index2]->index() == index2);
454 template<
class Container,
class Holder,
class Generator>
455 BOOST_DEDUCED_TYPENAME container_proxy<Container, Holder, Generator>::iterator
456 container_proxy<Container, Holder, Generator>::erase (iterator iter)
458 return erase (iter, iter + 1);
461 template<
class Container,
class Holder,
class Generator>
462 BOOST_DEDUCED_TYPENAME container_proxy<Container, Holder, Generator>::iterator
463 container_proxy<Container, Holder, Generator>::erase(
464 iterator from, iterator to)
466 assert (from.ptr ==
this);
467 assert (to.ptr ==
this);
470 prepare_erase (from.index, to.index);
474 = raw_container().erase(
475 raw_container().begin() + from.index,
476 raw_container().begin() + to.index);
478 return iterator (
this, result);
481 template<
class Container,
class Holder,
class Generator>
482 BOOST_DEDUCED_TYPENAME container_proxy<Container, Holder, Generator>::iterator
483 container_proxy<Container, Holder, Generator>::insert(
484 iterator iter, raw_value_type
const ©)
488 insert (iter, ©, (©) + 1, std::random_access_iterator_tag());
493 template<
class Container,
class Holder,
class Generator>
494 bool container_proxy<Container, Holder, Generator>::clear_proxy(
500 assert (ptr->owner() ==
this);
517 template<
class Container,
class Holder,
class Generator>
518 void container_proxy<Container, Holder, Generator>::clear_proxies(
519 size_type from_index, size_type to_index)
521 while (from_index != to_index)
523 clear_proxy (m_proxies[from_index]);
528 template<
class Container,
class Holder,
class Generator>
529 void container_proxy<Container, Holder, Generator>
530 ::detach_proxy (size_type index)
532 pointer_impl &ptr = m_proxies[index];
534 assert (ptr->index() == index);
536 if (clear_proxy (ptr))
539 ptr.reset (
new shared_proxy (
this, index));
543 template<
class Container,
class Holder,
class Generator>
544 void container_proxy<Container, Holder, Generator>::detach_proxies(
545 size_type from_index, size_type to_index)
547 while (from_index != to_index)
549 detach_proxy (from_index);
554 template<
class Container,
class Holder,
class Generator>
555 void container_proxy<Container, Holder, Generator>
556 ::prepare_erase (size_type from_index, size_type to_index)
558 difference_type deleting = to_index - from_index;
559 pointer_iterator erase_begin = m_proxies.begin() + from_index;
560 pointer_iterator erase_end = m_proxies.begin() + to_index;
563 adjust_proxies (erase_end, m_proxies.end(), -deleting);
566 clear_proxies (from_index, to_index);
569 m_proxies.erase (erase_begin, erase_end);
572 template<
class Container,
class Holder,
class Generator>
573 void container_proxy<Container, Holder, Generator>::notify_insertion(
574 size_type from_index, size_type to_index)
576 size_type count = to_index - from_index;
579 m_proxies.begin() + from_index, count, pointer_impl());
583 write_proxies (from_index, to_index);
589 m_proxies.begin() + from_index,
590 m_proxies.begin() + to_index);
597 m_proxies.begin() + to_index,
599 static_cast<difference_type
> (count));
602 template<
class Container,
class Holder,
class Generator>
603 void container_proxy<Container, Holder, Generator>::adjust_proxies(
604 pointer_iterator from,
606 difference_type offset)
610 (*from)->m_index += offset;
615 template<
class Container,
class Holder,
class Generator>
616 void container_proxy<Container, Holder, Generator>::write_proxies(
617 size_type from, size_type to)
626 pointer_impl &ptr = m_proxies[from];
628 if ((ptr.get() == 0) || (!ptr.unique()))
632 ptr.reset (
new shared_proxy (
this, from));
638 assert (ptr->owner() ==
this);
646 template<
class Container,
class Holder,
class Generator>
647 void container_proxy<Container, Holder, Generator>::claim_all_proxies ()
649 for (pointer_iterator iter = m_proxies.begin();
650 iter != m_proxies.end();
653 (*iter)->m_owner_ptr =
this;
657 template<
class Container,
class Holder,
class Generator>
658 bool container_proxy<Container, Holder, Generator>::is_valid ()
const
660 bool ok = size() == m_proxies.size();
662 for (size_type count = 0; ok && (count < size()); ++count)
664 pointer_impl
const &ptr = m_proxies[count];
666 ok = ptr.get() && (ptr->owner() ==
this) && (ptr->index() == count)
667 && !ptr->m_element_ptr.get();
677 template<
typename Container>
680 typedef Container container;
681 typedef typename container::raw_value_type value_type;
682 typedef typename container::raw_value_type key_type;
683 typedef typename container::reference reference;
685 typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <value_type>::param_type
687 typedef typename BOOST_PYTHON_INDEXING_CALL_TRAITS <key_type>::param_type
690 #if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
699 template<
typename PythonClass,
typename Policy>
700 static void visit_container_class(
701 PythonClass &pyClass, Policy
const &policy)
703 value_traits_type::visit_container_class (pyClass, policy);
708 #if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
714 template <
typename RawContainer,
typename Holder,
typename Generator>
730 method_set_type MethodMask = all_methods,
740 #endif // BOOST_PYTHON_INDEXING_CONTAINER_PROXY_HPP
Definition: container_proxy.hpp:65
Definition: algorithms.hpp:42
Definition: container_traits.hpp:113
Definition: python_CEGUI.h:9
Definition: container_proxy.hpp:80
Definition: proxy_iterator.hpp:32
Definition: container_suite.hpp:42
Definition: container_proxy.hpp:103
Definition: element_proxy_traits.hpp:37
Definition: element_proxy.hpp:33
Definition: algorithms.hpp:532
Definition: container_proxy.hpp:82
Definition: container_proxy.hpp:733
Definition: container_proxy.hpp:52
Definition: shared_proxy_impl.hpp:34
Definition: element_proxy.hpp:117
Definition: container_proxy.hpp:678