You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
334 lines
12 KiB
C++
334 lines
12 KiB
C++
// 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_
|
|
|