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.
236 lines
5.8 KiB
C++
236 lines
5.8 KiB
C++
// 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_
|
|
|