1// Copyright (C) Vladimir Prus 2003.
2// Distributed under the Boost Software License, Version 1.0. (See
3// accompanying file LICENSE_1_0.txt or copy at
4// http://www.boost.org/LICENSE_1_0.txt)
5//
6// See http://www.boost.org/libs/graph/vector_property_map.html for
7// documentation.
8//
9
10#ifndef BOOST_PROPERTY_MAP_VECTOR_PROPERTY_MAP_HPP
11#define BOOST_PROPERTY_MAP_VECTOR_PROPERTY_MAP_HPP
12
13#include <boost/property_map/property_map.hpp>
14#include <boost/smart_ptr/shared_ptr.hpp>
15#include <iterator>
16#include <vector>
17
18namespace boost {
19 template<typename T, typename IndexMap = identity_property_map>
20 class vector_property_map
21 : public boost::put_get_helper<
22 typename std::iterator_traits<
23 typename std::vector<T>::iterator >::reference,
24 vector_property_map<T, IndexMap> >
25 {
26 public:
27 typedef typename property_traits<IndexMap>::key_type key_type;
28 typedef T value_type;
29 typedef typename std::iterator_traits<
30 typename std::vector<T>::iterator >::reference reference;
31 typedef boost::lvalue_property_map_tag category;
32
33 vector_property_map(const IndexMap& index = IndexMap())
34 : store(new std::vector<T>()), index(index)
35 {}
36
37 vector_property_map(unsigned initial_size,
38 const IndexMap& index = IndexMap())
39 : store(new std::vector<T>(initial_size)), index(index)
40 {}
41
42 typename std::vector<T>::iterator storage_begin()
43 {
44 return store->begin();
45 }
46
47 typename std::vector<T>::iterator storage_end()
48 {
49 return store->end();
50 }
51
52 typename std::vector<T>::const_iterator storage_begin() const
53 {
54 return store->begin();
55 }
56
57 typename std::vector<T>::const_iterator storage_end() const
58 {
59 return store->end();
60 }
61
62 IndexMap& get_index_map() { return index; }
63 const IndexMap& get_index_map() const { return index; }
64
65 public:
66 // Copy ctor absent, default semantics is OK.
67 // Assignment operator absent, default semantics is OK.
68 // CONSIDER: not sure that assignment to 'index' is correct.
69
70 reference operator[](const key_type& v) const {
71 typename property_traits<IndexMap>::value_type i = get(index, v);
72 if (static_cast<unsigned>(i) >= store->size()) {
73 store->resize(i + 1, T());
74 }
75 return (*store)[i];
76 }
77 private:
78 // Conceptually, we have a vector of infinite size. For practical
79 // purposes, we start with an empty vector and grow it as needed.
80 // Note that we cannot store pointer to vector here -- we cannot
81 // store pointer to data, because if copy of property map resizes
82 // the vector, the pointer to data will be invalidated.
83 // I wonder if class 'pmap_ref' is simply needed.
84 shared_ptr< std::vector<T> > store;
85 IndexMap index;
86 };
87
88 template<typename T, typename IndexMap>
89 vector_property_map<T, IndexMap>
90 make_vector_property_map(IndexMap index)
91 {
92 return vector_property_map<T, IndexMap>(index);
93 }
94}
95
96#endif
97