// Copyright (C) 2008 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_STD_VECTOr_C_H_ #define DLIB_STD_VECTOr_C_H_ #include <vector> #include <algorithm> #include "../assert.h" #include "std_vector_c_abstract.h" #include "../serialize.h" #include "../is_kind.h" namespace dlib { template < typename T, typename Allocator = std::allocator<T> > class std_vector_c : public std::vector<T,Allocator> { typedef typename std::vector<T,Allocator> base_type; public: // types: typedef typename Allocator::reference reference; typedef typename Allocator::const_reference const_reference; typedef typename base_type::iterator iterator; // See 23.1 typedef typename base_type::const_iterator const_iterator; // See 23.1 typedef typename base_type::size_type size_type; // See 23.1 typedef typename base_type::difference_type difference_type;// See 23.1 typedef T value_type; typedef Allocator allocator_type; typedef typename Allocator::pointer pointer; typedef typename Allocator::const_pointer const_pointer; typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; // 23.2.4.1 construct/copy/destroy: explicit std_vector_c(const Allocator& alloc= Allocator()) : base_type(alloc) {} explicit std_vector_c(size_type n, const T& value = T(), const Allocator& alloc= Allocator()) : base_type(n, value, alloc) {} template <typename InputIterator> std_vector_c(InputIterator first, InputIterator last, const Allocator& alloc= Allocator()) : base_type(first,last,alloc) {} std_vector_c(const std::vector<T,Allocator>& x) : base_type(x) {} std_vector_c<T,Allocator>& operator=(const std::vector<T,Allocator>& x) { static_cast<base_type&>(*this) = x; return *this; } template <typename InputIterator> void assign(InputIterator first, InputIterator last) { base_type::assign(first,last); } void assign(size_type n, const T& u) { base_type::assign(n,u); } allocator_type get_allocator() const { return base_type::get_allocator(); } // iterators: iterator begin() { return base_type::begin(); } const_iterator begin() const { return base_type::begin(); } iterator end() { return base_type::end(); } const_iterator end() const { return base_type::end(); } reverse_iterator rbegin() { return base_type::rbegin(); } const_reverse_iterator rbegin() const { return base_type::rbegin(); } reverse_iterator rend() { return base_type::rend(); } const_reverse_iterator rend() const { return base_type::rend(); } // 23.2.4.2 capacity: size_type size() const { return base_type::size(); } size_type max_size() const { return base_type::max_size(); } void resize(size_type sz, T c = T()) { base_type::resize(sz,c); } size_type capacity() const { return base_type::capacity(); } bool empty() const { return base_type::empty(); } void reserve(size_type n) { base_type::reserve(n); } // element access: const_reference at(size_type n) const { return base_type::at(n); } reference at(size_type n) { return base_type::at(n); } // 23.2.4.3 modifiers: void push_back(const T& x) { base_type::push_back(x); } void swap(std_vector_c<T,Allocator>& x) { base_type::swap(x); } void clear() { base_type::clear(); } // ------------------------------------------------------ // Things that have preconditions that should be checked. // ------------------------------------------------------ reference operator[]( size_type n ) { DLIB_CASSERT(n < size(), "\treference std_vector_c::operator[](n)" << "\n\tYou have supplied an invalid index" << "\n\tthis: " << this << "\n\tn: " << n << "\n\tsize(): " << size() ); return static_cast<base_type&>(*this)[n]; } // ------------------------------------------------------ const_reference operator[]( size_type n ) const { DLIB_CASSERT(n < size(), "\tconst_reference std_vector_c::operator[](n)" << "\n\tYou have supplied an invalid index" << "\n\tthis: " << this << "\n\tn: " << n << "\n\tsize(): " << size() ); return static_cast<const base_type&>(*this)[n]; } // ------------------------------------------------------ reference front( ) { DLIB_CASSERT(size() > 0, "\treference std_vector_c::front()" << "\n\tYou can't call front() on an empty vector" << "\n\tthis: " << this ); return base_type::front(); } // ------------------------------------------------------ const_reference front( ) const { DLIB_CASSERT(size() > 0, "\tconst_reference std_vector_c::front()" << "\n\tYou can't call front() on an empty vector" << "\n\tthis: " << this ); return base_type::front(); } // ------------------------------------------------------ reference back( ) { DLIB_CASSERT(size() > 0, "\treference std_vector_c::back()" << "\n\tYou can't call back() on an empty vector" << "\n\tthis: " << this ); return base_type::back(); } // ------------------------------------------------------ const_reference back( ) const { DLIB_CASSERT(size() > 0, "\tconst_reference std_vector_c::back()" << "\n\tYou can't call back() on an empty vector" << "\n\tthis: " << this ); return base_type::back(); } // ------------------------------------------------------ void pop_back( ) { DLIB_CASSERT(size() > 0, "\tconst_reference std_vector_c::pop_back()" << "\n\tYou can't call pop_back() on an empty vector" << "\n\tthis: " << this ); base_type::pop_back(); } // ------------------------------------------------------ iterator insert( iterator position, const T& x ) { DLIB_CASSERT( begin() <= position && position <= end(), "\titerator std_vector_c::insert(position,x)" << "\n\tYou have called insert() with an invalid position" << "\n\tthis: " << this ); return base_type::insert(position, x); } // ------------------------------------------------------ void insert( iterator position, size_type n, const T& x ) { DLIB_CASSERT( begin() <= position && position <= end(), "\tvoid std_vector_c::insert(position,n,x)" << "\n\tYou have called insert() with an invalid position" << "\n\tthis: " << this ); base_type::insert(position, n, x); } // ------------------------------------------------------ template <typename InputIterator> void insert( iterator position, InputIterator first, InputIterator last ) { DLIB_CASSERT( begin() <= position && position <= end(), "\tvoid std_vector_c::insert(position,first,last)" << "\n\tYou have called insert() with an invalid position" << "\n\tthis: " << this ); base_type::insert(position, first, last); } // ------------------------------------------------------ iterator erase( iterator position ) { DLIB_CASSERT( begin() <= position && position < end(), "\titerator std_vector_c::erase(position)" << "\n\tYou have called erase() with an invalid position" << "\n\tthis: " << this ); return base_type::erase(position); } // ------------------------------------------------------ iterator erase( iterator first, iterator last ) { DLIB_CASSERT( begin() <= first && first <= last && last <= end(), "\titerator std_vector_c::erase(first,last)" << "\n\tYou have called erase() with an invalid range of iterators" << "\n\tthis: " << this ); return base_type::erase(first,last); } // ------------------------------------------------------ }; // ---------------------------------------------------------------------------------------- // Add these swaps just to make absolutely sure the specialized swap always gets called even // if the compiler is crappy and would otherwise mess it up. template <typename T, typename Allocator> void swap(std_vector_c<T,Allocator>& x, std_vector_c<T,Allocator>& y) { x.swap(y); } template <typename T, typename Allocator> void swap(std::vector<T,Allocator>& x, std_vector_c<T,Allocator>& y) { x.swap(y); } template <typename T, typename Allocator> void swap(std_vector_c<T,Allocator>& x, std::vector<T,Allocator>& y) { y.swap(x); } // ---------------------------------------------------------------------------------------- template <typename T, typename alloc> void serialize ( const std_vector_c<T,alloc>& item, std::ostream& out ) { try { const unsigned long size = static_cast<unsigned long>(item.size()); serialize(size,out); for (unsigned long i = 0; i < item.size(); ++i) serialize(item[i],out); } catch (serialization_error& e) { throw serialization_error(e.info + "\n while serializing object of type std_vector_c"); } } // ---------------------------------------------------------------------------------------- template <typename T, typename alloc> void deserialize ( std_vector_c<T, alloc>& item, std::istream& in ) { try { unsigned long size; deserialize(size,in); item.resize(size); for (unsigned long i = 0; i < size; ++i) deserialize(item[i],in); } catch (serialization_error& e) { throw serialization_error(e.info + "\n while deserializing object of type std_vector_c"); } } // ---------------------------------------------------------------------------------------- template <typename T, typename alloc> struct is_std_vector<std_vector_c<T,alloc> > { const static bool value = true; }; // ---------------------------------------------------------------------------------------- } #endif // DLIB_STD_VECTOr_C_H_