Initial Commit - Lesson 31 (Commit #1)
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
// Copyright (C) 2012 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_CIRCULAR_BuFFER_Hh_
|
||||
#define DLIB_CIRCULAR_BuFFER_Hh_
|
||||
|
||||
#include "circular_buffer_abstract.h"
|
||||
#include <vector>
|
||||
#include "../algs.h"
|
||||
#include "../serialize.h"
|
||||
#include "../matrix/matrix_mat.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class circular_buffer
|
||||
{
|
||||
public:
|
||||
typedef default_memory_manager mem_manager_type;
|
||||
typedef T value_type;
|
||||
typedef T type;
|
||||
|
||||
circular_buffer()
|
||||
{
|
||||
}
|
||||
|
||||
explicit circular_buffer(unsigned long s)
|
||||
{
|
||||
resize(s);
|
||||
}
|
||||
|
||||
void clear (
|
||||
)
|
||||
{
|
||||
offset = 0;
|
||||
data.clear();
|
||||
}
|
||||
|
||||
T& operator[] ( unsigned long i)
|
||||
{
|
||||
DLIB_ASSERT(i < size(),
|
||||
"\t T& circular_buffer::operator[](i)"
|
||||
<< "\n\t You have supplied an invalid index"
|
||||
<< "\n\t this: " << this
|
||||
<< "\n\t i: " << i
|
||||
<< "\n\t size(): " << size()
|
||||
);
|
||||
return data[(i+offset)%data.size()];
|
||||
}
|
||||
|
||||
const T& operator[] ( unsigned long i) const
|
||||
{
|
||||
DLIB_ASSERT(i < size(),
|
||||
"\t const T& circular_buffer::operator[](i)"
|
||||
<< "\n\t You have supplied an invalid index"
|
||||
<< "\n\t this: " << this
|
||||
<< "\n\t i: " << i
|
||||
<< "\n\t size(): " << size()
|
||||
);
|
||||
return data[(i+offset)%data.size()];
|
||||
}
|
||||
|
||||
void resize(unsigned long size)
|
||||
{
|
||||
offset = 0;
|
||||
data.resize(size);
|
||||
}
|
||||
|
||||
void assign(
|
||||
unsigned long size,
|
||||
const T& value
|
||||
)
|
||||
{
|
||||
offset = 0;
|
||||
data.assign(size,value);
|
||||
}
|
||||
|
||||
unsigned long size() const { return data.size(); }
|
||||
|
||||
void push_front(const T& value)
|
||||
{
|
||||
if (data.size() != 0)
|
||||
{
|
||||
offset = (offset - 1 + data.size())%data.size();
|
||||
data[offset] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void push_back(const T& value)
|
||||
{
|
||||
if (data.size() != 0)
|
||||
{
|
||||
data[offset] = value;
|
||||
offset = (offset + 1 + data.size())%data.size();
|
||||
}
|
||||
}
|
||||
|
||||
T& front(
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(size() > 0,
|
||||
"\t T& circular_buffer::front()"
|
||||
<< "\n\t You can't call front() on an empty circular_buffer"
|
||||
<< "\n\t this: " << this
|
||||
);
|
||||
return (*this)[0];
|
||||
}
|
||||
|
||||
const T& front(
|
||||
) const
|
||||
{
|
||||
DLIB_CASSERT(size() > 0,
|
||||
"\t const T& circular_buffer::front()"
|
||||
<< "\n\t You can't call front() on an empty circular_buffer"
|
||||
<< "\n\t this: " << this
|
||||
);
|
||||
return (*this)[0];
|
||||
}
|
||||
|
||||
T& back(
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(size() > 0,
|
||||
"\t T& circular_buffer::back()"
|
||||
<< "\n\t You can't call back() on an empty circular_buffer"
|
||||
<< "\n\t this: " << this
|
||||
);
|
||||
return (*this)[size()-1];
|
||||
}
|
||||
|
||||
const T& back(
|
||||
) const
|
||||
{
|
||||
DLIB_CASSERT(size() > 0,
|
||||
"\t const T& circular_buffer::back()"
|
||||
<< "\n\t You can't call back() on an empty circular_buffer"
|
||||
<< "\n\t this: " << this
|
||||
);
|
||||
return (*this)[size()-1];
|
||||
}
|
||||
|
||||
void swap( circular_buffer& item)
|
||||
{
|
||||
std::swap(item.offset, offset);
|
||||
data.swap(item.data);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::vector<T> data;
|
||||
|
||||
unsigned long offset = 0;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void swap (
|
||||
circular_buffer<T>& a,
|
||||
circular_buffer<T>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void serialize (
|
||||
const circular_buffer<T>& item,
|
||||
std::ostream& out
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
serialize(item.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 circular_buffer");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void deserialize (
|
||||
circular_buffer<T>& 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)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type circular_buffer");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
const matrix_op<op_array_to_mat<circular_buffer<T> > > mat (
|
||||
const circular_buffer<T>& m
|
||||
)
|
||||
{
|
||||
typedef op_array_to_mat<circular_buffer<T> > op;
|
||||
return matrix_op<op>(op(m));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_CIRCULAR_BuFFER_Hh_
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
// Copyright (C) 2012 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_CIRCULAR_BuFFER_ABSTRACT_Hh_
|
||||
#ifdef DLIB_CIRCULAR_BuFFER_ABSTRACT_Hh_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "../serialize.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class circular_buffer
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T must have a default constructor and be copyable.
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
swap(), size(), front(), back(), and operator[] functions do
|
||||
not invalidate pointers or references to internal data.
|
||||
All other functions have no such guarantee.
|
||||
|
||||
INITIAL VALUE
|
||||
- size() == 0
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object is a circular buffer of objects of type T. This means
|
||||
that when objects are pushed onto one of its ends it does not grow
|
||||
in size. Instead, it shifts all elements over one to make room for
|
||||
the new element and the element at the opposing end falls off the
|
||||
buffer and is lost.
|
||||
!*/
|
||||
|
||||
public:
|
||||
typedef default_memory_manager mem_manager_type;
|
||||
typedef T value_type;
|
||||
typedef T type;
|
||||
|
||||
circular_buffer(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #size() == 0
|
||||
- this object is properly initialized
|
||||
!*/
|
||||
|
||||
explicit circular_buffer(
|
||||
unsigned long s
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #size() == s
|
||||
- this object is properly initialized
|
||||
!*/
|
||||
|
||||
void clear (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- this object has its initial value
|
||||
- #size() == 0
|
||||
!*/
|
||||
|
||||
T& operator[] (
|
||||
unsigned long i
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- i < size()
|
||||
ensures
|
||||
- returns a non-const reference to the i-th element of this circular buffer
|
||||
!*/
|
||||
|
||||
const T& operator[] (
|
||||
unsigned long i
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- i < size()
|
||||
ensures
|
||||
- returns a const reference to the i-th element of this circular buffer
|
||||
!*/
|
||||
|
||||
void resize(
|
||||
unsigned long new_size
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #size() == new_size
|
||||
!*/
|
||||
|
||||
void assign(
|
||||
unsigned long new_size,
|
||||
const T& value
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #size() == new_size
|
||||
- for all valid i:
|
||||
- (*this)[i] == value
|
||||
!*/
|
||||
|
||||
unsigned long size(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of elements in this circular buffer
|
||||
!*/
|
||||
|
||||
T& front(
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- size() > 0
|
||||
ensures
|
||||
- returns a reference to (*this)[0]
|
||||
!*/
|
||||
|
||||
const T& front(
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- size() > 0
|
||||
ensures
|
||||
- returns a const reference to (*this)[0]
|
||||
!*/
|
||||
|
||||
T& back(
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- size() > 0
|
||||
ensures
|
||||
- returns a reference to (*this)[size()-1]
|
||||
!*/
|
||||
|
||||
const T& back(
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- size() > 0
|
||||
ensures
|
||||
- returns a const reference to (*this)[size()-1]
|
||||
!*/
|
||||
|
||||
void push_front(
|
||||
const T& value
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #size() == size()
|
||||
(i.e. the size of this object does not change)
|
||||
- if (size() != 0) then
|
||||
- #front() == value
|
||||
- all items are shifted over such that,
|
||||
- #(*this)[1] == (*this)[0]
|
||||
- #(*this)[2] == (*this)[1]
|
||||
- #(*this)[3] == (*this)[2]
|
||||
- etc.
|
||||
- back() is shifted out of the circular buffer
|
||||
- else
|
||||
- This function has no effect on this object
|
||||
!*/
|
||||
|
||||
void push_back(
|
||||
const T& value
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #size() == size()
|
||||
(i.e. the size of this object does not change)
|
||||
- if (size() != 0) then
|
||||
- #back() == value
|
||||
- all items are shifted over such that,
|
||||
- front() is shifted out of the circular buffer
|
||||
- #(*this)[0] == (*this)[1]
|
||||
- #(*this)[1] == (*this)[2]
|
||||
- #(*this)[2] == (*this)[3]
|
||||
- etc.
|
||||
- else
|
||||
- This function has no effect on this object
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
circular_buffer& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this with item
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void swap (
|
||||
circular_buffer<T>& a,
|
||||
circular_buffer<T>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void serialize (
|
||||
const circular_buffer<T>& item,
|
||||
std::ostream& out
|
||||
);
|
||||
/*!
|
||||
provides serialization support
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void deserialize (
|
||||
circular_buffer<T>& item,
|
||||
std::istream& in
|
||||
);
|
||||
/*!
|
||||
provides deserialization support
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
const matrix_exp mat (
|
||||
const circular_buffer<T>& m
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns a matrix R such that:
|
||||
- is_col_vector(R) == true
|
||||
- R.size() == m.size()
|
||||
- for all valid r:
|
||||
R(r) == m[r]
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_CIRCULAR_BuFFER_ABSTRACT_Hh_
|
||||
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SLIDING_BUFFER_KERNEl_1_
|
||||
#define DLIB_SLIDING_BUFFER_KERNEl_1_
|
||||
|
||||
#include "sliding_buffer_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../serialize.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class sliding_buffer_kernel_1 : public enumerable<T>
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
- buffer_size == 0
|
||||
- buffer == 0
|
||||
- buffer_start == 0
|
||||
- current == 0
|
||||
- at_start_ == true
|
||||
|
||||
CONVENTION
|
||||
- buffer_size == size()
|
||||
|
||||
- element() == (*this)[current]
|
||||
- current_element_valid() == (current < buffer_size) && at_start_ == false
|
||||
- at_start() == at_start_
|
||||
|
||||
- if (buffer_size != 0) then
|
||||
- buffer[(buffer_start+i)&(mask)] == operator[](i)
|
||||
- mask == buffer_size-1
|
||||
- else
|
||||
- buffer == 0
|
||||
- buffer_size == 0
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
|
||||
sliding_buffer_kernel_1 (
|
||||
) :
|
||||
buffer_start(0),
|
||||
buffer_size(0),
|
||||
buffer(0),
|
||||
current(0),
|
||||
at_start_(true)
|
||||
{}
|
||||
|
||||
virtual ~sliding_buffer_kernel_1 (
|
||||
) { if (buffer) delete [] buffer; }
|
||||
|
||||
void clear(
|
||||
)
|
||||
{
|
||||
buffer_size = 0;
|
||||
if (buffer) delete [] buffer;
|
||||
buffer = 0;
|
||||
at_start_ = true;
|
||||
current = 0;
|
||||
}
|
||||
|
||||
void set_size (
|
||||
unsigned long exp_size
|
||||
)
|
||||
{
|
||||
at_start_ = true;
|
||||
if (buffer) delete [] buffer;
|
||||
buffer_size = 1;
|
||||
while (exp_size != 0)
|
||||
{
|
||||
--exp_size;
|
||||
buffer_size <<= 1;
|
||||
}
|
||||
mask = buffer_size-1;
|
||||
try { buffer = new T[buffer_size]; }
|
||||
catch (...) { buffer = 0; buffer_size = 0; throw; }
|
||||
}
|
||||
|
||||
size_t size (
|
||||
) const { return buffer_size; }
|
||||
|
||||
void rotate_left (
|
||||
unsigned long amount
|
||||
) { buffer_start = ((buffer_start-amount)&mask); at_start_ = true; }
|
||||
|
||||
void rotate_right (
|
||||
unsigned long amount
|
||||
) { buffer_start = ((buffer_start+amount)&mask); at_start_ = true;}
|
||||
|
||||
const T& operator[] (
|
||||
unsigned long index
|
||||
) const { return buffer[(buffer_start+index)&mask]; }
|
||||
|
||||
T& operator[] (
|
||||
unsigned long index
|
||||
) { return buffer[(buffer_start+index)&mask]; }
|
||||
|
||||
unsigned long get_element_id(
|
||||
unsigned long index
|
||||
) const { return ((buffer_start+index)&mask); }
|
||||
|
||||
unsigned long get_element_index (
|
||||
unsigned long element_id
|
||||
) const { return ((element_id-buffer_start)&mask);}
|
||||
|
||||
void swap (
|
||||
sliding_buffer_kernel_1<T>& item
|
||||
)
|
||||
{
|
||||
exchange(buffer_start,item.buffer_start);
|
||||
exchange(buffer_size,item.buffer_size);
|
||||
exchange(buffer,item.buffer);
|
||||
exchange(mask,item.mask);
|
||||
exchange(current,item.current);
|
||||
exchange(at_start_,item.at_start_);
|
||||
}
|
||||
|
||||
|
||||
bool at_start (
|
||||
) const { return at_start_; }
|
||||
|
||||
void reset (
|
||||
) const { at_start_ = true; }
|
||||
|
||||
bool current_element_valid (
|
||||
) const { return (current < buffer_size) && (at_start_ == false); }
|
||||
|
||||
const T& element (
|
||||
) const { return (*this)[current]; }
|
||||
|
||||
T& element (
|
||||
) { return (*this)[current]; }
|
||||
|
||||
bool move_next (
|
||||
) const
|
||||
{
|
||||
if (at_start_ == false)
|
||||
{
|
||||
if (current+1 < buffer_size)
|
||||
{
|
||||
++current;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = buffer_size;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
at_start_ = false;
|
||||
current = 0;
|
||||
return (buffer_size != 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// data members
|
||||
unsigned long buffer_start;
|
||||
unsigned long buffer_size;
|
||||
T* buffer;
|
||||
unsigned long mask;
|
||||
|
||||
|
||||
mutable unsigned long current;
|
||||
mutable bool at_start_;
|
||||
|
||||
// restricted functions
|
||||
sliding_buffer_kernel_1(sliding_buffer_kernel_1<T>&); // copy constructor
|
||||
sliding_buffer_kernel_1<T>& operator=(sliding_buffer_kernel_1<T>&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
inline void swap (
|
||||
sliding_buffer_kernel_1<T>& a,
|
||||
sliding_buffer_kernel_1<T>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void deserialize (
|
||||
sliding_buffer_kernel_1<T>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.clear();
|
||||
unsigned long size;
|
||||
deserialize(size,in);
|
||||
if (size > 0)
|
||||
{
|
||||
int count = 0;
|
||||
while (size != 1)
|
||||
{
|
||||
size /= 2;
|
||||
++count;
|
||||
}
|
||||
item.set_size(count);
|
||||
|
||||
for (unsigned long i = 0; i < item.size(); ++i)
|
||||
deserialize(item[i],in);
|
||||
}
|
||||
}
|
||||
catch (serialization_error& e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type sliding_buffer_kernel_1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DLIB_SLIDING_BUFFER_KERNEl_1_
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_SLIDING_BUFFER_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_SLIDING_BUFFER_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../serialize.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class sliding_buffer : public enumerable<T>
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T must have a default constructor
|
||||
|
||||
INITIAL VALUE
|
||||
size() == 0
|
||||
|
||||
ENUMERATION ORDER
|
||||
The enumerator will iterate over the elements of the sliding_buffer in the
|
||||
order (*this)[0], (*this)[1], (*this)[2], ...
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents an array of T objects. The main
|
||||
feature of this object is its ability to rotate its contents
|
||||
left or right. An example will make it clear.
|
||||
|
||||
suppose we have the following buffer (assuming T is a char):
|
||||
"some data!" <-- the data in the buffer
|
||||
9876543210 <-- the index numbers associated with each character
|
||||
|
||||
applying rotate_left(2) to this buffer would give us
|
||||
"me data!so"
|
||||
9876543210
|
||||
|
||||
if instead of calling rotate_left we call rotate_right(3) instead we would have
|
||||
"ta!some da"
|
||||
9876543210
|
||||
|
||||
Also note that unless specified otherwise, no member functions
|
||||
of this object throw exceptions.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
|
||||
sliding_buffer (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
!*/
|
||||
|
||||
virtual ~sliding_buffer (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- any resources associated with *this have been released
|
||||
!*/
|
||||
|
||||
void clear(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this has its initial value
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
if this exception is thrown then #*this is unusable
|
||||
until clear() is called and succeeds
|
||||
!*/
|
||||
|
||||
void set_size (
|
||||
unsigned long exp_size
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- 0 < exp_size < 32
|
||||
ensures
|
||||
- #size() == 2^exp_size
|
||||
- the value of all elements in the buffer are undefined
|
||||
- #at_start() == true
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
if this exception is thrown then #size() == 0
|
||||
!*/
|
||||
|
||||
void rotate_left (
|
||||
unsigned long amount
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all i where 0 <= i < size():
|
||||
(#*this)[i] == (*this)[(i-amount)&(size()-1)]
|
||||
i.e. rotates the contents of *this left by amount spaces
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
void rotate_right (
|
||||
unsigned long amount
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all i where 0 <= i < size():
|
||||
(#*this)[i] == (*this)[(i+amount)&(size()-1)]
|
||||
i.e. rotates the contents of *this right by amount spaces
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
unsigned long get_element_id (
|
||||
unsigned long index
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- index < size()
|
||||
ensures
|
||||
- returns an element id number that uniquely references the element at
|
||||
the given index. (you can use this id to locate the new position of
|
||||
an element after the buffer has been rotated)
|
||||
- returned value is < size()
|
||||
!*/
|
||||
|
||||
unsigned long get_element_index (
|
||||
unsigned long element_id
|
||||
) const;
|
||||
/*!
|
||||
require
|
||||
- element_id < size()
|
||||
ensures
|
||||
- returns the index of the element with the given element_id.
|
||||
( (*this)[get_element_index(element_id)] will always refer to the same element
|
||||
no matter where it has been rotated to)
|
||||
- returned value is < size()
|
||||
!*/
|
||||
|
||||
const T& operator[] (
|
||||
unsigned long index
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- index < size()
|
||||
ensures
|
||||
- returns a const reference to the element in *this at position index
|
||||
!*/
|
||||
|
||||
T& operator[] (
|
||||
unsigned long index
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- index < size()
|
||||
ensures
|
||||
- returns a reference to the element in *this at position index
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
sliding_buffer<T>& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
sliding_buffer(sliding_buffer<T>&); // copy constructor
|
||||
sliding_buffer<T>& operator=(sliding_buffer<T>&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void swap (
|
||||
sliding_buffer<T>& a,
|
||||
sliding_buffer<T>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void deserialize (
|
||||
sliding_buffer<T>& item,
|
||||
std::istream& in
|
||||
);
|
||||
/*!
|
||||
provides deserialization support
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SLIDING_BUFFER_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SLIDING_BUFFER_KERNEl_C_
|
||||
#define DLIB_SLIDING_BUFFER_KERNEl_C_
|
||||
|
||||
#include "sliding_buffer_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../assert.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename sb_base
|
||||
>
|
||||
class sliding_buffer_kernel_c : public sb_base
|
||||
{
|
||||
typedef typename sb_base::type T;
|
||||
|
||||
public:
|
||||
void set_size (
|
||||
unsigned long exp_size
|
||||
);
|
||||
|
||||
const T& operator[] (
|
||||
unsigned long index
|
||||
) const;
|
||||
|
||||
T& operator[] (
|
||||
unsigned long index
|
||||
);
|
||||
|
||||
unsigned long get_element_id (
|
||||
unsigned long index
|
||||
) const;
|
||||
|
||||
unsigned long get_element_index (
|
||||
unsigned long element_id
|
||||
) const;
|
||||
|
||||
const T& element (
|
||||
) const;
|
||||
|
||||
T& element (
|
||||
);
|
||||
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename sb_base
|
||||
>
|
||||
inline void swap (
|
||||
sliding_buffer_kernel_c<sb_base>& a,
|
||||
sliding_buffer_kernel_c<sb_base>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename sb_base
|
||||
>
|
||||
void sliding_buffer_kernel_c<sb_base>::
|
||||
set_size (
|
||||
unsigned long exp_size
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( 0 < exp_size && exp_size < 32,
|
||||
"\tvoid sliding_buffer::set_size(unsigned long)"
|
||||
<< "\n\texp_size must be some number between 1 and 31"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\texp_size: " << exp_size
|
||||
);
|
||||
|
||||
// call the real function
|
||||
sb_base::set_size(exp_size);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename sb_base
|
||||
>
|
||||
unsigned long sliding_buffer_kernel_c<sb_base>::
|
||||
get_element_id (
|
||||
unsigned long index
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( index < this->size(),
|
||||
"\tunsigned long sliding_buffer::get_element_id(unsigned long) const"
|
||||
<< "\n\tindex must be in the range 0 to size()-1"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tindex: " << index
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return sb_base::get_element_id(index);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename sb_base
|
||||
>
|
||||
unsigned long sliding_buffer_kernel_c<sb_base>::
|
||||
get_element_index (
|
||||
unsigned long element_id
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( element_id < this->size(),
|
||||
"\tunsigned long sliding_buffer::get_element_index(unsigned long) const"
|
||||
<< "\n\tid must be in the range 0 to size()-1"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tid: " << element_id
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return sb_base::get_element_index(element_id);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename sb_base
|
||||
>
|
||||
const typename sb_base::type& sliding_buffer_kernel_c<sb_base>::
|
||||
operator[] (
|
||||
unsigned long index
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( index < this->size(),
|
||||
"\tconst T& sliding_buffer::operator[](unsigned long) const"
|
||||
<< "\n\tindex must be in the range 0 to size()-1"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tindex: " << index
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return sb_base::operator[](index);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename sb_base
|
||||
>
|
||||
typename sb_base::type& sliding_buffer_kernel_c<sb_base>::
|
||||
operator[] (
|
||||
unsigned long index
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( index < this->size(),
|
||||
"\tT& sliding_buffer::operator[](unsigned long)"
|
||||
<< "\n\tindex must be in the range 0 to size()-1"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tindex: " << index
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return sb_base::operator[](index);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename sb_base
|
||||
>
|
||||
const typename sb_base::type& sliding_buffer_kernel_c<sb_base>::
|
||||
element (
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tconst T& sliding_buffer::element"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return sb_base::element();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename sb_base
|
||||
>
|
||||
typename sb_base::type& sliding_buffer_kernel_c<sb_base>::
|
||||
element (
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tT& sliding_buffer::element"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return sb_base::element();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SLIDING_BUFFER_KERNEl_C_
|
||||
|
||||
Reference in New Issue
Block a user