// Copyright {Jagger Software Limited} 2003 #ifndef CONTAINER_BOUNDED_VECTOR_INCLUDED #define CONTAINER_BOUNDED_VECTOR_INCLUDED #include #include #include namespace container { template class bounded_vector { public: // types typedef bounded_vector self_type; typedef size_t size_type; typedef element_type * iterator; typedef const element_type * const_iterator; typedef std::reverse_iterator< iterator> reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef element_type & reference; typedef const element_type & const_reference; public: // 'tors explicit bounded_vector(int fixed_capacity); explicit bounded_vector(size_t fixed_capacity); template bounded_vector(forward_iterator from, forward_iterator until) : fixed_capacity(std::distance(from, until)) , used_length(0) , elements(allocate(fixed_capacity)) { std::copy(from, until, std::back_inserter(*this)); } template explicit bounded_vector(const container_type & seq) : fixed_capacity(seq.size()) , used_length(0) , elements(allocate(fixed_capacity)) { std::copy(seq.begin(), seq.end(), std::back_inserter(*this)); } bounded_vector(const self_type &); ~bounded_vector(); public: // assignment self_type & operator=(const self_type &); public: // capacity size_t size() const; size_t max_size() const; size_t capacity() const; bool empty() const; bool full() const; void clear(); void swap(self_type &); public: // traversal iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; reverse_iterator rbegin(); const_reverse_iterator rbegin() const; reverse_iterator rend(); const_reverse_iterator rend() const; public: // end element access reference front(); const_reference front() const; reference back(); const_reference back() const; void push_back(const_reference); void pop_back(); public: // subscripting reference operator[](size_t); const_reference operator[](size_t) const; private: // implementation static element_type * allocate(size_t); static void deallocate(element_type *); private: // validation void check_not_empty() const; void check_not_full() const; void range_check(size_t) const; private: // state size_t fixed_capacity; // order dependency size_t used_length; // [0..fixed_capacity) element_type * elements; // never null }; } #include "container/bounded_vector-template.hpp" #endif #if 0 //--------------------------------------------------------------- // Notes /* * bounded_vector<> is for C++ problems that cry out for * the ability to create dynamic, initialised, arrays. In other, * words, something like this (which is clearly not allowed * in C/C++, although it is in C#, Java, etc). * * int * const nos = new int[]{ 1, 2, 3 }; * * Instead you can write this... * * bounded_vector nos(3); * nos.push_back(1); * nos.push_back(2); * nos.push_back(3); * * or this... * * bounded_vector eg2(3); * copy(nos.begin(), nos.end(), back_inserter(eg2)); * * or this... * * bounded_vector eg3(nos.begin(), nos.end()); * * bounded_vector knows it's own size/capacity, which a * raw C/C++ array pointer does not. * * the max_size() is always the same as capacity() * * If full() then push_back() will throw an std::logic_error. * This means that a bounded_vector will never do an * internal reallocation so it never invalidates any pointers * or iterators. * * The constructor taking a single int (as opposed to a size_t) * argument is there so that a declaration such as: * * bounded_vector table(42); * * does not instantiate the container_type constructor (since 42 is * an int). */ //--------------------------------------------------------------- // Example of use #endif