// graph-tool -- a general graph modification and manipulation thingy // // Copyright (C) 2007-2012 Tiago de Paula Peixoto // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 3 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // Copyright (C) Vladimir Prus 2003. // Distributed under 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) // // See http://www.boost.org/libs/graph/vector_property_map.html for // documentation. // // // This is a modification of boost's vector property map which optionally // disables bound checking for better performance. // #ifndef FAST_VECTOR_PROPERTY_MAP_HH #define FAST_VECTOR_PROPERTY_MAP_HH #include #if (BOOST_VERSION >= 104000) # include #else # include #endif #include #include namespace boost { template class unchecked_vector_property_map; template class checked_vector_property_map : public boost::put_get_helper< typename std::iterator_traits< typename std::vector::iterator >::reference, checked_vector_property_map > { public: typedef typename property_traits::key_type key_type; typedef T value_type; typedef typename std::iterator_traits< typename std::vector::iterator >::reference reference; typedef boost::lvalue_property_map_tag category; template friend class unchecked_vector_property_map; typedef unchecked_vector_property_map unchecked_t; typedef IndexMap index_map_t; typedef checked_vector_property_map self_t; checked_vector_property_map(const IndexMap& index = IndexMap()) : store(new std::vector()), index(index) {} checked_vector_property_map(unsigned initial_size, const IndexMap& index = IndexMap()) : store(new std::vector(initial_size)), index(index) {} checked_vector_property_map(const unchecked_t& map) : checked_vector_property_map(map.get_checked()) {} typename std::vector::iterator storage_begin() { return store->begin(); } typename std::vector::iterator storage_end() { return store->end(); } typename std::vector::const_iterator storage_begin() const { return store->begin(); } typename std::vector::const_iterator storage_end() const { return store->end(); } void reserve(size_t size) const { #pragma omp critical if (store->size() < size) store->resize(size); } std::vector& get_storage() const { return (*store); } unchecked_t get_unchecked(size_t size = 0) const { reserve(size); return unchecked_t(*this, size); } public: // Copy ctor absent, default semantics is OK. // Assignment operator absent, default semantics is OK. // CONSIDER: not sure that assignment to 'index' is correct. reference operator[](const key_type& v) const { typename property_traits::value_type i = get(index, v); if (static_cast(i) >= store->size()) { store->resize(i + 1, T()); } return (*store)[i]; } protected: // Conceptually, we have a vector of infinite size. For practical // purposes, we start with an empty vector and grow it as needed. // Note that we cannot store pointer to vector here -- we cannot // store pointer to data, because if copy of property map resizes // the vector, the pointer to data will be invalidated. // I wonder if class 'pmap_ref' is simply needed. shared_ptr< std::vector > store; IndexMap index; }; template class unchecked_vector_property_map : public boost::put_get_helper< typename std::iterator_traits< typename std::vector::iterator >::reference, unchecked_vector_property_map > { public: typedef typename property_traits::key_type key_type; typedef T value_type; typedef typename std::iterator_traits< typename std::vector::iterator >::reference reference; typedef boost::lvalue_property_map_tag category; typedef checked_vector_property_map checked_t; unchecked_vector_property_map(const checked_t& checked = checked_t(), size_t size = 0) : _checked(checked) { if (size > 0 && _checked.store->size() < size) _checked.store->resize(size); } unchecked_vector_property_map(const IndexMap& index_map, size_t size = 0) { *this = unchecked_vector_property_map(checked_t(index_map), size); } void reserve(size_t size) const { _checked.reserve(size); } reference operator[](const key_type& v) const { typename property_traits::value_type i = get(_checked.index, v); return (*_checked.store)[i]; } std::vector& get_storage() const { return _checked.get_storage(); } checked_t get_checked() {return _checked;} private: checked_t _checked; }; template checked_vector_property_map make_checked_vector_property_map(IndexMap index) { return checked_vector_property_map(index); } template unchecked_vector_property_map make_unchecked_vector_property_map(IndexMap index) { return unchecked_vector_property_map(index); } } #endif