Initial Commit - Lesson 31 (Commit #1)

This commit is contained in:
Norman Lansing
2026-02-24 22:39:26 -05:00
commit 9591e7f503
4631 changed files with 1019212 additions and 0 deletions

View File

@@ -0,0 +1,333 @@
// 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_

View File

@@ -0,0 +1,470 @@
// Copyright (C) 2008 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_STD_VECTOr_C_ABSTRACT_H_
#ifdef DLIB_STD_VECTOr_C_ABSTRACT_H_
#include <vector>
#include <algorithm>
#include "../assert.h"
namespace dlib
{
template <
typename T,
typename Allocator = std::allocator<T>
>
class std_vector_c : public std::vector<T,Allocator>
{
/*!
WHAT THIS OBJECT REPRESENTS
This object is a simple wrapper around the std::vector object. It
provides an identical interface but also checks the preconditions of
each member function. That is, if you violate a requires
clause the dlib::fatal_error exception is thrown.
!*/
typedef typename std::vector<T,Allocator> base_type;
public:
typedef typename Allocator::reference reference;
typedef typename Allocator::const_reference const_reference;
typedef typename base_type::iterator iterator;
typedef typename base_type::const_iterator const_iterator;
typedef typename base_type::size_type size_type;
typedef typename base_type::difference_type difference_type;
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;
explicit std_vector_c(
const Allocator& alloc = Allocator()
);
/*!
ensures
- #get_allocator() == alloc
- #size() == 0
!*/
explicit std_vector_c (
size_type n,
const T& value = T(),
const Allocator& alloc = Allocator()
);
/*!
ensures
- #size() == n
- #get_allocator() == alloc
- for all valid i:
- (*this)[i] == value
!*/
template <typename InputIterator>
std_vector_c (
InputIterator first,
InputIterator last,
const Allocator& alloc = Allocator()
);
/*!
ensures
- #size() == std::distance(first,last)
- #get_allocator() == alloc
- std::equal(first, last, begin()) == true
!*/
std_vector_c(
const std::vector<T,Allocator>& x
);
/*!
ensures
- #*this == x
!*/
std_vector_c<T,Allocator>& operator= (
const std::vector<T,Allocator>& x
);
/*!
ensures
- #*this == x
- returns #*this
!*/
template <typename InputIterator>
void assign(
InputIterator first,
InputIterator last
);
/*!
ensures
- #size() == std::distance(first,last)
- std::equal(first, last, begin()) == true
!*/
void assign(
size_type n,
const T& value
);
/*!
ensures
- #size() == n
- for all valid i:
- (*this)[i] == value
!*/
allocator_type get_allocator(
) const;
/*!
ensures
- returns the allocator used by this vector
!*/
iterator begin(
);
/*!
ensures
- if (size() > 0) then
- returns an iterator referring to the first element in
this container.
- else
- returns end()
!*/
const_iterator begin(
) const;
/*!
ensures
- if (size() > 0) then
- returns a const_iterator referring to the first element in
this container.
- else
- returns end()
!*/
iterator end(
);
/*!
ensures
- returns an iterator that represents one past the end of
this container
!*/
const_iterator end(
) const;
/*!
ensures
- returns an iterator that represents one past the end of
this container
!*/
reverse_iterator rbegin(
);
/*!
ensures
- returns std::reverse_iterator(end())
!*/
const_reverse_iterator rbegin(
) const;
/*!
ensures
- returns std::reverse_iterator(end())
!*/
reverse_iterator rend(
);
/*!
ensures
- returns std::reverse_iterator(begin())
!*/
const_reverse_iterator rend(
) const;
/*!
ensures
- returns std::reverse_iterator(begin())
!*/
size_type size(
) const;
/*!
ensures
- returns end()-begin()
(i.e. returns the number of elements in this container)
!*/
size_type max_size(
) const;
/*!
ensures
- returns the maximum number of elements this vector can contain
!*/
void resize(
size_type sz,
T c = T()
);
/*!
ensures
- #size() == sz
- any element with index between 0 and sz - 1 which was in the
vector before the call to resize() retains its value and index.
All other elements have a value given by c.
!*/
size_type capacity(
) const;
/*!
ensures
- returns the total number of elements that the vector can hold without
requiring reallocation.
!*/
bool empty(
) const;
/*!
ensures
- if (size() == 0) then
- returns true
- else
- returns false
!*/
void reserve(
size_type n
);
/*!
ensures
- #capacity() >= n
!*/
const_reference at(
size_type n
) const;
/*!
ensures
- if (n < size()) then
- returns a const reference to (*this)[n]
- else
- throws std::out_of_range
!*/
reference at(
size_type n
);
/*!
ensures
- if (n < size()) then
- returns a reference to (*this)[n]
- else
- throws std::out_of_range
!*/
void push_back(
const T& x
);
/*!
ensures
- #size() == size() + 1
- #back() == x
!*/
void swap(
std_vector_c<T,Allocator>& x
);
/*!
ensures
- swaps the state of *this and x
!*/
void clear(
);
/*!
ensures
- #size() == 0
!*/
reference operator[](
size_type n
);
/*!
requires
- n < size()
ensures
- returns a reference to the nth element of this container
!*/
const_reference operator[](
size_type n
) const;
/*!
requires
- n < size()
ensures
- returns a const reference to the nth element of this container
!*/
reference front(
);
/*!
requires
- size() > 0
ensures
- returns a reference to (*this)[0]
!*/
const_reference front(
) const;
/*!
requires
- size() > 0
ensures
- returns a const reference to (*this)[0]
!*/
reference back(
);
/*!
requires
- size() > 0
ensures
- returns a reference to (*this)[size()-1]
!*/
const_reference back(
) const;
/*!
requires
- size() > 0
ensures
- returns a const reference to (*this)[size()-1]
!*/
void pop_back(
);
/*!
requires
- size() > 0
ensures
- #size() == size() - 1
- removes the last element in the vector but leaves the others
unmodified.
!*/
iterator insert(
iterator position,
const T& x
);
/*!
requires
- begin() <= position && position <= end()
(i.e. position references an element in this vector object)
ensures
- #size() == size() + 1
- inserts a copy of x into *this before the given position
- returns an iterator that points to the copy of x inserted
into *this
!*/
void insert(
iterator position,
size_type n,
const T& x
);
/*!
requires
- begin() <= position && position <= end()
(i.e. position references an element in this vector object)
ensures
- #size() == size() + n
- inserts n copies of x into *this before the given position
!*/
template <typename InputIterator>
void insert(
iterator position,
InputIterator first,
InputIterator last
);
/*!
requires
- begin() <= position && position <= end()
(i.e. position references an element in this vector object)
- first and last are not iterators into *this
ensures
- #size() == size() + std::distance(last,first)
- inserts copies of the range of elements [first,last) into *this
before the given position
!*/
iterator erase(
iterator position
);
/*!
requires
- begin() <= position && position < end()
(i.e. position references an element in this vector object)
ensures
- #size() == size() - 1
- removes the element in this vector referenced by position but
leaves all other elements in this vector unmodified.
- if (position < end()-1) then
- returns an iterator referencing the element immediately
following *position prior to the erase.
- else
- returns end()
!*/
iterator erase(
iterator first,
iterator last
);
/*!
requires
- begin() <= first && first <= last && last <= end()
(i.e. the range [first,last) must be inside this container )
ensures
- #size() == size() - (last-first)
- removes the elements in this vector referenced by the
iterator range [first,last) but leaves all other elements
in this vector unmodified.
- if (last < end()-1) then
- returns an iterator referencing the element immediately
following *last prior to the erase.
- else
- returns end()
!*/
};
// ----------------------------------------------------------------------------------------
template <typename T, typename alloc>
void serialize (
const std_vector_c<T,alloc>& item,
std::ostream& out
);
/*!
provides serialization support
!*/
// ----------------------------------------------------------------------------------------
template <typename T, typename alloc>
void deserialize (
std_vector_c<T, alloc>& item,
std::istream& in
);
/*!
provides deserialization support
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_STD_VECTOr_C_ABSTRACT_H_