#ifndef VTR_VECTOR #define VTR_VECTOR #include #include #include #include "vtr_range.h" namespace vtr { //A std::vector container which is indexed by K (instead of size_t). // //The main use of this container is to behave like a std::vector which is //indexed by a vtr::StrongId. It assumes that K is explicitly convertable to size_t //(i.e. via operator size_t()), and can be explicitly constructed from a size_t. // //If you need more std::map-like (instead of std::vector-like) behaviour see //vtr::vector_map. template class vector : private std::vector { public: typedef K key_type; class key_iterator; typedef vtr::Range key_range; public: //Pass through std::vector's types using typename std::vector::value_type; using typename std::vector::allocator_type; using typename std::vector::reference; using typename std::vector::const_reference; using typename std::vector::pointer; using typename std::vector::const_pointer; using typename std::vector::iterator; using typename std::vector::const_iterator; using typename std::vector::reverse_iterator; using typename std::vector::const_reverse_iterator; using typename std::vector::difference_type; using typename std::vector::size_type; //Pass through std::vector's methods using std::vector::vector; using std::vector::begin; using std::vector::end; using std::vector::rbegin; using std::vector::rend; using std::vector::cbegin; using std::vector::cend; using std::vector::crbegin; using std::vector::crend; using std::vector::size; using std::vector::max_size; using std::vector::resize; using std::vector::capacity; using std::vector::empty; using std::vector::reserve; using std::vector::shrink_to_fit; using std::vector::front; using std::vector::back; using std::vector::data; using std::vector::assign; using std::vector::push_back; using std::vector::pop_back; using std::vector::insert; using std::vector::erase; using std::vector::swap; using std::vector::clear; using std::vector::emplace; using std::vector::emplace_back; using std::vector::get_allocator; //Don't include operator[] and at() from std::vector, //since we redine them to take key_type instead of size_t reference operator[](const key_type id) { auto i = size_t(id); return std::vector::operator[](i); } const_reference operator[](const key_type id) const { auto i = size_t(id); return std::vector::operator[](i); } reference at(const key_type id) { auto i = size_t(id); return std::vector::at(i); } const_reference at(const key_type id) const { auto i = size_t(id); return std::vector::at(i); } //Returns a range containing the keys key_range keys() const { return vtr::make_range(key_begin(), key_end()); } public: //Iterator class which is convertable to the key_type //This allows end-users to call the parent class's keys() member //to iterate through the keys with a range-based for loop class key_iterator : public std::iterator { public: //We use the intermediate type my_iter to avoid a potential ambiguity for which //clang generates errors and warnings using my_iter = typename std::iterator; using typename my_iter::iterator; using typename my_iter::pointer; using typename my_iter::reference; using typename my_iter::value_type; key_iterator(key_iterator::value_type init) : value_(init) {} //vtr::vector assumes that the key time is convertable to size_t and //that all the underlying IDs are zero-based and contiguous. That means //we can just increment the underlying Id to build the next key. key_iterator operator++() { value_ = value_type(size_t(value_) + 1); return *this; } key_iterator operator--() { value_ = value_type(size_t(value_) - 1); return *this; } reference operator*() { return value_; } pointer operator->() { return &value_; } friend bool operator==(const key_iterator lhs, const key_iterator rhs) { return lhs.value_ == rhs.value_; } friend bool operator!=(const key_iterator lhs, const key_iterator rhs) { return !(lhs == rhs); } private: value_type value_; }; private: key_iterator key_begin() const { return key_iterator(key_type(0)); } key_iterator key_end() const { return key_iterator(key_type(size())); } }; } // namespace vtr #endif