// Copyright {Jagger Software Limited} 2003 #if !defined CONTAINER_BOUNDED_VECTOR_INCLUDED || \ defined CONTAINER_BOUNDED_VECTOR_TEMPLATE_INCLUDED #error "container/bounded_vector-template.hpp" #included directly #endif #define CONTAINER_BOUNDED_VECTOR_TEMPLATE_INCLUDED #include "container/construct.hpp" #include "container/destruct.hpp" #include namespace { size_t positive(int value) { if (value < 0) { throw std::logic_error("container::bounded_vector::c'tor(arg1 < zero)"); } return static_cast(value); } } namespace container // bounded_vector - 'tors { using namespace std; template bounded_vector::bounded_vector(int value) : fixed_capacity(positive(value)) , used_length(0) , elements(allocate(fixed_capacity)) { } template bounded_vector::bounded_vector(size_t value) : fixed_capacity(value) , used_length(0) , elements(allocate(fixed_capacity)) { } template bounded_vector::bounded_vector(const self_type & other) : fixed_capacity(other.fixed_capacity) , used_length(0) , elements(bounded) { copy(other.begin(), other.end(), back_inserter(*this)); } template bounded_vector::~bounded_vector() { clear(); deallocate(elements); } } namespace container // bounded_vector - assignment { template bounded_vector & bounded_vector::operator=(const self_type & rhs) { self_type(rhs).swap(*this); return *this; } } namespace container // bounded_vector - capacity { template size_t bounded_vector::size() const { return used_length; } template size_t bounded_vector::max_size() const { return capacity(); } template size_t bounded_vector::capacity() const { return fixed_capacity; } template bool bounded_vector::empty() const { return size() == 0; } template bool bounded_vector::full() const { return size() == capacity(); } template void bounded_vector::clear() { while (!empty()) { pop_back(); } } template void bounded_vector::swap(self_type & other) { ::swap(fixed_capacity, other.fixed_capacity); ::swap(used_length, other.used_length); ::swap(elements, other.elements); } } namespace container // bounded_vector - iteration { template typename bounded_vector::iterator bounded_vector::begin() { return elements; } template typename bounded_vector::iterator bounded_vector::end() { return elements + size(); } template typename bounded_vector::const_iterator bounded_vector::begin() const { return elements; } template typename bounded_vector::const_iterator bounded_vector::end() const { return elements + size(); } } namespace container // bounded_vector - reverse iteration { template typename bounded_vector::reverse_iterator bounded_vector::rbegin() { return reverse_iterator(end()); } template typename bounded_vector::reverse_iterator bounded_vector::rend() { return reverse_iterator(begin()); } template typename bounded_vector::const_reverse_iterator bounded_vector::rbegin() const { return const_reverse_iterator(end()); } template typename bounded_vector::const_reverse_iterator bounded_vector::rend() const { return const_reverse_iterator(begin()); } } namespace container // bounded_vector - end element access { template element_type & bounded_vector::front() { check_not_empty(); return *begin(); } template element_type & bounded_vector::back() { check_not_empty(); return *(end() - 1); } template const element_type & bounded_vector::front() const { check_not_empty(); return *begin(); } template const element_type & bounded_vector::back() const { check_not_empty(); return *(end() - 1); } template void bounded_vector::push_back(const element_type & pushed) { check_not_full(); construct(&elements[used_length], pushed); ++used_length; } template void bounded_vector::pop_back() { check_not_empty(); --used_length; destruct(&elements[used_length]); } } namespace container // bounded_vector - subscripting { template element_type & bounded_vector::operator[](size_t at) { range_check(at); return elements[at]; } template const element_type & bounded_vector::operator[](size_t at) const { range_check(at); return elements[at]; } } namespace container // bounded_vector - validation { template void bounded_vector::check_not_empty() const { if (empty()) { throw std::logic_error("container::bounded_vector::empty()"); } } template void bounded_vector::check_not_full() const { if (full()) { throw std::logic_error("container::bounded_vector::full()"); } } template void bounded_vector::range_check(size_t at) const { if (at >= size()) { throw std::out_of_range("container::bounded_vector[at]"); } } } namespace container // bounded_vector - implementation { template element_type * bounded_vector::allocate(size_t amount) { void * const block = ::operator new(amount * sizeof(element_type)); return static_cast(block); } template void bounded_vector::deallocate(element_type * ptr) { void * const block = static_cast(ptr); ::operator delete(block); } }