Lesson 35 - Get Compute Auth Token Working
This commit is contained in:
1158
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/algs.h
vendored
Normal file
1158
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/algs.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/array.h
vendored
Normal file
10
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/array.h
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_ARRAy_
|
||||
#define DLIB_ARRAy_
|
||||
|
||||
#include "array/array_kernel.h"
|
||||
#include "array/array_tools.h"
|
||||
|
||||
#endif // DLIB_ARRAy_
|
||||
|
||||
@@ -0,0 +1,809 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_ARRAY_KERNEl_2_
|
||||
#define DLIB_ARRAY_KERNEl_2_
|
||||
|
||||
#include "array_kernel_abstract.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../algs.h"
|
||||
#include "../serialize.h"
|
||||
#include "../sort.h"
|
||||
#include "../is_kind.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager = default_memory_manager
|
||||
>
|
||||
class array : public enumerable<T>
|
||||
{
|
||||
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
- array_size == 0
|
||||
- max_array_size == 0
|
||||
- array_elements == 0
|
||||
- pos == 0
|
||||
- last_pos == 0
|
||||
- _at_start == true
|
||||
|
||||
CONVENTION
|
||||
- array_size == size()
|
||||
- max_array_size == max_size()
|
||||
- if (max_array_size > 0)
|
||||
- array_elements == pointer to max_array_size elements of type T
|
||||
- else
|
||||
- array_elements == 0
|
||||
|
||||
- if (array_size > 0)
|
||||
- last_pos == array_elements + array_size - 1
|
||||
- else
|
||||
- last_pos == 0
|
||||
|
||||
|
||||
- at_start() == _at_start
|
||||
- current_element_valid() == pos != 0
|
||||
- if (current_element_valid()) then
|
||||
- *pos == element()
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
// These typedefs are here for backwards compatibility with old versions of dlib.
|
||||
typedef array kernel_1a;
|
||||
typedef array kernel_1a_c;
|
||||
typedef array kernel_2a;
|
||||
typedef array kernel_2a_c;
|
||||
typedef array sort_1a;
|
||||
typedef array sort_1a_c;
|
||||
typedef array sort_1b;
|
||||
typedef array sort_1b_c;
|
||||
typedef array sort_2a;
|
||||
typedef array sort_2a_c;
|
||||
typedef array sort_2b;
|
||||
typedef array sort_2b_c;
|
||||
typedef array expand_1a;
|
||||
typedef array expand_1a_c;
|
||||
typedef array expand_1b;
|
||||
typedef array expand_1b_c;
|
||||
typedef array expand_1c;
|
||||
typedef array expand_1c_c;
|
||||
typedef array expand_1d;
|
||||
typedef array expand_1d_c;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef T type;
|
||||
typedef T value_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
array (
|
||||
) :
|
||||
array_size(0),
|
||||
max_array_size(0),
|
||||
array_elements(0),
|
||||
pos(0),
|
||||
last_pos(0),
|
||||
_at_start(true)
|
||||
{}
|
||||
|
||||
array(const array&) = delete;
|
||||
array& operator=(array&) = delete;
|
||||
|
||||
array(
|
||||
array&& item
|
||||
) : array()
|
||||
{
|
||||
swap(item);
|
||||
}
|
||||
|
||||
array& operator=(
|
||||
array&& item
|
||||
)
|
||||
{
|
||||
swap(item);
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit array (
|
||||
size_t new_size
|
||||
) :
|
||||
array_size(0),
|
||||
max_array_size(0),
|
||||
array_elements(0),
|
||||
pos(0),
|
||||
last_pos(0),
|
||||
_at_start(true)
|
||||
{
|
||||
resize(new_size);
|
||||
}
|
||||
|
||||
~array (
|
||||
);
|
||||
|
||||
void clear (
|
||||
);
|
||||
|
||||
inline const T& operator[] (
|
||||
size_t pos
|
||||
) const;
|
||||
|
||||
inline T& operator[] (
|
||||
size_t pos
|
||||
);
|
||||
|
||||
void set_size (
|
||||
size_t size
|
||||
);
|
||||
|
||||
inline size_t max_size(
|
||||
) const;
|
||||
|
||||
void set_max_size(
|
||||
size_t max
|
||||
);
|
||||
|
||||
void swap (
|
||||
array& item
|
||||
);
|
||||
|
||||
// functions from the enumerable interface
|
||||
inline size_t size (
|
||||
) const;
|
||||
|
||||
inline bool at_start (
|
||||
) const;
|
||||
|
||||
inline void reset (
|
||||
) const;
|
||||
|
||||
bool current_element_valid (
|
||||
) const;
|
||||
|
||||
inline const T& element (
|
||||
) const;
|
||||
|
||||
inline T& element (
|
||||
);
|
||||
|
||||
bool move_next (
|
||||
) const;
|
||||
|
||||
void sort (
|
||||
);
|
||||
|
||||
void resize (
|
||||
size_t new_size
|
||||
);
|
||||
|
||||
const T& back (
|
||||
) const;
|
||||
|
||||
T& back (
|
||||
);
|
||||
|
||||
void pop_back (
|
||||
);
|
||||
|
||||
void pop_back (
|
||||
T& item
|
||||
);
|
||||
|
||||
void push_back (
|
||||
T& item
|
||||
);
|
||||
|
||||
void push_back (
|
||||
T&& item
|
||||
);
|
||||
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
iterator begin() { return array_elements; }
|
||||
const_iterator begin() const { return array_elements; }
|
||||
iterator end() { return array_elements+array_size; }
|
||||
const_iterator end() const { return array_elements+array_size; }
|
||||
|
||||
private:
|
||||
|
||||
typename mem_manager::template rebind<T>::other pool;
|
||||
|
||||
// data members
|
||||
size_t array_size;
|
||||
size_t max_array_size;
|
||||
T* array_elements;
|
||||
|
||||
mutable T* pos;
|
||||
T* last_pos;
|
||||
mutable bool _at_start;
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
inline void swap (
|
||||
array<T,mem_manager>& a,
|
||||
array<T,mem_manager>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void serialize (
|
||||
const array<T,mem_manager>& item,
|
||||
std::ostream& out
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
serialize(item.max_size(),out);
|
||||
serialize(item.size(),out);
|
||||
|
||||
for (size_t 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 array");
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
array<T,mem_manager>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
size_t max_size, size;
|
||||
deserialize(max_size,in);
|
||||
deserialize(size,in);
|
||||
item.set_max_size(max_size);
|
||||
item.set_size(size);
|
||||
for (size_t 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 array");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
array<T,mem_manager>::
|
||||
~array (
|
||||
)
|
||||
{
|
||||
if (array_elements)
|
||||
{
|
||||
pool.deallocate_array(array_elements);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
clear (
|
||||
)
|
||||
{
|
||||
reset();
|
||||
last_pos = 0;
|
||||
array_size = 0;
|
||||
if (array_elements)
|
||||
{
|
||||
pool.deallocate_array(array_elements);
|
||||
}
|
||||
array_elements = 0;
|
||||
max_array_size = 0;
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
const T& array<T,mem_manager>::
|
||||
operator[] (
|
||||
size_t pos
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT( pos < this->size() ,
|
||||
"\tconst T& array::operator[]"
|
||||
<< "\n\tpos must < size()"
|
||||
<< "\n\tpos: " << pos
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return array_elements[pos];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
T& array<T,mem_manager>::
|
||||
operator[] (
|
||||
size_t pos
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT( pos < this->size() ,
|
||||
"\tT& array::operator[]"
|
||||
<< "\n\tpos must be < size()"
|
||||
<< "\n\tpos: " << pos
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return array_elements[pos];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
set_size (
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(( size <= this->max_size() ),
|
||||
"\tvoid array::set_size"
|
||||
<< "\n\tsize must be <= max_size()"
|
||||
<< "\n\tsize: " << size
|
||||
<< "\n\tmax size: " << this->max_size()
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
reset();
|
||||
array_size = size;
|
||||
if (size > 0)
|
||||
last_pos = array_elements + size - 1;
|
||||
else
|
||||
last_pos = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
size_t array<T,mem_manager>::
|
||||
size (
|
||||
) const
|
||||
{
|
||||
return array_size;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
set_max_size(
|
||||
size_t max
|
||||
)
|
||||
{
|
||||
reset();
|
||||
array_size = 0;
|
||||
last_pos = 0;
|
||||
if (max != 0)
|
||||
{
|
||||
// if new max size is different
|
||||
if (max != max_array_size)
|
||||
{
|
||||
if (array_elements)
|
||||
{
|
||||
pool.deallocate_array(array_elements);
|
||||
}
|
||||
// try to get more memroy
|
||||
try { array_elements = pool.allocate_array(max); }
|
||||
catch (...) { array_elements = 0; max_array_size = 0; throw; }
|
||||
max_array_size = max;
|
||||
}
|
||||
|
||||
}
|
||||
// if the array is being made to be zero
|
||||
else
|
||||
{
|
||||
if (array_elements)
|
||||
pool.deallocate_array(array_elements);
|
||||
max_array_size = 0;
|
||||
array_elements = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
size_t array<T,mem_manager>::
|
||||
max_size (
|
||||
) const
|
||||
{
|
||||
return max_array_size;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
swap (
|
||||
array<T,mem_manager>& item
|
||||
)
|
||||
{
|
||||
auto array_size_temp = item.array_size;
|
||||
auto max_array_size_temp = item.max_array_size;
|
||||
T* array_elements_temp = item.array_elements;
|
||||
|
||||
item.array_size = array_size;
|
||||
item.max_array_size = max_array_size;
|
||||
item.array_elements = array_elements;
|
||||
|
||||
array_size = array_size_temp;
|
||||
max_array_size = max_array_size_temp;
|
||||
array_elements = array_elements_temp;
|
||||
|
||||
exchange(_at_start,item._at_start);
|
||||
exchange(pos,item.pos);
|
||||
exchange(last_pos,item.last_pos);
|
||||
pool.swap(item.pool);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// enumerable function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
bool array<T,mem_manager>::
|
||||
at_start (
|
||||
) const
|
||||
{
|
||||
return _at_start;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
reset (
|
||||
) const
|
||||
{
|
||||
_at_start = true;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
bool array<T,mem_manager>::
|
||||
current_element_valid (
|
||||
) const
|
||||
{
|
||||
return pos != 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
const T& array<T,mem_manager>::
|
||||
element (
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT(this->current_element_valid(),
|
||||
"\tconst T& array::element()"
|
||||
<< "\n\tThe current element must be valid if you are to access it."
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return *pos;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
T& array<T,mem_manager>::
|
||||
element (
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT(this->current_element_valid(),
|
||||
"\tT& array::element()"
|
||||
<< "\n\tThe current element must be valid if you are to access it."
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return *pos;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
bool array<T,mem_manager>::
|
||||
move_next (
|
||||
) const
|
||||
{
|
||||
if (!_at_start)
|
||||
{
|
||||
if (pos < last_pos)
|
||||
{
|
||||
++pos;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_at_start = false;
|
||||
if (array_size > 0)
|
||||
{
|
||||
pos = array_elements;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Yet more functions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
sort (
|
||||
)
|
||||
{
|
||||
if (this->size() > 1)
|
||||
{
|
||||
// call the quick sort function for arrays that is in algs.h
|
||||
dlib::qsort_array(*this,0,this->size()-1);
|
||||
}
|
||||
this->reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
resize (
|
||||
size_t new_size
|
||||
)
|
||||
{
|
||||
if (this->max_size() < new_size)
|
||||
{
|
||||
array temp;
|
||||
temp.set_max_size(new_size);
|
||||
temp.set_size(new_size);
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
exchange((*this)[i],temp[i]);
|
||||
}
|
||||
temp.swap(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->set_size(new_size);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
T& array<T,mem_manager>::
|
||||
back (
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT( this->size() > 0 ,
|
||||
"\tT& array::back()"
|
||||
<< "\n\tsize() must be bigger than 0"
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return (*this)[this->size()-1];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
const T& array<T,mem_manager>::
|
||||
back (
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT( this->size() > 0 ,
|
||||
"\tconst T& array::back()"
|
||||
<< "\n\tsize() must be bigger than 0"
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return (*this)[this->size()-1];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
pop_back (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT( this->size() > 0 ,
|
||||
"\tvoid array::pop_back()"
|
||||
<< "\n\tsize() must be bigger than 0"
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
exchange(item,(*this)[this->size()-1]);
|
||||
this->set_size(this->size()-1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
pop_back (
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT( this->size() > 0 ,
|
||||
"\tvoid array::pop_back()"
|
||||
<< "\n\tsize() must be bigger than 0"
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
this->set_size(this->size()-1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
push_back (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
if (this->max_size() == this->size())
|
||||
{
|
||||
// double the size of the array
|
||||
array temp;
|
||||
temp.set_max_size(this->size()*2 + 1);
|
||||
temp.set_size(this->size()+1);
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
exchange((*this)[i],temp[i]);
|
||||
}
|
||||
exchange(item,temp[temp.size()-1]);
|
||||
temp.swap(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->set_size(this->size()+1);
|
||||
exchange(item,(*this)[this->size()-1]);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void array<T,mem_manager>::
|
||||
push_back (
|
||||
T&& item
|
||||
) { push_back(item); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T, typename MM>
|
||||
struct is_array <array<T,MM> >
|
||||
{
|
||||
const static bool value = true;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_ARRAY_KERNEl_2_
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_ARRAY_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_ARRAY_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../serialize.h"
|
||||
#include "../algs.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager = default_memory_manager
|
||||
>
|
||||
class array : public enumerable<T>
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T must have a default constructor.
|
||||
|
||||
REQUIREMENTS ON mem_manager
|
||||
must be an implementation of memory_manager/memory_manager_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_global/memory_manager_global_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
|
||||
mem_manager::type can be set to anything.
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
front(), back(), swap(), max_size(), set_size(), and operator[]
|
||||
functions do not invalidate pointers or references to internal data.
|
||||
All other functions have no such guarantee.
|
||||
|
||||
INITIAL VALUE
|
||||
size() == 0
|
||||
max_size() == 0
|
||||
|
||||
ENUMERATION ORDER
|
||||
The enumerator will iterate over the elements of the array in the
|
||||
order (*this)[0], (*this)[1], (*this)[2], ...
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents an ordered 1-dimensional array of items,
|
||||
each item is associated with an integer value. The items are
|
||||
numbered from 0 though size() - 1 and the operator[] functions
|
||||
run in constant time.
|
||||
|
||||
Also note that unless specified otherwise, no member functions
|
||||
of this object throw exceptions.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
typedef T value_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
array (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
!*/
|
||||
|
||||
explicit array (
|
||||
size_t new_size
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
- #size() == new_size
|
||||
- #max_size() == new_size
|
||||
- All elements of the array will have initial values for their type.
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
!*/
|
||||
|
||||
~array (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- all memory associated with *this has been released
|
||||
!*/
|
||||
|
||||
array(
|
||||
array&& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- move constructs *this from item. Therefore, the state of item is
|
||||
moved into *this and #item has a valid but unspecified state.
|
||||
!*/
|
||||
|
||||
array& operator=(
|
||||
array&& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- move assigns *this from item. Therefore, the state of item is
|
||||
moved into *this and #item has a valid but unspecified state.
|
||||
- returns a reference to #*this
|
||||
!*/
|
||||
|
||||
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 the array object is unusable
|
||||
until clear() is called and succeeds
|
||||
!*/
|
||||
|
||||
const T& operator[] (
|
||||
size_t pos
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- pos < size()
|
||||
ensures
|
||||
- returns a const reference to the element at position pos
|
||||
!*/
|
||||
|
||||
T& operator[] (
|
||||
size_t pos
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- pos < size()
|
||||
ensures
|
||||
- returns a non-const reference to the element at position pos
|
||||
!*/
|
||||
|
||||
void set_size (
|
||||
size_t size
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- size <= max_size()
|
||||
ensures
|
||||
- #size() == size
|
||||
- any element with index between 0 and size - 1 which was in the
|
||||
array before the call to set_size() retains its value and index.
|
||||
All other elements have undetermined (but valid for their type)
|
||||
values. (e.g. this object might buffer old T objects and reuse
|
||||
them without reinitializing them between calls to set_size())
|
||||
- #at_start() == true
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
may throw this exception if there is not enough memory and
|
||||
if it does throw then the call to set_size() has no effect
|
||||
!*/
|
||||
|
||||
size_t max_size(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the maximum size of *this
|
||||
!*/
|
||||
|
||||
void set_max_size(
|
||||
size_t max
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #max_size() == max
|
||||
- #size() == 0
|
||||
- #at_start() == true
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
may throw this exception if there is not enough
|
||||
memory and if it does throw then max_size() == 0
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
array<T>& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
void sort (
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- T must be a type with that is comparable via operator<
|
||||
ensures
|
||||
- for all elements in #*this the ith element is <= the i+1 element
|
||||
- #at_start() == true
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
data may be lost if sort() throws
|
||||
!*/
|
||||
|
||||
void resize (
|
||||
size_t new_size
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #size() == new_size
|
||||
- #max_size() == max(new_size,max_size())
|
||||
- for all i < size() && i < new_size:
|
||||
- #(*this)[i] == (*this)[i]
|
||||
(i.e. All the original elements of *this which were at index
|
||||
values less than new_size are unmodified.)
|
||||
- for all valid i >= size():
|
||||
- #(*this)[i] has an undefined value
|
||||
(i.e. any new elements of the array have an undefined value)
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If an exception is thrown then it has no effect on *this.
|
||||
!*/
|
||||
|
||||
|
||||
const T& back (
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- size() != 0
|
||||
ensures
|
||||
- returns a const reference to (*this)[size()-1]
|
||||
!*/
|
||||
|
||||
T& back (
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- size() != 0
|
||||
ensures
|
||||
- returns a non-const reference to (*this)[size()-1]
|
||||
!*/
|
||||
|
||||
void pop_back (
|
||||
T& item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- size() != 0
|
||||
ensures
|
||||
- #size() == size() - 1
|
||||
- swaps (*this)[size()-1] into item
|
||||
- All elements with an index less than size()-1 are
|
||||
unmodified by this operation.
|
||||
!*/
|
||||
|
||||
void pop_back (
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- size() != 0
|
||||
ensures
|
||||
- #size() == size() - 1
|
||||
- All elements with an index less than size()-1 are
|
||||
unmodified by this operation.
|
||||
!*/
|
||||
|
||||
void push_back (
|
||||
T& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #size() == size()+1
|
||||
- swaps item into (*this)[#size()-1]
|
||||
- #back() == item
|
||||
- #item has some undefined value (whatever happens to
|
||||
get swapped out of the array)
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If an exception is thrown then it has no effect on *this.
|
||||
!*/
|
||||
|
||||
void push_back (T&& item) { push_back(item); }
|
||||
/*!
|
||||
enable push_back from rvalues
|
||||
!*/
|
||||
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
|
||||
iterator begin(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns an iterator that points to the first element in this array or
|
||||
end() if the array is empty.
|
||||
!*/
|
||||
|
||||
const_iterator begin(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns a const iterator that points to the first element in this
|
||||
array or end() if the array is empty.
|
||||
!*/
|
||||
|
||||
iterator end(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns an iterator that points to one past the end of the array.
|
||||
!*/
|
||||
|
||||
const_iterator end(
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns a const iterator that points to one past the end of the
|
||||
array.
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
array(array<T>&); // copy constructor
|
||||
array<T>& operator=(array<T>&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
inline void swap (
|
||||
array<T>& a,
|
||||
array<T>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void serialize (
|
||||
const array<T>& item,
|
||||
std::ostream& out
|
||||
);
|
||||
/*!
|
||||
provides serialization support
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void deserialize (
|
||||
array<T>& item,
|
||||
std::istream& in
|
||||
);
|
||||
/*!
|
||||
provides deserialization support
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_ARRAY_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2013 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_ARRAY_tOOLS_H_
|
||||
#define DLIB_ARRAY_tOOLS_H_
|
||||
|
||||
#include "../assert.h"
|
||||
#include "array_tools_abstract.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
template <typename T>
|
||||
void split_array (
|
||||
T& a,
|
||||
T& b,
|
||||
double frac
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT(0 <= frac && frac <= 1,
|
||||
"\t void split_array()"
|
||||
<< "\n\t frac must be between 0 and 1."
|
||||
<< "\n\t frac: " << frac
|
||||
);
|
||||
|
||||
const unsigned long asize = static_cast<unsigned long>(a.size()*frac);
|
||||
const unsigned long bsize = a.size()-asize;
|
||||
|
||||
b.resize(bsize);
|
||||
for (unsigned long i = 0; i < b.size(); ++i)
|
||||
{
|
||||
swap(b[i], a[i+asize]);
|
||||
}
|
||||
a.resize(asize);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DLIB_ARRAY_tOOLS_H_
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2013 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_ARRAY_tOOLS_ABSTRACT_H_
|
||||
#ifdef DLIB_ARRAY_tOOLS_ABSTRACT_H_
|
||||
|
||||
#include "array_kernel_abstract.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
template <typename T>
|
||||
void split_array (
|
||||
T& a,
|
||||
T& b,
|
||||
double frac
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- 0 <= frac <= 1
|
||||
- T must be an array type such as dlib::array or std::vector
|
||||
ensures
|
||||
- This function takes the elements of a and splits them into two groups. The
|
||||
first group remains in a and the second group is put into b. The ordering of
|
||||
elements in a is preserved. In particular, concatenating #a with #b will
|
||||
reproduce the original contents of a.
|
||||
- The elements in a are moved around using global swap(). So they must be
|
||||
swappable, but do not need to be copyable.
|
||||
- #a.size() == floor(a.size()*frac)
|
||||
- #b.size() == a.size()-#a.size()
|
||||
!*/
|
||||
}
|
||||
|
||||
#endif // DLIB_ARRAY_tOOLS_ABSTRACT_H_
|
||||
|
||||
217
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/assert.h
vendored
Normal file
217
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/assert.h
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_ASSERt_
|
||||
#define DLIB_ASSERt_
|
||||
|
||||
#include "config.h"
|
||||
#include <sstream>
|
||||
#include <iosfwd>
|
||||
#include "error.h"
|
||||
|
||||
// -----------------------------
|
||||
|
||||
// Use some stuff from boost here
|
||||
// (C) Copyright John Maddock 2001 - 2003.
|
||||
// (C) Copyright Darin Adler 2001.
|
||||
// (C) Copyright Peter Dimov 2001.
|
||||
// (C) Copyright Bill Kempf 2002.
|
||||
// (C) Copyright Jens Maurer 2002.
|
||||
// (C) Copyright David Abrahams 2002 - 2003.
|
||||
// (C) Copyright Gennaro Prota 2003.
|
||||
// (C) Copyright Eric Friedman 2003.
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
//
|
||||
#ifndef DLIB_BOOST_JOIN
|
||||
#define DLIB_BOOST_JOIN( X, Y ) DLIB_BOOST_DO_JOIN( X, Y )
|
||||
#define DLIB_BOOST_DO_JOIN( X, Y ) DLIB_BOOST_DO_JOIN2(X,Y)
|
||||
#define DLIB_BOOST_DO_JOIN2( X, Y ) X##Y
|
||||
#endif
|
||||
|
||||
// figure out if the compiler has rvalue references.
|
||||
#if defined(__clang__)
|
||||
# if __has_feature(cxx_rvalue_references)
|
||||
# define DLIB_HAS_RVALUE_REFERENCES
|
||||
# endif
|
||||
# if __has_feature(cxx_generalized_initializers)
|
||||
# define DLIB_HAS_INITIALIZER_LISTS
|
||||
# endif
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define DLIB_HAS_RVALUE_REFERENCES
|
||||
# define DLIB_HAS_INITIALIZER_LISTS
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1800
|
||||
# define DLIB_HAS_INITIALIZER_LISTS
|
||||
# define DLIB_HAS_RVALUE_REFERENCES
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
# define DLIB_HAS_RVALUE_REFERENCES
|
||||
#elif defined(__INTEL_COMPILER) && defined(BOOST_INTEL_STDCXX0X)
|
||||
# define DLIB_HAS_RVALUE_REFERENCES
|
||||
# define DLIB_HAS_INITIALIZER_LISTS
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__GNUC_LIBSTD__) && ((__GNUC_LIBSTD__-0) * 100 + __GNUC_LIBSTD_MINOR__-0 <= 402)
|
||||
// Apple has not updated libstdc++ in some time and anything under 4.02 does not have <initializer_list> for sure.
|
||||
# undef DLIB_HAS_INITIALIZER_LISTS
|
||||
#endif
|
||||
|
||||
// figure out if the compiler has static_assert.
|
||||
#if defined(__clang__)
|
||||
# if __has_feature(cxx_static_assert)
|
||||
# define DLIB_HAS_STATIC_ASSERT
|
||||
# endif
|
||||
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define DLIB_HAS_STATIC_ASSERT
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
# define DLIB_HAS_STATIC_ASSERT
|
||||
#elif defined(__INTEL_COMPILER) && defined(BOOST_INTEL_STDCXX0X)
|
||||
# define DLIB_HAS_STATIC_ASSERT
|
||||
#endif
|
||||
|
||||
|
||||
// -----------------------------
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
template <bool value> struct compile_time_assert;
|
||||
template <> struct compile_time_assert<true> { enum {value=1}; };
|
||||
|
||||
template <typename T, typename U> struct assert_are_same_type;
|
||||
template <typename T> struct assert_are_same_type<T,T> {enum{value=1};};
|
||||
template <typename T, typename U> struct assert_are_not_same_type {enum{value=1}; };
|
||||
template <typename T> struct assert_are_not_same_type<T,T> {};
|
||||
|
||||
template <typename T, typename U> struct assert_types_match {enum{value=0};};
|
||||
template <typename T> struct assert_types_match<T,T> {enum{value=1};};
|
||||
}
|
||||
|
||||
|
||||
// gcc 4.8 will warn about unused typedefs. But we use typedefs in some of the compile
|
||||
// time assert macros so we need to make it not complain about them "not being used".
|
||||
#ifdef __GNUC__
|
||||
#define DLIB_NO_WARN_UNUSED __attribute__ ((unused))
|
||||
#else
|
||||
#define DLIB_NO_WARN_UNUSED
|
||||
#endif
|
||||
|
||||
// Use the newer static_assert if it's available since it produces much more readable error
|
||||
// messages.
|
||||
#ifdef DLIB_HAS_STATIC_ASSERT
|
||||
#define COMPILE_TIME_ASSERT(expression) static_assert(expression, "Failed assertion")
|
||||
#define ASSERT_ARE_SAME_TYPE(type1, type2) static_assert(::dlib::assert_types_match<type1,type2>::value, "These types should be the same but aren't.")
|
||||
#define ASSERT_ARE_NOT_SAME_TYPE(type1, type2) static_assert(!::dlib::assert_types_match<type1,type2>::value, "These types should NOT be the same.")
|
||||
#else
|
||||
#define COMPILE_TIME_ASSERT(expression) \
|
||||
DLIB_NO_WARN_UNUSED typedef char DLIB_BOOST_JOIN(DLIB_CTA, __LINE__)[::dlib::compile_time_assert<(bool)(expression)>::value]
|
||||
|
||||
#define ASSERT_ARE_SAME_TYPE(type1, type2) \
|
||||
DLIB_NO_WARN_UNUSED typedef char DLIB_BOOST_JOIN(DLIB_AAST, __LINE__)[::dlib::assert_are_same_type<type1,type2>::value]
|
||||
|
||||
#define ASSERT_ARE_NOT_SAME_TYPE(type1, type2) \
|
||||
DLIB_NO_WARN_UNUSED typedef char DLIB_BOOST_JOIN(DLIB_AANST, __LINE__)[::dlib::assert_are_not_same_type<type1,type2>::value]
|
||||
#endif
|
||||
|
||||
// -----------------------------
|
||||
|
||||
#if defined DLIB_DISABLE_ASSERTS
|
||||
// if DLIB_DISABLE_ASSERTS is on then never enable DLIB_ASSERT no matter what.
|
||||
#undef ENABLE_ASSERTS
|
||||
#endif
|
||||
|
||||
#if !defined(DLIB_DISABLE_ASSERTS) && ( defined DEBUG || defined _DEBUG)
|
||||
// make sure ENABLE_ASSERTS is defined if we are indeed using them.
|
||||
#ifndef ENABLE_ASSERTS
|
||||
#define ENABLE_ASSERTS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// -----------------------------
|
||||
|
||||
#ifdef __GNUC__
|
||||
// There is a bug in version 4.4.5 of GCC on Ubuntu which causes GCC to segfault
|
||||
// when __PRETTY_FUNCTION__ is used within certain templated functions. So just
|
||||
// don't use it with this version of GCC.
|
||||
# if !(__GNUC__ == 4 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ == 5)
|
||||
# define DLIB_FUNCTION_NAME __PRETTY_FUNCTION__
|
||||
# else
|
||||
# define DLIB_FUNCTION_NAME "unknown function"
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
#define DLIB_FUNCTION_NAME __FUNCSIG__
|
||||
#else
|
||||
#define DLIB_FUNCTION_NAME "unknown function"
|
||||
#endif
|
||||
|
||||
#define DLIBM_CASSERT(_exp,_message) \
|
||||
{if ( !(_exp) ) \
|
||||
{ \
|
||||
dlib_assert_breakpoint(); \
|
||||
std::ostringstream dlib_o_out; \
|
||||
dlib_o_out << "\n\nError detected at line " << __LINE__ << ".\n"; \
|
||||
dlib_o_out << "Error detected in file " << __FILE__ << ".\n"; \
|
||||
dlib_o_out << "Error detected in function " << DLIB_FUNCTION_NAME << ".\n\n"; \
|
||||
dlib_o_out << "Failing expression was " << #_exp << ".\n"; \
|
||||
dlib_o_out << std::boolalpha << _message << "\n"; \
|
||||
throw dlib::fatal_error(dlib::EBROKEN_ASSERT,dlib_o_out.str()); \
|
||||
}}
|
||||
|
||||
// This macro is not needed if you have a real C++ compiler. It's here to work around bugs in Visual Studio's preprocessor.
|
||||
#define DLIB_WORKAROUND_VISUAL_STUDIO_BUGS(x) x
|
||||
// Make it so the 2nd argument of DLIB_CASSERT is optional. That is, you can call it like
|
||||
// DLIB_CASSERT(exp) or DLIB_CASSERT(exp,message).
|
||||
#define DLIBM_CASSERT_1_ARGS(exp) DLIBM_CASSERT(exp,"")
|
||||
#define DLIBM_CASSERT_2_ARGS(exp,message) DLIBM_CASSERT(exp,message)
|
||||
#define DLIBM_GET_3TH_ARG(arg1, arg2, arg3, ...) arg3
|
||||
#define DLIBM_CASSERT_CHOOSER(...) DLIB_WORKAROUND_VISUAL_STUDIO_BUGS(DLIBM_GET_3TH_ARG(__VA_ARGS__, DLIBM_CASSERT_2_ARGS, DLIBM_CASSERT_1_ARGS, DLIB_CASSERT_NEVER_USED))
|
||||
#define DLIB_CASSERT(...) DLIB_WORKAROUND_VISUAL_STUDIO_BUGS(DLIBM_CASSERT_CHOOSER(__VA_ARGS__)(__VA_ARGS__))
|
||||
|
||||
|
||||
#ifdef ENABLE_ASSERTS
|
||||
#define DLIB_ASSERT(...) DLIB_CASSERT(__VA_ARGS__)
|
||||
#define DLIB_IF_ASSERT(exp) exp
|
||||
#else
|
||||
#define DLIB_ASSERT(...) {}
|
||||
#define DLIB_IF_ASSERT(exp)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*!A DLIB_ASSERT_HAS_STANDARD_LAYOUT
|
||||
|
||||
This macro is meant to cause a compiler error if a type doesn't have a simple
|
||||
memory layout (like a C struct). In particular, types with simple layouts are
|
||||
ones which can be copied via memcpy().
|
||||
|
||||
|
||||
This was called a POD type in C++03 and in C++0x we are looking to check if
|
||||
it is a "standard layout type". Once we can use C++0x we can change this macro
|
||||
to something that uses the std::is_standard_layout type_traits class.
|
||||
See: http://www2.research.att.com/~bs/C++0xFAQ.html#PODs
|
||||
!*/
|
||||
// Use the fact that in C++03 you can't put non-PODs into a union.
|
||||
#define DLIB_ASSERT_HAS_STANDARD_LAYOUT(type) \
|
||||
union DLIB_BOOST_JOIN(DAHSL_,__LINE__) { type TYPE_NOT_STANDARD_LAYOUT; }; \
|
||||
DLIB_NO_WARN_UNUSED typedef char DLIB_BOOST_JOIN(DAHSL2_,__LINE__)[sizeof(DLIB_BOOST_JOIN(DAHSL_,__LINE__))];
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
// breakpoints
|
||||
extern "C"
|
||||
{
|
||||
inline void dlib_assert_breakpoint(
|
||||
) {}
|
||||
/*!
|
||||
ensures
|
||||
- this function does nothing
|
||||
It exists just so you can put breakpoints on it in a debugging tool.
|
||||
It is called only when an DLIB_ASSERT or DLIB_CASSERT fails and is about to
|
||||
throw an exception.
|
||||
!*/
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
|
||||
#include "stack_trace.h"
|
||||
|
||||
#endif // DLIB_ASSERt_
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_BINARY_SEARCH_TREe_
|
||||
#define DLIB_BINARY_SEARCH_TREe_
|
||||
|
||||
|
||||
#include "binary_search_tree/binary_search_tree_kernel_1.h"
|
||||
#include "binary_search_tree/binary_search_tree_kernel_2.h"
|
||||
#include "binary_search_tree/binary_search_tree_kernel_c.h"
|
||||
|
||||
|
||||
#include "algs.h"
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager = default_memory_manager,
|
||||
typename compare = std::less<domain>
|
||||
>
|
||||
class binary_search_tree
|
||||
{
|
||||
binary_search_tree() {}
|
||||
|
||||
public:
|
||||
|
||||
//----------- kernels ---------------
|
||||
|
||||
// kernel_1a
|
||||
typedef binary_search_tree_kernel_1<domain,range,mem_manager,compare>
|
||||
kernel_1a;
|
||||
typedef binary_search_tree_kernel_c<kernel_1a>
|
||||
kernel_1a_c;
|
||||
|
||||
|
||||
// kernel_2a
|
||||
typedef binary_search_tree_kernel_2<domain,range,mem_manager,compare>
|
||||
kernel_2a;
|
||||
typedef binary_search_tree_kernel_c<kernel_2a>
|
||||
kernel_2a_c;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_BINARY_SEARCH_TREe_
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,311 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_BINARY_SEARCH_TREE_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_BINARY_SEARCH_TREE_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../interfaces/map_pair.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../serialize.h"
|
||||
#include "../algs.h"
|
||||
#include <functional>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager = default_memory_manager,
|
||||
typename compare = std::less<domain>
|
||||
>
|
||||
class binary_search_tree : public enumerable<map_pair<domain,range> >,
|
||||
public asc_pair_remover<domain,range,compare>
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON domain
|
||||
domain must be comparable by compare where compare is a functor compatible with std::less and
|
||||
domain is swappable by a global swap() and
|
||||
domain must have a default constructor
|
||||
|
||||
REQUIREMENTS ON range
|
||||
range is swappable by a global swap() and
|
||||
range must have a default constructor
|
||||
|
||||
REQUIREMENTS ON mem_manager
|
||||
must be an implementation of memory_manager/memory_manager_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_global/memory_manager_global_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
|
||||
mem_manager::type can be set to anything.
|
||||
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
swap(), count(), height(), and operator[] functions
|
||||
do not invalidate pointers or references to internal data.
|
||||
|
||||
position_enumerator() invalidates pointers or references to
|
||||
data returned by element() and only by element() (i.e. pointers and
|
||||
references returned by operator[] are still valid).
|
||||
|
||||
All other functions have no such guarantees.
|
||||
|
||||
INITIAL VALUE
|
||||
size() == 0
|
||||
height() == 0
|
||||
|
||||
ENUMERATION ORDER
|
||||
The enumerator will iterate over the domain (and each associated
|
||||
range element) elements in ascending order according to the compare functor.
|
||||
(i.e. the elements are enumerated in sorted order)
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
this object represents a data dictionary that is built on top of some
|
||||
kind of binary search tree. It maps objects of type domain to objects
|
||||
of type range.
|
||||
|
||||
Also note that unless specified otherwise, no member functions
|
||||
of this object throw exceptions.
|
||||
|
||||
NOTE:
|
||||
definition of equivalent:
|
||||
a is equivalent to b if
|
||||
a < b == false and
|
||||
b < a == false
|
||||
!*/
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef domain domain_type;
|
||||
typedef range range_type;
|
||||
typedef compare compare_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
binary_search_tree(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by domain's or range's
|
||||
constructor.
|
||||
!*/
|
||||
|
||||
virtual ~binary_search_tree(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- all memory associated with *this has been released
|
||||
!*/
|
||||
|
||||
void clear(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this has its initial value
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by domain's or range's
|
||||
constructor.
|
||||
if this exception is thrown then *this is unusable
|
||||
until clear() is called and succeeds
|
||||
!*/
|
||||
|
||||
short height (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of elements in the longest path from the root
|
||||
of the tree to a leaf
|
||||
!*/
|
||||
|
||||
unsigned long count (
|
||||
const domain& d
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of elements in the domain of *this that are
|
||||
equivalent to d
|
||||
!*/
|
||||
|
||||
void add (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- &d != &r (i.e. d and r cannot be the same variable)
|
||||
ensures
|
||||
- adds a mapping between d and r to *this
|
||||
- if (count(d) == 0) then
|
||||
- #*(*this)[d] == r
|
||||
- else
|
||||
- #(*this)[d] != 0
|
||||
- #d and #r have initial values for their types
|
||||
- #count(d) == count(d) + 1
|
||||
- #at_start() == true
|
||||
- #size() == size() + 1
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by domain's or range's
|
||||
constructor.
|
||||
if add() throws then it has no effect
|
||||
!*/
|
||||
|
||||
void remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- (*this)[d] != 0
|
||||
- &d != &r (i.e. d and r cannot be the same variable)
|
||||
- &d != &d_copy (i.e. d and d_copy cannot be the same variable)
|
||||
- &r != &d_copy (i.e. r and d_copy cannot be the same variable)
|
||||
ensures
|
||||
- some element in the domain of *this that is equivalent to d has
|
||||
been removed and swapped into #d_copy. Additionally, its
|
||||
associated range element has been removed and swapped into #r.
|
||||
- #count(d) == count(d) - 1
|
||||
- #size() == size() - 1
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
void destroy (
|
||||
const domain& d
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- (*this)[d] != 0
|
||||
ensures
|
||||
- an element in the domain of *this equivalent to d has been removed.
|
||||
The element in the range of *this associated with d has also been
|
||||
removed.
|
||||
- #count(d) == count(d) - 1
|
||||
- #size() == size() - 1
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
void remove_last_in_order (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- size() > 0
|
||||
ensures
|
||||
- the last/biggest (according to the compare functor) element in the domain of *this has
|
||||
been removed and swapped into #d. The element in the range of *this
|
||||
associated with #d has also been removed and swapped into #r.
|
||||
- #count(#d) == count(#d) - 1
|
||||
- #size() == size() - 1
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
void remove_current_element (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- current_element_valid() == true
|
||||
ensures
|
||||
- the current element given by element() has been removed and swapped into d and r.
|
||||
- #d == element().key()
|
||||
- #r == element().value()
|
||||
- #count(#d) == count(#d) - 1
|
||||
- #size() == size() - 1
|
||||
- moves the enumerator to the next element. If element() was the last
|
||||
element in enumeration order then #current_element_valid() == false
|
||||
and #at_start() == false.
|
||||
!*/
|
||||
|
||||
void position_enumerator (
|
||||
const domain& d
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- #at_start() == false
|
||||
- if (count(d) > 0) then
|
||||
- #element().key() == d
|
||||
- else if (there are any items in the domain of *this that are bigger than
|
||||
d according to the compare functor) then
|
||||
- #element().key() == the smallest item in the domain of *this that is
|
||||
bigger than d according to the compare functor.
|
||||
- else
|
||||
- #current_element_valid() == false
|
||||
!*/
|
||||
|
||||
const range* operator[] (
|
||||
const domain& d
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (there is an element in the domain equivalent to d) then
|
||||
- returns a pointer to an element in the range of *this that
|
||||
is associated with an element in the domain of *this
|
||||
equivalent to d.
|
||||
- else
|
||||
- returns 0
|
||||
!*/
|
||||
|
||||
range* operator[] (
|
||||
const domain& d
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (there is an element in the domain equivalent to d) then
|
||||
- returns a pointer to an element in the range of *this that
|
||||
is associated with an element in the domain of *this
|
||||
equivalent to d.
|
||||
- else
|
||||
- returns 0
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
binary_search_tree& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
binary_search_tree(binary_search_tree&);
|
||||
binary_search_tree& operator=(binary_search_tree&);
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
inline void swap (
|
||||
binary_search_tree<domain,range,mem_manager,compare>& a,
|
||||
binary_search_tree<domain,range,mem_manager,compare>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void deserialize (
|
||||
binary_search_tree<domain,range,mem_manager,compare>& item,
|
||||
std::istream& in
|
||||
);
|
||||
/*!
|
||||
provides deserialization support
|
||||
!*/
|
||||
}
|
||||
|
||||
#endif // DLIB_BINARY_SEARCH_TREE_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_BINARY_SEARCH_TREE_KERNEl_C_
|
||||
#define DLIB_BINARY_SEARCH_TREE_KERNEl_C_
|
||||
|
||||
#include "../interfaces/map_pair.h"
|
||||
#include "binary_search_tree_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../assert.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename bst_base
|
||||
>
|
||||
class binary_search_tree_kernel_c : public bst_base
|
||||
{
|
||||
typedef typename bst_base::domain_type domain;
|
||||
typedef typename bst_base::range_type range;
|
||||
|
||||
public:
|
||||
|
||||
binary_search_tree_kernel_c () {}
|
||||
|
||||
void remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
);
|
||||
|
||||
void destroy (
|
||||
const domain& d
|
||||
);
|
||||
|
||||
void add (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
void remove_any (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
const map_pair<domain, range>& element(
|
||||
) const
|
||||
{
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tconst map_pair<domain,range>& binary_search_tree::element() const"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return bst_base::element();
|
||||
}
|
||||
|
||||
map_pair<domain, range>& element(
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tmap_pair<domain,range>& binary_search_tree::element()"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
return bst_base::element();
|
||||
}
|
||||
|
||||
void remove_last_in_order (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
void remove_current_element (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <
|
||||
typename bst_base
|
||||
>
|
||||
inline void swap (
|
||||
binary_search_tree_kernel_c<bst_base>& a,
|
||||
binary_search_tree_kernel_c<bst_base>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename bst_base
|
||||
>
|
||||
void binary_search_tree_kernel_c<bst_base>::
|
||||
add (
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT( static_cast<const void*>(&d) != static_cast<void*>(&r),
|
||||
"\tvoid binary_search_tree::add"
|
||||
<< "\n\tyou can't call add() and give the same object to both parameters."
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << &d
|
||||
<< "\n\t&r: " << &r
|
||||
<< "\n\tsize(): " << this->size()
|
||||
);
|
||||
|
||||
bst_base::add(d,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename bst_base
|
||||
>
|
||||
void binary_search_tree_kernel_c<bst_base>::
|
||||
destroy (
|
||||
const domain& d
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(this->operator[](d) != 0,
|
||||
"\tvoid binary_search_tree::destroy"
|
||||
<< "\n\tthe element must be in the tree for it to be removed"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << &d
|
||||
);
|
||||
|
||||
bst_base::destroy(d);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename bst_base
|
||||
>
|
||||
void binary_search_tree_kernel_c<bst_base>::
|
||||
remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(this->operator[](d) != 0 &&
|
||||
(static_cast<const void*>(&d) != static_cast<void*>(&d_copy)) &&
|
||||
(static_cast<const void*>(&d) != static_cast<void*>(&r)) &&
|
||||
(static_cast<const void*>(&r) != static_cast<void*>(&d_copy)),
|
||||
"\tvoid binary_search_tree::remove"
|
||||
<< "\n\tthe element must be in the tree for it to be removed"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << &d
|
||||
<< "\n\t&d_copy: " << &d_copy
|
||||
<< "\n\t&r: " << &r
|
||||
);
|
||||
|
||||
bst_base::remove(d,d_copy,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename bst_base
|
||||
>
|
||||
void binary_search_tree_kernel_c<bst_base>::
|
||||
remove_any(
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(this->size() != 0 &&
|
||||
(static_cast<const void*>(&d) != static_cast<void*>(&r)),
|
||||
"\tvoid binary_search_tree::remove_any"
|
||||
<< "\n\ttree must not be empty if something is going to be removed"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << &d
|
||||
<< "\n\t&r: " << &r
|
||||
);
|
||||
|
||||
bst_base::remove_any(d,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename bst_base
|
||||
>
|
||||
void binary_search_tree_kernel_c<bst_base>::
|
||||
remove_last_in_order (
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(this->size() > 0,
|
||||
"\tvoid binary_search_tree::remove_last_in_order()"
|
||||
<< "\n\tyou can't remove an element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
bst_base::remove_last_in_order(d,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename bst_base
|
||||
>
|
||||
void binary_search_tree_kernel_c<bst_base>::
|
||||
remove_current_element (
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tvoid binary_search_tree::remove_current_element()"
|
||||
<< "\n\tyou can't remove the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
bst_base::remove_current_element(d,r);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_BINARY_SEARCH_TREE_KERNEl_C_
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (C) 2008 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_BOUND_FUNCTION_POINTEr_
|
||||
#define DLIB_BOUND_FUNCTION_POINTEr_
|
||||
|
||||
#include "bound_function_pointer/bound_function_pointer_kernel_1.h"
|
||||
|
||||
#endif // DLIB_BOUND_FUNCTION_POINTEr_
|
||||
|
||||
|
||||
@@ -0,0 +1,774 @@
|
||||
// Copyright (C) 2008 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_BOUND_FUNCTION_POINTER_KERNEl_1_
|
||||
#define DLIB_BOUND_FUNCTION_POINTER_KERNEl_1_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "../member_function_pointer.h"
|
||||
#include "bound_function_pointer_kernel_abstract.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace bfp1_helpers
|
||||
{
|
||||
template <typename T> struct strip { typedef T type; };
|
||||
template <typename T> struct strip<T&> { typedef T type; };
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
class bound_function_helper_base_base
|
||||
{
|
||||
public:
|
||||
virtual ~bound_function_helper_base_base(){}
|
||||
virtual void call() const = 0;
|
||||
virtual bool is_set() const = 0;
|
||||
virtual void clone(void* ptr) const = 0;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
class bound_function_helper_base : public bound_function_helper_base_base
|
||||
{
|
||||
public:
|
||||
bound_function_helper_base():arg1(0), arg2(0), arg3(0), arg4(0) {}
|
||||
|
||||
typename strip<T1>::type* arg1;
|
||||
typename strip<T2>::type* arg2;
|
||||
typename strip<T3>::type* arg3;
|
||||
typename strip<T4>::type* arg4;
|
||||
|
||||
|
||||
member_function_pointer<T1,T2,T3,T4> mfp;
|
||||
};
|
||||
|
||||
// ----------------
|
||||
|
||||
template <typename F, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void>
|
||||
class bound_function_helper : public bound_function_helper_base<T1,T2,T3,T4>
|
||||
{
|
||||
public:
|
||||
void call() const
|
||||
{
|
||||
(*fp)(*this->arg1, *this->arg2, *this->arg3, *this->arg4);
|
||||
}
|
||||
|
||||
typename strip<F>::type* fp;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
class bound_function_helper<void,T1,T2,T3,T4> : public bound_function_helper_base<T1,T2,T3,T4>
|
||||
{
|
||||
public:
|
||||
void call() const
|
||||
{
|
||||
if (this->mfp) this->mfp(*this->arg1, *this->arg2, *this->arg3, *this->arg4);
|
||||
else if (fp) fp(*this->arg1, *this->arg2, *this->arg3, *this->arg4);
|
||||
}
|
||||
|
||||
void (*fp)(T1, T2, T3, T4);
|
||||
};
|
||||
|
||||
// ----------------
|
||||
|
||||
template <typename F>
|
||||
class bound_function_helper<F,void,void,void,void> : public bound_function_helper_base<void,void,void,void>
|
||||
{
|
||||
public:
|
||||
void call() const
|
||||
{
|
||||
(*fp)();
|
||||
}
|
||||
|
||||
typename strip<F>::type* fp;
|
||||
};
|
||||
|
||||
template <>
|
||||
class bound_function_helper<void,void,void,void,void> : public bound_function_helper_base<void,void,void,void>
|
||||
{
|
||||
public:
|
||||
void call() const
|
||||
{
|
||||
if (this->mfp) this->mfp();
|
||||
else if (fp) fp();
|
||||
}
|
||||
|
||||
void (*fp)();
|
||||
};
|
||||
|
||||
// ----------------
|
||||
|
||||
template <typename F, typename T1>
|
||||
class bound_function_helper<F,T1,void,void,void> : public bound_function_helper_base<T1,void,void,void>
|
||||
{
|
||||
public:
|
||||
void call() const
|
||||
{
|
||||
(*fp)(*this->arg1);
|
||||
}
|
||||
|
||||
typename strip<F>::type* fp;
|
||||
};
|
||||
|
||||
template <typename T1>
|
||||
class bound_function_helper<void,T1,void,void,void> : public bound_function_helper_base<T1,void,void,void>
|
||||
{
|
||||
public:
|
||||
void call() const
|
||||
{
|
||||
if (this->mfp) this->mfp(*this->arg1);
|
||||
else if (fp) fp(*this->arg1);
|
||||
}
|
||||
|
||||
void (*fp)(T1);
|
||||
};
|
||||
|
||||
// ----------------
|
||||
|
||||
template <typename F, typename T1, typename T2>
|
||||
class bound_function_helper<F,T1,T2,void,void> : public bound_function_helper_base<T1,T2,void,void>
|
||||
{
|
||||
public:
|
||||
void call() const
|
||||
{
|
||||
(*fp)(*this->arg1, *this->arg2);
|
||||
}
|
||||
|
||||
typename strip<F>::type* fp;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
class bound_function_helper<void,T1,T2,void,void> : public bound_function_helper_base<T1,T2,void,void>
|
||||
{
|
||||
public:
|
||||
void call() const
|
||||
{
|
||||
if (this->mfp) this->mfp(*this->arg1, *this->arg2);
|
||||
else if (fp) fp(*this->arg1, *this->arg2);
|
||||
}
|
||||
|
||||
void (*fp)(T1, T2);
|
||||
};
|
||||
|
||||
// ----------------
|
||||
|
||||
template <typename F, typename T1, typename T2, typename T3>
|
||||
class bound_function_helper<F,T1,T2,T3,void> : public bound_function_helper_base<T1,T2,T3,void>
|
||||
{
|
||||
public:
|
||||
void call() const
|
||||
{
|
||||
(*fp)(*this->arg1, *this->arg2, *this->arg3);
|
||||
}
|
||||
|
||||
typename strip<F>::type* fp;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
class bound_function_helper<void,T1,T2,T3,void> : public bound_function_helper_base<T1,T2,T3,void>
|
||||
{
|
||||
public:
|
||||
|
||||
void call() const
|
||||
{
|
||||
if (this->mfp) this->mfp(*this->arg1, *this->arg2, *this->arg3);
|
||||
else if (fp) fp(*this->arg1, *this->arg2, *this->arg3);
|
||||
}
|
||||
|
||||
void (*fp)(T1, T2, T3);
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
class bound_function_helper_T : public T
|
||||
{
|
||||
public:
|
||||
bound_function_helper_T(){ this->fp = 0;}
|
||||
|
||||
bool is_set() const
|
||||
{
|
||||
return this->fp != 0 || this->mfp.is_set();
|
||||
}
|
||||
|
||||
template <unsigned long mem_size>
|
||||
void safe_clone(stack_based_memory_block<mem_size>& buf)
|
||||
{
|
||||
// This is here just to validate the assumption that our block of memory we have made
|
||||
// in bf_memory is the right size to store the data for this object. If you
|
||||
// get a compiler error on this line then email me :)
|
||||
COMPILE_TIME_ASSERT(sizeof(bound_function_helper_T) <= mem_size);
|
||||
clone(buf.get());
|
||||
}
|
||||
|
||||
void clone (void* ptr) const
|
||||
{
|
||||
bound_function_helper_T* p = new(ptr) bound_function_helper_T();
|
||||
p->arg1 = this->arg1;
|
||||
p->arg2 = this->arg2;
|
||||
p->arg3 = this->arg3;
|
||||
p->arg4 = this->arg4;
|
||||
p->fp = this->fp;
|
||||
p->mfp = this->mfp;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class bound_function_pointer
|
||||
{
|
||||
typedef bfp1_helpers::bound_function_helper_T<bfp1_helpers::bound_function_helper<void,int> > bf_null_type;
|
||||
|
||||
public:
|
||||
|
||||
// These typedefs are here for backwards compatibility with previous versions of
|
||||
// dlib.
|
||||
typedef bound_function_pointer kernel_1a;
|
||||
typedef bound_function_pointer kernel_1a_c;
|
||||
|
||||
|
||||
bound_function_pointer (
|
||||
) { bf_null_type().safe_clone(bf_memory); }
|
||||
|
||||
bound_function_pointer (
|
||||
const bound_function_pointer& item
|
||||
) { item.bf()->clone(bf_memory.get()); }
|
||||
|
||||
~bound_function_pointer()
|
||||
{ destroy_bf_memory(); }
|
||||
|
||||
bound_function_pointer& operator= (
|
||||
const bound_function_pointer& item
|
||||
) { bound_function_pointer(item).swap(*this); return *this; }
|
||||
|
||||
void clear (
|
||||
) { bound_function_pointer().swap(*this); }
|
||||
|
||||
bool is_set (
|
||||
) const
|
||||
{
|
||||
return bf()->is_set();
|
||||
}
|
||||
|
||||
void swap (
|
||||
bound_function_pointer& item
|
||||
)
|
||||
{
|
||||
// make a temp copy of item
|
||||
bound_function_pointer temp(item);
|
||||
|
||||
// destory the stuff in item
|
||||
item.destroy_bf_memory();
|
||||
// copy *this into item
|
||||
bf()->clone(item.bf_memory.get());
|
||||
|
||||
// destory the stuff in this
|
||||
destroy_bf_memory();
|
||||
// copy temp into *this
|
||||
temp.bf()->clone(bf_memory.get());
|
||||
}
|
||||
|
||||
void operator() (
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT(is_set() == true ,
|
||||
"\tvoid bound_function_pointer::operator()"
|
||||
<< "\n\tYou must call set() before you can use this function"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
bf()->call();
|
||||
}
|
||||
|
||||
private:
|
||||
struct dummy{ void nonnull() {}};
|
||||
typedef void (dummy::*safe_bool)();
|
||||
|
||||
public:
|
||||
operator safe_bool () const { return is_set() ? &dummy::nonnull : 0; }
|
||||
bool operator!() const { return !is_set(); }
|
||||
|
||||
// -------------------------------------------
|
||||
// set function object overloads
|
||||
// -------------------------------------------
|
||||
|
||||
template <typename F>
|
||||
void set (
|
||||
F& function_object
|
||||
)
|
||||
{
|
||||
COMPILE_TIME_ASSERT(is_function<F>::value == false);
|
||||
COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
|
||||
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<F> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.fp = &function_object;
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename F, typename A1 >
|
||||
void set (
|
||||
F& function_object,
|
||||
A1& arg1
|
||||
)
|
||||
{
|
||||
COMPILE_TIME_ASSERT(is_function<F>::value == false);
|
||||
COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
|
||||
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<F,A1> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.fp = &function_object;
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename F, typename A1, typename A2 >
|
||||
void set (
|
||||
F& function_object,
|
||||
A1& arg1,
|
||||
A2& arg2
|
||||
)
|
||||
{
|
||||
COMPILE_TIME_ASSERT(is_function<F>::value == false);
|
||||
COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
|
||||
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<F,A1,A2> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.fp = &function_object;
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename F, typename A1, typename A2, typename A3 >
|
||||
void set (
|
||||
F& function_object,
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3
|
||||
)
|
||||
{
|
||||
COMPILE_TIME_ASSERT(is_function<F>::value == false);
|
||||
COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
|
||||
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<F,A1,A2,A3> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.arg3 = &arg3;
|
||||
temp.fp = &function_object;
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename F, typename A1, typename A2, typename A3, typename A4>
|
||||
void set (
|
||||
F& function_object,
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3,
|
||||
A4& arg4
|
||||
)
|
||||
{
|
||||
COMPILE_TIME_ASSERT(is_function<F>::value == false);
|
||||
COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
|
||||
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<F,A1,A2,A3,A4> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.arg3 = &arg3;
|
||||
temp.arg4 = &arg4;
|
||||
temp.fp = &function_object;
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
// set mfp overloads
|
||||
// -------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*funct)()
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.mfp.set(object,funct);
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename T >
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*funct)()const
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.mfp.set(object,funct);
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
|
||||
template <typename T, typename T1, typename A1 >
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*funct)(T1),
|
||||
A1& arg1
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.mfp.set(object,funct);
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename T, typename T1, typename A1 >
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*funct)(T1)const,
|
||||
A1& arg1
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.mfp.set(object,funct);
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
// ----------------
|
||||
|
||||
template <typename T, typename T1, typename A1,
|
||||
typename T2, typename A2>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*funct)(T1, T2),
|
||||
A1& arg1,
|
||||
A2& arg2
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1,T2> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.mfp.set(object,funct);
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename T, typename T1, typename A1,
|
||||
typename T2, typename A2>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*funct)(T1, T2)const,
|
||||
A1& arg1,
|
||||
A2& arg2
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1,T2> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.mfp.set(object,funct);
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
// ----------------
|
||||
|
||||
template <typename T, typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*funct)(T1, T2, T3),
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.arg3 = &arg3;
|
||||
temp.mfp.set(object,funct);
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename T, typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*funct)(T1, T2, T3)const,
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.arg3 = &arg3;
|
||||
temp.mfp.set(object,funct);
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
// ----------------
|
||||
|
||||
template <typename T, typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3,
|
||||
typename T4, typename A4>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*funct)(T1, T2, T3, T4),
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3,
|
||||
A4& arg4
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3,T4> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.arg3 = &arg3;
|
||||
temp.arg4 = &arg4;
|
||||
temp.mfp.set(object,funct);
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename T, typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3,
|
||||
typename T4, typename A4>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*funct)(T1, T2, T3, T4)const,
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3,
|
||||
A4& arg4
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3,T4> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.arg3 = &arg3;
|
||||
temp.arg4 = &arg4;
|
||||
temp.mfp.set(object,funct);
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
// set fp overloads
|
||||
// -------------------------------------------
|
||||
|
||||
void set (
|
||||
void (*funct)()
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.fp = funct;
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename T1, typename A1>
|
||||
void set (
|
||||
void (*funct)(T1),
|
||||
A1& arg1
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.fp = funct;
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename T1, typename A1,
|
||||
typename T2, typename A2>
|
||||
void set (
|
||||
void (*funct)(T1, T2),
|
||||
A1& arg1,
|
||||
A2& arg2
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1,T2> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.fp = funct;
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3>
|
||||
void set (
|
||||
void (*funct)(T1, T2, T3),
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.arg3 = &arg3;
|
||||
temp.fp = funct;
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
template <typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3,
|
||||
typename T4, typename A4>
|
||||
void set (
|
||||
void (*funct)(T1, T2, T3, T4),
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3,
|
||||
A4& arg4
|
||||
)
|
||||
{
|
||||
using namespace bfp1_helpers;
|
||||
destroy_bf_memory();
|
||||
typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3,T4> > bf_helper_type;
|
||||
|
||||
bf_helper_type temp;
|
||||
temp.arg1 = &arg1;
|
||||
temp.arg2 = &arg2;
|
||||
temp.arg3 = &arg3;
|
||||
temp.arg4 = &arg4;
|
||||
temp.fp = funct;
|
||||
|
||||
temp.safe_clone(bf_memory);
|
||||
}
|
||||
|
||||
// -------------------------------------------
|
||||
|
||||
private:
|
||||
|
||||
stack_based_memory_block<sizeof(bf_null_type)> bf_memory;
|
||||
|
||||
void destroy_bf_memory (
|
||||
)
|
||||
{
|
||||
// Honestly, this probably doesn't even do anything but I'm putting
|
||||
// it here just for good measure.
|
||||
bf()->~bound_function_helper_base_base();
|
||||
}
|
||||
|
||||
bfp1_helpers::bound_function_helper_base_base* bf ()
|
||||
{ return static_cast<bfp1_helpers::bound_function_helper_base_base*>(bf_memory.get()); }
|
||||
|
||||
const bfp1_helpers::bound_function_helper_base_base* bf () const
|
||||
{ return static_cast<const bfp1_helpers::bound_function_helper_base_base*>(bf_memory.get()); }
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
inline void swap (
|
||||
bound_function_pointer& a,
|
||||
bound_function_pointer& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_BOUND_FUNCTION_POINTER_KERNEl_1_
|
||||
|
||||
@@ -0,0 +1,456 @@
|
||||
// Copyright (C) 2008 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_BOUND_FUNCTION_POINTER_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_BOUND_FUNCTION_POINTER_KERNEl_ABSTRACT_
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class bound_function_pointer
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
is_set() == false
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents a function with all its arguments bound to
|
||||
specific objects. For example:
|
||||
|
||||
void test(int& var) { var = var+1; }
|
||||
|
||||
bound_function_pointer funct;
|
||||
|
||||
int a = 4;
|
||||
funct.set(test,a); // bind the variable a to the first argument of the test() function
|
||||
|
||||
// at this point a == 4
|
||||
funct();
|
||||
// after funct() is called a == 5
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
bound_function_pointer (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
!*/
|
||||
|
||||
bound_function_pointer(
|
||||
const bound_function_pointer& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- *this == item
|
||||
!*/
|
||||
|
||||
~bound_function_pointer (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- any resources associated with *this have been released
|
||||
!*/
|
||||
|
||||
bound_function_pointer& operator=(
|
||||
const bound_function_pointer& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- *this == item
|
||||
!*/
|
||||
|
||||
void clear(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this has its initial value
|
||||
!*/
|
||||
|
||||
bool is_set (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (this->set() has been called) then
|
||||
- returns true
|
||||
- else
|
||||
- returns false
|
||||
!*/
|
||||
|
||||
operator some_undefined_pointer_type (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (is_set()) then
|
||||
- returns a non 0 value
|
||||
- else
|
||||
- returns a 0 value
|
||||
!*/
|
||||
|
||||
bool operator! (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns !is_set()
|
||||
!*/
|
||||
|
||||
void operator () (
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- is_set() == true
|
||||
ensures
|
||||
- calls the bound function on the object(s) specified by the last
|
||||
call to this->set()
|
||||
throws
|
||||
- any exception thrown by the function specified by
|
||||
the previous call to this->set().
|
||||
If any of these exceptions are thrown then the call to this
|
||||
function will have no effect on *this.
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
bound_function_pointer& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
// ----------------------
|
||||
|
||||
template <typename F>
|
||||
void set (
|
||||
F& function_object
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- function_object() is a valid expression
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call function_object()
|
||||
(This seems pointless but it is a useful base case)
|
||||
!*/
|
||||
|
||||
template < typename T>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*funct)()
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid member function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*funct)()
|
||||
!*/
|
||||
|
||||
template < typename T>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*funct)()const
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid bound function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*funct)()
|
||||
!*/
|
||||
|
||||
void set (
|
||||
void (*funct)()
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid function pointer
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call funct()
|
||||
!*/
|
||||
|
||||
// ----------------------
|
||||
|
||||
template <typename F, typename A1 >
|
||||
void set (
|
||||
F& function_object,
|
||||
A1& arg1
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- function_object(arg1) is a valid expression
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call function_object(arg1)
|
||||
!*/
|
||||
|
||||
template < typename T, typename T1, typename A1 >
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*funct)(T1),
|
||||
A1& arg1
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid member function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*funct)(arg1)
|
||||
!*/
|
||||
|
||||
template < typename T, typename T1, typename A1 >
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*funct)(T1)const,
|
||||
A1& arg1
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid bound function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*funct)(arg1)
|
||||
!*/
|
||||
|
||||
template <typename T1, typename A1>
|
||||
void set (
|
||||
void (*funct)(T1),
|
||||
A1& arg1
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid function pointer
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call funct(arg1)
|
||||
!*/
|
||||
|
||||
// ----------------------
|
||||
template <typename F, typename A1, typename A2 >
|
||||
void set (
|
||||
F& function_object,
|
||||
A1& arg1,
|
||||
A2& arg2
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- function_object(arg1,arg2) is a valid expression
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call function_object(arg1,arg2)
|
||||
!*/
|
||||
|
||||
template < typename T, typename T1, typename A1,
|
||||
typename T2, typename A2>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*funct)(T1,T2),
|
||||
A1& arg1,
|
||||
A2& arg2
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid member function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*funct)(arg1,arg2)
|
||||
!*/
|
||||
|
||||
template < typename T, typename T1, typename A1,
|
||||
typename T2, typename A2>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*funct)(T1,T2)const,
|
||||
A1& arg1,
|
||||
A2& arg2
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid bound function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*funct)(arg1,arg2)
|
||||
!*/
|
||||
|
||||
template <typename T1, typename A1,
|
||||
typename T2, typename A2>
|
||||
void set (
|
||||
void (*funct)(T1,T2),
|
||||
A1& arg1,
|
||||
A2& arg2
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid function pointer
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call funct(arg1,arg2)
|
||||
!*/
|
||||
|
||||
// ----------------------
|
||||
|
||||
template <typename F, typename A1, typename A2, typename A3 >
|
||||
void set (
|
||||
F& function_object,
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- function_object(arg1,arg2,arg3) is a valid expression
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call function_object(arg1,arg2,arg3)
|
||||
!*/
|
||||
|
||||
template < typename T, typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*funct)(T1,T2,T3),
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid member function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*funct)(arg1,arg2,arg3)
|
||||
!*/
|
||||
|
||||
template < typename T, typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*funct)(T1,T2,T3)const,
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid bound function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*funct)(arg1,arg2,arg3)
|
||||
!*/
|
||||
|
||||
template <typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3>
|
||||
void set (
|
||||
void (*funct)(T1,T2,T3),
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid function pointer
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call funct(arg1,arg2,arg3)
|
||||
!*/
|
||||
|
||||
// ----------------------
|
||||
|
||||
template <typename F, typename A1, typename A2, typename A3, typename A4>
|
||||
void set (
|
||||
F& function_object,
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3,
|
||||
A4& arg4
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- function_object(arg1,arg2,arg3,arg4) is a valid expression
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call function_object(arg1,arg2,arg3,arg4)
|
||||
!*/
|
||||
|
||||
template < typename T, typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3,
|
||||
typename T4, typename A4>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*funct)(T1,T2,T3,T4),
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3,
|
||||
A4& arg4
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid member function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*funct)(arg1,arg2,arg3,arg4)
|
||||
!*/
|
||||
|
||||
template < typename T, typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3,
|
||||
typename T4, typename A4>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*funct)(T1,T2,T3,T4)const,
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3,
|
||||
A4& arg4
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid bound function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*funct)(arg1,arg2,arg3,arg4)
|
||||
!*/
|
||||
|
||||
template <typename T1, typename A1,
|
||||
typename T2, typename A2,
|
||||
typename T3, typename A3,
|
||||
typename T4, typename A4>
|
||||
void set (
|
||||
void (*funct)(T1,T2,T3,T4),
|
||||
A1& arg1,
|
||||
A2& arg2,
|
||||
A3& arg3,
|
||||
A4& arg4
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- funct == a valid function pointer
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call funct(arg1,arg2,arg3,arg4)
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
inline void swap (
|
||||
bound_function_pointer& a,
|
||||
bound_function_pointer& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_BOUND_FUNCTION_POINTER_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_BYTE_ORDEREr_
|
||||
#define DLIB_BYTE_ORDEREr_
|
||||
|
||||
|
||||
#include "byte_orderer/byte_orderer_kernel_1.h"
|
||||
|
||||
#endif // DLIB_BYTE_ORDEREr_
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_BYTE_ORDEREr_KERNEL_1_
|
||||
#define DLIB_BYTE_ORDEREr_KERNEL_1_
|
||||
|
||||
#include "byte_orderer_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../assert.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
class byte_orderer
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
- if (this machine is little endian) then
|
||||
- little_endian == true
|
||||
- else
|
||||
- little_endian == false
|
||||
|
||||
CONVENTION
|
||||
- host_is_big_endian() == !little_endian
|
||||
- host_is_little_endian() == little_endian
|
||||
|
||||
- if (this machine is little endian) then
|
||||
- little_endian == true
|
||||
- else
|
||||
- little_endian == false
|
||||
|
||||
|
||||
!*/
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// this is here for backwards compatibility with older versions of dlib.
|
||||
typedef byte_orderer kernel_1a;
|
||||
|
||||
byte_orderer (
|
||||
)
|
||||
{
|
||||
// This will probably never be false but if it is then it means chars are not 8bits
|
||||
// on this system. Which is a problem for this object.
|
||||
COMPILE_TIME_ASSERT(sizeof(short) >= 2);
|
||||
|
||||
unsigned long temp = 1;
|
||||
unsigned char* ptr = reinterpret_cast<unsigned char*>(&temp);
|
||||
if (*ptr == 1)
|
||||
little_endian = true;
|
||||
else
|
||||
little_endian = false;
|
||||
}
|
||||
|
||||
virtual ~byte_orderer (
|
||||
){}
|
||||
|
||||
bool host_is_big_endian (
|
||||
) const { return !little_endian; }
|
||||
|
||||
bool host_is_little_endian (
|
||||
) const { return little_endian; }
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
inline void host_to_network (
|
||||
T& item
|
||||
) const
|
||||
{ if (little_endian) flip(item); }
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
inline void network_to_host (
|
||||
T& item
|
||||
) const { if (little_endian) flip(item); }
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void host_to_big (
|
||||
T& item
|
||||
) const { if (little_endian) flip(item); }
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void big_to_host (
|
||||
T& item
|
||||
) const { if (little_endian) flip(item); }
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void host_to_little (
|
||||
T& item
|
||||
) const { if (!little_endian) flip(item); }
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void little_to_host (
|
||||
T& item
|
||||
) const { if (!little_endian) flip(item); }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
template <
|
||||
typename T,
|
||||
size_t size
|
||||
>
|
||||
inline void flip (
|
||||
T (&array)[size]
|
||||
) const
|
||||
/*!
|
||||
ensures
|
||||
- flips the bytes in every element of this array
|
||||
!*/
|
||||
{
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
flip(array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
inline void flip (
|
||||
T& item
|
||||
) const
|
||||
/*!
|
||||
ensures
|
||||
- reverses the byte ordering in item
|
||||
!*/
|
||||
{
|
||||
DLIB_ASSERT_HAS_STANDARD_LAYOUT(T);
|
||||
|
||||
T value;
|
||||
|
||||
// If you are getting this as an error then you are probably using
|
||||
// this object wrong. If you think you aren't then send me (Davis) an
|
||||
// email and I'll either set you straight or change/remove this check so
|
||||
// your stuff works :)
|
||||
COMPILE_TIME_ASSERT(sizeof(T) <= sizeof(long double));
|
||||
|
||||
// If you are getting a compile error on this line then it means T is
|
||||
// a pointer type. It doesn't make any sense to byte swap pointers
|
||||
// since they have no meaning outside the context of their own process.
|
||||
// So you probably just forgot to dereference that pointer before passing
|
||||
// it to this function :)
|
||||
COMPILE_TIME_ASSERT(is_pointer_type<T>::value == false);
|
||||
|
||||
|
||||
const size_t size = sizeof(T);
|
||||
unsigned char* const ptr = reinterpret_cast<unsigned char*>(&item);
|
||||
unsigned char* const ptr_temp = reinterpret_cast<unsigned char*>(&value);
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
ptr_temp[size-i-1] = ptr[i];
|
||||
|
||||
item = value;
|
||||
}
|
||||
|
||||
bool little_endian;
|
||||
};
|
||||
|
||||
// make flip not do anything at all for chars
|
||||
template <> inline void byte_orderer::flip<char> ( char& ) const {}
|
||||
template <> inline void byte_orderer::flip<unsigned char> ( unsigned char& ) const {}
|
||||
template <> inline void byte_orderer::flip<signed char> ( signed char& ) const {}
|
||||
}
|
||||
|
||||
#endif // DLIB_BYTE_ORDEREr_KERNEL_1_
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_BYTE_ORDEREr_ABSTRACT_
|
||||
#ifdef DLIB_BYTE_ORDEREr_ABSTRACT_
|
||||
|
||||
#include "../algs.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
class byte_orderer
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
This object has no state.
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object simply provides a mechanism to convert data from a
|
||||
host machine's own byte ordering to big or little endian and to
|
||||
also do the reverse.
|
||||
|
||||
It also provides a pair of functions to convert to/from network byte
|
||||
order where network byte order is big endian byte order. This pair of
|
||||
functions does the exact same thing as the host_to_big() and big_to_host()
|
||||
functions and is provided simply so that client code can use the most
|
||||
self documenting name appropriate.
|
||||
|
||||
Also note that this object is capable of correctly flipping the contents
|
||||
of arrays when the arrays are declared on the stack. e.g. You can
|
||||
say things like:
|
||||
int array[10];
|
||||
bo.host_to_network(array);
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
byte_orderer (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
virtual ~byte_orderer (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- any resources associated with *this have been released
|
||||
!*/
|
||||
|
||||
bool host_is_big_endian (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (the host computer is a big endian machine) then
|
||||
- returns true
|
||||
- else
|
||||
- returns false
|
||||
!*/
|
||||
|
||||
bool host_is_little_endian (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (the host computer is a little endian machine) then
|
||||
- returns true
|
||||
- else
|
||||
- returns false
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void host_to_network (
|
||||
T& item
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- #item == the value of item converted from host byte order
|
||||
to network byte order.
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void network_to_host (
|
||||
T& item
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- #item == the value of item converted from network byte order
|
||||
to host byte order.
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void host_to_big (
|
||||
T& item
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- #item == the value of item converted from host byte order
|
||||
to big endian byte order.
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void big_to_host (
|
||||
T& item
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- #item == the value of item converted from big endian byte order
|
||||
to host byte order.
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void host_to_little (
|
||||
T& item
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- #item == the value of item converted from host byte order
|
||||
to little endian byte order.
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void little_to_host (
|
||||
T& item
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- #item == the value of item converted from little endian byte order
|
||||
to host byte order.
|
||||
!*/
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_BYTE_ORDEREr_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlib_include_path_tutorial.txt"
|
||||
34
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/config.h
vendored
Normal file
34
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/config.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
// If you are compiling dlib as a shared library and installing it somewhere on your system
|
||||
// then it is important that any programs that use dlib agree on the state of the
|
||||
// DLIB_ASSERT statements (i.e. they are either always on or always off). Therefore,
|
||||
// uncomment one of the following lines to force all DLIB_ASSERTs to either always on or
|
||||
// always off. If you don't define one of these two macros then DLIB_ASSERT will toggle
|
||||
// automatically depending on the state of certain other macros, which is not what you want
|
||||
// when creating a shared library.
|
||||
// #define ENABLE_ASSERTS // asserts always enabled
|
||||
/* #undef DLIB_DISABLE_ASSERTS */
|
||||
|
||||
/* #undef DLIB_ISO_CPP_ONLY */
|
||||
/* #undef DLIB_NO_GUI_SUPPORT */
|
||||
#define DLIB_ENABLE_STACK_TRACE
|
||||
|
||||
#define LAPACK_FORCE_UNDERSCORE
|
||||
/* #undef LAPACK_FORCE_NOUNDERSCORE */
|
||||
|
||||
// You should also consider telling dlib to link against libjpeg, libpng, libgif, fftw, CUDA,
|
||||
// and a BLAS and LAPACK library. To do this you need to uncomment the following #defines.
|
||||
#define DLIB_JPEG_SUPPORT
|
||||
#define DLIB_PNG_SUPPORT
|
||||
/* #undef DLIB_GIF_SUPPORT */
|
||||
/* #undef DLIB_USE_FFTW */
|
||||
#define DLIB_USE_BLAS
|
||||
#define DLIB_USE_LAPACK
|
||||
/* #undef DLIB_USE_CUDA */
|
||||
/* #undef DLIB_USE_MKL_FFT */
|
||||
|
||||
// This variable allows dlib/test_for_odr_violations.h to catch people who mistakenly use
|
||||
// headers from one version of dlib with a compiled dlib binary from a different dlib version.
|
||||
// #define DLIB_CHECK_FOR_VERSION_MISMATCH DLIB_VERSION_MISMATCH_CHECK__EXPECTED_VERSION_19_21_99
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
// Copyright (C) 2010 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_CONSOLE_PROGRESS_INDiCATOR_Hh_
|
||||
#define DLIB_CONSOLE_PROGRESS_INDiCATOR_Hh_
|
||||
|
||||
#include <ctime>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class console_progress_indicator
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object is a tool for reporting how long a task will take
|
||||
to complete.
|
||||
|
||||
For example, consider the following bit of code:
|
||||
|
||||
console_progress_indicator pbar(100)
|
||||
for (int i = 1; i <= 100; ++i)
|
||||
{
|
||||
pbar.print_status(i);
|
||||
long_running_operation();
|
||||
}
|
||||
|
||||
The above code will print a message to the console each iteration
|
||||
which shows how much time is remaining until the loop terminates.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
inline explicit console_progress_indicator (
|
||||
double target_value
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #target() == target_value
|
||||
!*/
|
||||
|
||||
inline void reset (
|
||||
double target_value
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #target() == target_value
|
||||
- performs the equivalent of:
|
||||
*this = console_progress_indicator(target_value)
|
||||
(i.e. resets this object with a new target value)
|
||||
|
||||
!*/
|
||||
|
||||
inline double target (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- This object attempts to measure how much time is
|
||||
left until we reach a certain targeted value. This
|
||||
function returns that targeted value.
|
||||
!*/
|
||||
|
||||
inline bool print_status (
|
||||
double cur,
|
||||
bool always_print = false
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- print_status() assumes it is called with values which are linearly
|
||||
approaching target(). It will attempt to predict how much time is
|
||||
remaining until cur becomes equal to target().
|
||||
- prints a status message to the screen which indicates how much
|
||||
more time is left until cur is equal to target()
|
||||
- if (always_print) then
|
||||
- This function prints to the screen each time it is called.
|
||||
- else
|
||||
- This function throttles the printing so that at most 1 message is
|
||||
printed each second. Note that it won't print anything to the screen
|
||||
until about one second has elapsed. This means that the first call
|
||||
to print_status() never prints to the screen.
|
||||
- This function returns true if it prints to the screen and false
|
||||
otherwise.
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
double target_val;
|
||||
|
||||
time_t start_time;
|
||||
double first_val;
|
||||
double seen_first_val;
|
||||
time_t last_time;
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// IMPLEMENTATION DETAILS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
console_progress_indicator::
|
||||
console_progress_indicator (
|
||||
double target_value
|
||||
) :
|
||||
target_val(target_value),
|
||||
start_time(0),
|
||||
first_val(0),
|
||||
seen_first_val(false),
|
||||
last_time(0)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
bool console_progress_indicator::
|
||||
print_status (
|
||||
double cur,
|
||||
bool always_print
|
||||
)
|
||||
{
|
||||
const time_t cur_time = std::time(0);
|
||||
|
||||
// if this is the first time print_status has been called
|
||||
// then collect some information and exit. We will print status
|
||||
// on the next call.
|
||||
if (!seen_first_val)
|
||||
{
|
||||
start_time = cur_time;
|
||||
last_time = cur_time;
|
||||
first_val = cur;
|
||||
seen_first_val = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cur_time != last_time || always_print)
|
||||
{
|
||||
last_time = cur_time;
|
||||
double delta_t = static_cast<double>(cur_time - start_time);
|
||||
double delta_val = std::abs(cur - first_val);
|
||||
|
||||
// don't do anything if cur is equal to first_val
|
||||
if (delta_val < std::numeric_limits<double>::epsilon())
|
||||
return false;
|
||||
|
||||
double seconds = delta_t/delta_val * std::abs(target_val - cur);
|
||||
|
||||
std::ios::fmtflags oldflags = std::cout.flags();
|
||||
|
||||
std::cout.setf(std::ios::fixed,std::ios::floatfield);
|
||||
std::streamsize ss;
|
||||
|
||||
if (seconds < 60)
|
||||
{
|
||||
ss = std::cout.precision(0);
|
||||
std::cout << "Time remaining: " << seconds << " seconds. \r" << std::flush;
|
||||
}
|
||||
else if (seconds < 60*60)
|
||||
{
|
||||
ss = std::cout.precision(2);
|
||||
std::cout << "Time remaining: " << seconds/60 << " minutes. \r" << std::flush;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss = std::cout.precision(2);
|
||||
std::cout << "Time remaining: " << seconds/60/60 << " hours. \r" << std::flush;
|
||||
}
|
||||
|
||||
// restore previous output flags and precision settings
|
||||
std::cout.flags(oldflags);
|
||||
std::cout.precision(ss);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
double console_progress_indicator::
|
||||
target (
|
||||
) const
|
||||
{
|
||||
return target_val;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void console_progress_indicator::
|
||||
reset (
|
||||
double target_value
|
||||
)
|
||||
{
|
||||
*this = console_progress_indicator(target_value);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_CONSOLE_PROGRESS_INDiCATOR_Hh_
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlib_include_path_tutorial.txt"
|
||||
@@ -0,0 +1,13 @@
|
||||
#error "Don't write #include <dlib/all/source.cpp> in your code."
|
||||
/*
|
||||
In C++, it is generally an error to #include .cpp files. This is because it
|
||||
can lead to what are called multiply defined symbol errors. Therefore, you
|
||||
should compile dlib/all/source.cpp into your application just like you would
|
||||
compile any other .cpp file.
|
||||
|
||||
If you are using Visual Studio you add .cpp files to your application using
|
||||
the solution explorer window. Specifically, right click on Source Files,
|
||||
then select Add -> Existing Item and select the .cpp files you want to add.
|
||||
|
||||
For general information on compiling dlib see http://dlib.net/compile.html
|
||||
*/
|
||||
@@ -0,0 +1,20 @@
|
||||
#error "Don't put the dlib folder in your include path"
|
||||
/*
|
||||
You are getting this error because you have added the dlib folder to your
|
||||
compiler's include search path.
|
||||
|
||||
You should *NOT* add the dlib folder itself to your compiler's include path.
|
||||
Doing so will cause the build to fail because of name collisions (such as
|
||||
dlib/string.h and string.h from the standard library). Instead you should
|
||||
add the folder that contains the dlib folder to your include search path
|
||||
and then use include statements of the form #include <dlib/queue.h> or
|
||||
#include "dlib/queue.h". This will ensure that everything builds correctly.
|
||||
|
||||
XCode:
|
||||
The XCode IDE often puts all folders that it knows about into
|
||||
the compiler search path. So if you are using XCode then either
|
||||
don't drag the whole dlib folder into the project or alternatively
|
||||
modify your XCode project settings to not auto-add all folders to
|
||||
the include path. Instead just make sure that the dlib folder is
|
||||
itself inside a folder in your include path.
|
||||
*/
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2003 (C) The Trustees of Indiana University.
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
|
||||
// Jeremiah Willcock (jewillco at osl.iu.edu)
|
||||
// Andrew Lumsdaine (lums at osl.iu.edu)
|
||||
#ifndef DLIB_BOOST_UTILITY_ENABLE_IF_HPP
|
||||
#define DLIB_BOOST_UTILITY_ENABLE_IF_HPP
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <bool B, class T = void>
|
||||
struct enable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct enable_if_c<false, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct enable_if : public enable_if_c<Cond::value, T> {};
|
||||
|
||||
template <bool B, class T>
|
||||
struct lazy_enable_if_c {
|
||||
typedef typename T::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct lazy_enable_if_c<false, T> {};
|
||||
|
||||
template <class Cond, class T>
|
||||
struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
|
||||
|
||||
|
||||
template <bool B, class T = void>
|
||||
struct disable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct disable_if_c<true, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct disable_if : public disable_if_c<Cond::value, T> {};
|
||||
|
||||
template <bool B, class T>
|
||||
struct lazy_disable_if_c {
|
||||
typedef typename T::type type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct lazy_disable_if_c<true, T> {};
|
||||
|
||||
template <class Cond, class T>
|
||||
struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
|
||||
|
||||
} // namespace dlib
|
||||
|
||||
#endif // DLIB_BOOST_UTILITY_ENABLE_IF_HPP
|
||||
|
||||
449
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/error.h
vendored
Normal file
449
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/error.h
vendored
Normal file
@@ -0,0 +1,449 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_ERROr_
|
||||
#define DLIB_ERROr_
|
||||
|
||||
#include <string>
|
||||
#include <new> // for std::bad_alloc
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <exception>
|
||||
|
||||
// -------------------------------
|
||||
// ------ exception classes ------
|
||||
// -------------------------------
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
enum error_type
|
||||
{
|
||||
EPORT_IN_USE,
|
||||
ETIMEOUT,
|
||||
ECONNECTION,
|
||||
ELISTENER,
|
||||
ERESOLVE,
|
||||
EMONITOR,
|
||||
ECREATE_THREAD,
|
||||
ECREATE_MUTEX,
|
||||
ECREATE_SIGNALER,
|
||||
EUNSPECIFIED,
|
||||
EGENERAL_TYPE1,
|
||||
EGENERAL_TYPE2,
|
||||
EGENERAL_TYPE3,
|
||||
EINVALID_OPTION,
|
||||
ETOO_FEW_ARGS,
|
||||
ETOO_MANY_ARGS,
|
||||
ESOCKET,
|
||||
ETHREAD,
|
||||
EGUI,
|
||||
EFATAL,
|
||||
EBROKEN_ASSERT,
|
||||
EIMAGE_LOAD,
|
||||
EDIR_CREATE,
|
||||
EINCOMPATIBLE_OPTIONS,
|
||||
EMISSING_REQUIRED_OPTION,
|
||||
EINVALID_OPTION_ARG,
|
||||
EMULTIPLE_OCCURANCES,
|
||||
ECONFIG_READER,
|
||||
EIMAGE_SAVE,
|
||||
ECAST_TO_STRING,
|
||||
ESTRING_CAST,
|
||||
EUTF8_TO_UTF32,
|
||||
EOPTION_PARSE
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
// the base exception class
|
||||
class error : public std::exception
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This is the base exception class for the dlib library. i.e. all
|
||||
exceptions in this library inherit from this class.
|
||||
!*/
|
||||
|
||||
public:
|
||||
error(
|
||||
error_type t,
|
||||
const std::string& a
|
||||
): info(a), type(t) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == t
|
||||
- #info == a
|
||||
!*/
|
||||
|
||||
error(
|
||||
error_type t
|
||||
): type(t) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == t
|
||||
- #info == ""
|
||||
!*/
|
||||
|
||||
error(
|
||||
const std::string& a
|
||||
): info(a), type(EUNSPECIFIED) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == EUNSPECIFIED
|
||||
- #info == a
|
||||
!*/
|
||||
|
||||
error(
|
||||
): type(EUNSPECIFIED) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == EUNSPECIFIED
|
||||
- #info == ""
|
||||
!*/
|
||||
|
||||
virtual ~error(
|
||||
) throw() {}
|
||||
/*!
|
||||
ensures
|
||||
- does nothing
|
||||
!*/
|
||||
|
||||
const char* what(
|
||||
) const throw()
|
||||
/*!
|
||||
ensures
|
||||
- if (info.size() != 0) then
|
||||
- returns info.c_str()
|
||||
- else
|
||||
- returns type_to_string(type)
|
||||
!*/
|
||||
{
|
||||
if (info.size() > 0)
|
||||
return info.c_str();
|
||||
else
|
||||
return type_to_string();
|
||||
}
|
||||
|
||||
const char* type_to_string (
|
||||
) const throw()
|
||||
/*!
|
||||
ensures
|
||||
- returns a string that names the contents of the type member.
|
||||
!*/
|
||||
{
|
||||
if ( type == EPORT_IN_USE) return "EPORT_IN_USE";
|
||||
else if ( type == ETIMEOUT) return "ETIMEOUT";
|
||||
else if ( type == ECONNECTION) return "ECONNECTION";
|
||||
else if ( type == ELISTENER) return "ELISTENER";
|
||||
else if ( type == ERESOLVE) return "ERESOLVE";
|
||||
else if ( type == EMONITOR) return "EMONITOR";
|
||||
else if ( type == ECREATE_THREAD) return "ECREATE_THREAD";
|
||||
else if ( type == ECREATE_MUTEX) return "ECREATE_MUTEX";
|
||||
else if ( type == ECREATE_SIGNALER) return "ECREATE_SIGNALER";
|
||||
else if ( type == EUNSPECIFIED) return "EUNSPECIFIED";
|
||||
else if ( type == EGENERAL_TYPE1) return "EGENERAL_TYPE1";
|
||||
else if ( type == EGENERAL_TYPE2) return "EGENERAL_TYPE2";
|
||||
else if ( type == EGENERAL_TYPE3) return "EGENERAL_TYPE3";
|
||||
else if ( type == EINVALID_OPTION) return "EINVALID_OPTION";
|
||||
else if ( type == ETOO_FEW_ARGS) return "ETOO_FEW_ARGS";
|
||||
else if ( type == ETOO_MANY_ARGS) return "ETOO_MANY_ARGS";
|
||||
else if ( type == ESOCKET) return "ESOCKET";
|
||||
else if ( type == ETHREAD) return "ETHREAD";
|
||||
else if ( type == EGUI) return "EGUI";
|
||||
else if ( type == EFATAL) return "EFATAL";
|
||||
else if ( type == EBROKEN_ASSERT) return "EBROKEN_ASSERT";
|
||||
else if ( type == EIMAGE_LOAD) return "EIMAGE_LOAD";
|
||||
else if ( type == EDIR_CREATE) return "EDIR_CREATE";
|
||||
else if ( type == EINCOMPATIBLE_OPTIONS) return "EINCOMPATIBLE_OPTIONS";
|
||||
else if ( type == EMISSING_REQUIRED_OPTION) return "EMISSING_REQUIRED_OPTION";
|
||||
else if ( type == EINVALID_OPTION_ARG) return "EINVALID_OPTION_ARG";
|
||||
else if ( type == EMULTIPLE_OCCURANCES) return "EMULTIPLE_OCCURANCES";
|
||||
else if ( type == ECONFIG_READER) return "ECONFIG_READER";
|
||||
else if ( type == EIMAGE_SAVE) return "EIMAGE_SAVE";
|
||||
else if ( type == ECAST_TO_STRING) return "ECAST_TO_STRING";
|
||||
else if ( type == ESTRING_CAST) return "ESTRING_CAST";
|
||||
else if ( type == EUTF8_TO_UTF32) return "EUTF8_TO_UTF32";
|
||||
else if ( type == EOPTION_PARSE) return "EOPTION_PARSE";
|
||||
else return "undefined error type";
|
||||
}
|
||||
|
||||
const std::string info; // info about the error
|
||||
const error_type type; // the type of the error
|
||||
|
||||
private:
|
||||
const error& operator=(const error&);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class fatal_error : public error
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
As the name says, this object represents some kind of fatal error.
|
||||
That is, it represents an unrecoverable error and any program that
|
||||
throws this exception is, by definition, buggy and needs to be fixed.
|
||||
|
||||
Note that a fatal_error exception can only be thrown once. The second
|
||||
time an application attempts to construct a fatal_error it will be
|
||||
immediately aborted and an error message will be printed to std::cerr.
|
||||
The reason for this is because the first fatal_error was apparently ignored
|
||||
so the second fatal_error is going to make itself impossible to ignore
|
||||
by calling abort. The lesson here is that you should not try to ignore
|
||||
fatal errors.
|
||||
|
||||
This is also the exception thrown by the DLIB_ASSERT and DLIB_CASSERT macros.
|
||||
!*/
|
||||
|
||||
public:
|
||||
fatal_error(
|
||||
error_type t,
|
||||
const std::string& a
|
||||
): error(t,a) {check_for_previous_fatal_errors();}
|
||||
/*!
|
||||
ensures
|
||||
- #type == t
|
||||
- #info == a
|
||||
!*/
|
||||
|
||||
fatal_error(
|
||||
error_type t
|
||||
): error(t) {check_for_previous_fatal_errors();}
|
||||
/*!
|
||||
ensures
|
||||
- #type == t
|
||||
- #info == ""
|
||||
!*/
|
||||
|
||||
fatal_error(
|
||||
const std::string& a
|
||||
): error(EFATAL,a) {check_for_previous_fatal_errors();}
|
||||
/*!
|
||||
ensures
|
||||
- #type == EFATAL
|
||||
- #info == a
|
||||
!*/
|
||||
|
||||
fatal_error(
|
||||
): error(EFATAL) {check_for_previous_fatal_errors();}
|
||||
/*!
|
||||
ensures
|
||||
- #type == EFATAL
|
||||
- #info == ""
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
static inline char* message ()
|
||||
{
|
||||
static char buf[2000];
|
||||
buf[1999] = '\0'; // just to be extra safe
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline void dlib_fatal_error_terminate (
|
||||
)
|
||||
{
|
||||
std::cerr << "\n**************************** FATAL ERROR DETECTED ****************************";
|
||||
std::cerr << message() << std::endl;
|
||||
std::cerr << "******************************************************************************\n" << std::endl;
|
||||
}
|
||||
|
||||
void check_for_previous_fatal_errors()
|
||||
{
|
||||
// If dlib is being use to create plugins for some other application, like
|
||||
// MATLAB, then don't do these checks since it terminates the over arching
|
||||
// system. Just let the errors go to the plugin handler and it will deal with
|
||||
// them.
|
||||
#if defined(MATLAB_MEX_FILE) || defined(DLIB_NO_ABORT_ON_2ND_FATAL_ERROR)
|
||||
return;
|
||||
#else
|
||||
static bool is_first_fatal_error = true;
|
||||
if (is_first_fatal_error == false)
|
||||
{
|
||||
std::cerr << "\n\n ************************** FATAL ERROR DETECTED ************************** " << std::endl;
|
||||
std::cerr << " ************************** FATAL ERROR DETECTED ************************** " << std::endl;
|
||||
std::cerr << " ************************** FATAL ERROR DETECTED ************************** \n" << std::endl;
|
||||
std::cerr << "Two fatal errors have been detected, the first was inappropriately ignored. \n"
|
||||
<< "To prevent further fatal errors from being ignored this application will be \n"
|
||||
<< "terminated immediately and you should go fix this buggy program.\n\n"
|
||||
<< "The error message from this fatal error was:\n" << this->what() << "\n\n" << std::endl;
|
||||
using namespace std;
|
||||
assert(false);
|
||||
abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy the message into the fixed message buffer so that it can be recalled by dlib_fatal_error_terminate
|
||||
// if needed.
|
||||
char* msg = message();
|
||||
unsigned long i;
|
||||
for (i = 0; i < 2000-1 && i < this->info.size(); ++i)
|
||||
msg[i] = info[i];
|
||||
msg[i] = '\0';
|
||||
|
||||
// set this termination handler so that if the user doesn't catch this dlib::fatal_error that is being
|
||||
// thrown then it will eventually be printed to standard error
|
||||
std::set_terminate(&dlib_fatal_error_terminate);
|
||||
}
|
||||
is_first_fatal_error = false;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class gui_error : public error
|
||||
{
|
||||
public:
|
||||
gui_error(
|
||||
error_type t,
|
||||
const std::string& a
|
||||
): error(t,a) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == t
|
||||
- #info == a
|
||||
!*/
|
||||
|
||||
gui_error(
|
||||
error_type t
|
||||
): error(t) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == t
|
||||
- #info == ""
|
||||
!*/
|
||||
|
||||
gui_error(
|
||||
const std::string& a
|
||||
): error(EGUI,a) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == EGUI
|
||||
- #info == a
|
||||
!*/
|
||||
|
||||
gui_error(
|
||||
): error(EGUI) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == EGUI
|
||||
- #info == ""
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class socket_error : public error
|
||||
{
|
||||
public:
|
||||
socket_error(
|
||||
error_type t,
|
||||
const std::string& a
|
||||
): error(t,a) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == t
|
||||
- #info == a
|
||||
!*/
|
||||
|
||||
socket_error(
|
||||
error_type t
|
||||
): error(t) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == t
|
||||
- #info == ""
|
||||
!*/
|
||||
|
||||
socket_error(
|
||||
const std::string& a
|
||||
): error(ESOCKET,a) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == ESOCKET
|
||||
- #info == a
|
||||
!*/
|
||||
|
||||
socket_error(
|
||||
): error(ESOCKET) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == ESOCKET
|
||||
- #info == ""
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class thread_error : public error
|
||||
{
|
||||
public:
|
||||
thread_error(
|
||||
error_type t,
|
||||
const std::string& a
|
||||
): error(t,a) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == t
|
||||
- #info == a
|
||||
!*/
|
||||
|
||||
thread_error(
|
||||
error_type t
|
||||
): error(t) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == t
|
||||
- #info == ""
|
||||
!*/
|
||||
|
||||
thread_error(
|
||||
const std::string& a
|
||||
): error(ETHREAD,a) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == ETHREAD
|
||||
- #info == a
|
||||
!*/
|
||||
|
||||
thread_error(
|
||||
): error(ETHREAD) {}
|
||||
/*!
|
||||
ensures
|
||||
- #type == ETHREAD
|
||||
- #info == ""
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class impossible_labeling_error : public dlib::error
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This is the exception thrown by code that trains object detectors (e.g.
|
||||
structural_svm_object_detection_problem) when they detect that the set of
|
||||
truth boxes given to the training algorithm contains some impossible to
|
||||
obtain outputs.
|
||||
|
||||
This kind of problem can happen when the set of image positions scanned by
|
||||
the underlying object detection method doesn't include the truth rectangle
|
||||
as a possible output. Another possibility is when two truth boxes are very
|
||||
close together and hard coded non-max suppression logic would prevent two
|
||||
boxes in such close proximity from being output.
|
||||
!*/
|
||||
public:
|
||||
impossible_labeling_error(const std::string& msg) : dlib::error(msg) {};
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_ERROr_
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
// Copyright (C) 2013 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_FLOAT_DEtAILS_Hh_
|
||||
#define DLIB_FLOAT_DEtAILS_Hh_
|
||||
|
||||
#include <cmath>
|
||||
#include "algs.h"
|
||||
#include <limits>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
struct float_details
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object is a tool for converting floating point numbers into an
|
||||
explicit integer representation and then also converting back. In
|
||||
particular, a float_details object represents a floating point number with
|
||||
a 64 bit mantissa and 16 bit exponent. These are stored in the public
|
||||
fields of the same names.
|
||||
|
||||
The main use of this object is to convert floating point values into a
|
||||
known uniform representation so they can be serialized to an output stream.
|
||||
This allows dlib serialization code to work on any system, regardless of
|
||||
the floating point representation used by the hardware. It also means
|
||||
that, for example, a double can be serialized and then deserialized into a
|
||||
float and it will perform the appropriate conversion.
|
||||
|
||||
|
||||
In more detail, this object represents a floating point value equal to
|
||||
mantissa*pow(2,exponent), except when exponent takes on any of the
|
||||
following special values:
|
||||
- is_inf
|
||||
- is_ninf
|
||||
- is_nan
|
||||
These values are used to indicate that the floating point value should be
|
||||
either infinity, negative infinity, or not-a-number respectively.
|
||||
!*/
|
||||
|
||||
float_details(
|
||||
int64 man,
|
||||
int16 exp
|
||||
) : mantissa(man), exponent(exp) {}
|
||||
/*!
|
||||
ensures
|
||||
- #mantissa == man
|
||||
- #exponent == exp
|
||||
!*/
|
||||
|
||||
float_details() :
|
||||
mantissa(0), exponent(0)
|
||||
{}
|
||||
/*!
|
||||
ensures
|
||||
- this object represents a floating point value of 0
|
||||
!*/
|
||||
|
||||
float_details ( const double& val) { *this = val; }
|
||||
float_details ( const float& val) { *this = val; }
|
||||
float_details ( const long double& val) { *this = val; }
|
||||
/*!
|
||||
ensures
|
||||
- converts the given value into a float_details representation. This
|
||||
means that converting #*this back into a floating point number should
|
||||
recover the input val.
|
||||
!*/
|
||||
|
||||
float_details& operator= ( const double& val) { convert_from_T(val); return *this; }
|
||||
float_details& operator= ( const float& val) { convert_from_T(val); return *this; }
|
||||
float_details& operator= ( const long double& val) { convert_from_T(val); return *this; }
|
||||
/*!
|
||||
ensures
|
||||
- converts the given value into a float_details representation. This
|
||||
means that converting #*this back into a floating point number should
|
||||
recover the input val.
|
||||
!*/
|
||||
|
||||
operator double () const { return convert_to_T<double>(); }
|
||||
operator float () const { return convert_to_T<float>(); }
|
||||
operator long double () const { return convert_to_T<long double>(); }
|
||||
/*!
|
||||
ensures
|
||||
- converts the contents of this float_details object into a floating point number.
|
||||
!*/
|
||||
|
||||
const static int16 is_inf = 32000;
|
||||
const static int16 is_ninf = 32001;
|
||||
const static int16 is_nan = 32002;
|
||||
|
||||
int64 mantissa;
|
||||
int16 exponent;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// IMPLEMENTATION DETAILS
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
void convert_from_T (
|
||||
const T& val
|
||||
)
|
||||
{
|
||||
mantissa = 0;
|
||||
|
||||
const int digits = dlib::tmin<std::numeric_limits<T>::digits, 63>::value;
|
||||
|
||||
if (val == std::numeric_limits<T>::infinity())
|
||||
{
|
||||
exponent = is_inf;
|
||||
}
|
||||
else if (val == -std::numeric_limits<T>::infinity())
|
||||
{
|
||||
exponent = is_ninf;
|
||||
}
|
||||
else if (val < std::numeric_limits<T>::infinity())
|
||||
{
|
||||
int exp;
|
||||
mantissa = static_cast<int64>(std::frexp(val, &exp)*(((uint64)1)<<digits));
|
||||
exponent = exp - digits;
|
||||
|
||||
// Compact the representation a bit by shifting off any low order bytes
|
||||
// which are zero in the mantissa. This makes the numbers in mantissa and
|
||||
// exponent generally smaller which can make serialization and other things
|
||||
// more efficient in some cases.
|
||||
for (int i = 0; i < 8 && ((mantissa&0xFF)==0); ++i)
|
||||
{
|
||||
mantissa >>= 8;
|
||||
exponent += 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exponent = is_nan;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T convert_to_T (
|
||||
) const
|
||||
{
|
||||
if (exponent < is_inf)
|
||||
return std::ldexp((T)mantissa, exponent);
|
||||
else if (exponent == is_inf)
|
||||
return std::numeric_limits<T>::infinity();
|
||||
else if (exponent == is_ninf)
|
||||
return -std::numeric_limits<T>::infinity();
|
||||
else
|
||||
return std::numeric_limits<T>::quiet_NaN();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_FLOAT_DEtAILS_Hh_
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlib_include_path_tutorial.txt"
|
||||
14
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/hash.h
vendored
Normal file
14
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/hash.h
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_HASh_
|
||||
#define DLIB_HASh_
|
||||
|
||||
|
||||
#include "general_hash/hash.h"
|
||||
#include "general_hash/random_hashing.h"
|
||||
#include "general_hash/count_bits.h"
|
||||
|
||||
|
||||
#endif // DLIB_HASh_
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_CMD_LINE_PARSER_OPTIOn_
|
||||
#define DLIB_CMD_LINE_PARSER_OPTIOn_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename charT
|
||||
>
|
||||
class cmd_line_parser_option
|
||||
{
|
||||
/*!
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
None of the functions in cmd_line_parser_option will invalidate
|
||||
pointers or references to internal data when called.
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents a command line option.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef charT char_type;
|
||||
typedef std::basic_string<charT> string_type;
|
||||
|
||||
virtual ~cmd_line_parser_option (
|
||||
) = 0;
|
||||
|
||||
virtual const string_type& name (
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- returns the name of this option
|
||||
!*/
|
||||
|
||||
virtual const string_type& group_name (
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- returns the name of the group this option is in. If no group was set for
|
||||
this option then this function returns "".
|
||||
!*/
|
||||
|
||||
virtual const string_type& description (
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- returns the description for this option
|
||||
!*/
|
||||
|
||||
virtual unsigned long number_of_arguments(
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of arguments for this option
|
||||
!*/
|
||||
|
||||
virtual unsigned long count(
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of times this option appears on the command line.
|
||||
!*/
|
||||
|
||||
virtual const string_type& argument (
|
||||
unsigned long arg = 0,
|
||||
unsigned long N = 0
|
||||
) const = 0;
|
||||
/*!
|
||||
requires
|
||||
- arg < number_of_arguments()
|
||||
- N < count()
|
||||
ensures
|
||||
- returns the arg-th argument to the Nth occurrence of this
|
||||
option on the command line.
|
||||
!*/
|
||||
|
||||
inline operator bool (
|
||||
) const { return count() > 0; }
|
||||
/*!
|
||||
ensures
|
||||
- returns true if this option appears on the command line at all
|
||||
!*/
|
||||
|
||||
protected:
|
||||
|
||||
// restricted functions
|
||||
cmd_line_parser_option& operator=(const cmd_line_parser_option&){return *this;}
|
||||
|
||||
};
|
||||
|
||||
// destructor does nothing
|
||||
template < typename charT >
|
||||
cmd_line_parser_option<charT>::~cmd_line_parser_option() {}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_CMD_LINE_PARSER_OPTIOn_
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_ENUMERABLe_INTERFACE_
|
||||
#define DLIB_ENUMERABLe_INTERFACE_
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class enumerable
|
||||
{
|
||||
/*!
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
- if (at_start()) then
|
||||
- all pointers and references to data returned via element() are
|
||||
invalid.
|
||||
- calling move_next() or reset() invalidates pointers and references to
|
||||
data returned via element() and only data returned via element().
|
||||
- calling at_start(), current_element_valid(), size(), or element()
|
||||
does NOT invalidate pointers or references to any internal data.
|
||||
|
||||
INITIAL VALUE
|
||||
current_element_valid() == false
|
||||
at_start() == true
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represent an interface for iterating through the
|
||||
elements in a container. It starts out one before the first element
|
||||
in the container.
|
||||
|
||||
|
||||
EXAMPLE: The following loops though all elements in the container
|
||||
and prints them to cout.
|
||||
|
||||
container.reset();
|
||||
while(container.move_next()) {
|
||||
cout << container.element();
|
||||
}
|
||||
!*/
|
||||
|
||||
public:
|
||||
typedef T type;
|
||||
|
||||
inline virtual ~enumerable(
|
||||
) = 0;
|
||||
|
||||
virtual bool at_start (
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- returns true if *this represents one position before the first element
|
||||
in the container (this would also make the current element invalid)
|
||||
else returns false
|
||||
!*/
|
||||
|
||||
virtual void reset (
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- #current_element_valid() == false
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
virtual bool current_element_valid (
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- returns true if we are currently at a valid element else
|
||||
returns false
|
||||
!*/
|
||||
|
||||
virtual const T& element (
|
||||
) const = 0;
|
||||
/*!
|
||||
requires
|
||||
- current_element_valid() == true
|
||||
ensures
|
||||
- returns a const reference to the current element
|
||||
!*/
|
||||
|
||||
virtual T& element (
|
||||
) = 0;
|
||||
/*!
|
||||
requires
|
||||
- current_element_valid() == true
|
||||
ensures
|
||||
- returns a non-const reference to the current element
|
||||
!*/
|
||||
|
||||
virtual bool move_next (
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- moves to the next element. i.e. #element() will now
|
||||
return the next element in the container
|
||||
- the return value will be equal to #current_element_valid()
|
||||
- #at_start() == false
|
||||
|
||||
- returns true if there is another element
|
||||
- returns false if there are no more elements in the container
|
||||
!*/
|
||||
|
||||
virtual size_t size (
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of elements in *this
|
||||
!*/
|
||||
|
||||
protected:
|
||||
|
||||
// restricted functions
|
||||
enumerable& operator=(const enumerable&) {return *this;} // no assignment operator
|
||||
|
||||
};
|
||||
|
||||
// destructor does nothing
|
||||
template <typename T>
|
||||
enumerable<T>::~enumerable() {}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_ENUMERABLe_INTERFACE_
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MAP_PAIr_INTERFACE_
|
||||
#define DLIB_MAP_PAIr_INTERFACE_
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T1,
|
||||
typename T2
|
||||
>
|
||||
class map_pair
|
||||
{
|
||||
/*!
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
None of the functions in map_pair will invalidate
|
||||
pointers or references to internal data when called.
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
this object is used to return the key/value pair used in the
|
||||
map and hash_map containers when using the enumerable interface.
|
||||
|
||||
note that the enumerable interface is defined in
|
||||
interfaces/enumerable.h
|
||||
!*/
|
||||
|
||||
public:
|
||||
typedef T1 key_type;
|
||||
typedef T2 value_type;
|
||||
|
||||
virtual ~map_pair(
|
||||
)=0;
|
||||
|
||||
virtual const T1& key(
|
||||
) const =0;
|
||||
/*!
|
||||
ensures
|
||||
- returns a const reference to the key
|
||||
!*/
|
||||
|
||||
virtual const T2& value(
|
||||
) const =0;
|
||||
/*!
|
||||
ensures
|
||||
- returns a const reference to the value associated with key
|
||||
!*/
|
||||
|
||||
virtual T2& value(
|
||||
)=0;
|
||||
/*!
|
||||
ensures
|
||||
- returns a non-const reference to the value associated with key
|
||||
!*/
|
||||
|
||||
protected:
|
||||
|
||||
// restricted functions
|
||||
map_pair<T1,T2>& operator=(const map_pair<T1,T2>&) {return *this;} // no assignment operator
|
||||
|
||||
};
|
||||
|
||||
// destructor does nothing
|
||||
template <typename T1,typename T2>
|
||||
map_pair<T1,T2>::~map_pair () {}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MAP_PAIr_INTERFACE_
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
// Copyright (C) 2005 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_REMOVER_KERNEl_INTERFACE_
|
||||
#define DLIB_REMOVER_KERNEl_INTERFACE_
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class remover
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T is swappable by a global swap() and
|
||||
T must have a default constructor
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
The size() function does not invalidate pointers or
|
||||
references to internal data. All other functions have no such
|
||||
guarantee.
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents some generalized interface for removing
|
||||
single items from container classes.
|
||||
!*/
|
||||
|
||||
|
||||
public:
|
||||
typedef T type;
|
||||
|
||||
virtual ~remover(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- all resources associated with *this have been released.
|
||||
!*/
|
||||
|
||||
virtual void remove_any (
|
||||
T& item
|
||||
) = 0;
|
||||
/*!
|
||||
requires
|
||||
- size() != 0
|
||||
ensures
|
||||
- #size() == size() - 1
|
||||
- removes an element from *this and swaps it into item.
|
||||
- if (*this implements the enumerable interface) then
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
virtual size_t size (
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of elements in *this
|
||||
!*/
|
||||
|
||||
protected:
|
||||
|
||||
// restricted functions
|
||||
remover& operator=(const remover&) {return *this;} // assignment operator
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename compare
|
||||
>
|
||||
class asc_remover : public remover<T>
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T is swappable by a global swap() and
|
||||
T must have a default constructor and
|
||||
T must be comparable by compare where compare is a functor compatible with std::less
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents the same thing as remover except
|
||||
that remove_any() will remove elements in ascending order
|
||||
according to the compare functor.
|
||||
!*/
|
||||
public:
|
||||
typedef compare compare_type;
|
||||
|
||||
protected:
|
||||
// restricted functions
|
||||
asc_remover& operator=(const asc_remover&) {return *this;} // assignment operator
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range
|
||||
>
|
||||
class pair_remover
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON domain
|
||||
domain is swappable by a global swap() and
|
||||
domain must have a default constructor
|
||||
|
||||
REQUIREMENTS ON range
|
||||
range is swappable by a global swap() and
|
||||
range must have a default constructor
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
The size() function does not invalidate pointers or
|
||||
references to internal data. All other functions have no such
|
||||
guarantee.
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents some generalized interface for removing
|
||||
pairs from container classes which enforce some kind of pairing on
|
||||
the elements that they contain.
|
||||
!*/
|
||||
|
||||
public:
|
||||
typedef domain domain_type;
|
||||
typedef range range_type;
|
||||
|
||||
virtual ~pair_remover(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- all resources associated with *this have been released.
|
||||
!*/
|
||||
|
||||
virtual void remove_any (
|
||||
domain& d,
|
||||
range& r
|
||||
) = 0;
|
||||
/*!
|
||||
requires
|
||||
- &d != &r (i.e. d and r cannot be the same variable)
|
||||
- size() != 0
|
||||
ensures
|
||||
- #size() == size() - 1
|
||||
- removes an element from the domain of *this and swaps it
|
||||
into d.
|
||||
- removes the element in *this's range that is associated
|
||||
with #d and swaps it into r.
|
||||
- if (*this implements the enumerable interface) then
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
virtual size_t size (
|
||||
) const = 0;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of elements in *this
|
||||
!*/
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// restricted functions
|
||||
pair_remover& operator=(const pair_remover&) {return *this;} // assignment operator
|
||||
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename compare
|
||||
>
|
||||
class asc_pair_remover : public pair_remover<domain,range>
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON domain
|
||||
domain is swappable by a global swap() and
|
||||
domain must have a default constructor and
|
||||
domain must be comparable by compare where compare is a functor compatible with std::less
|
||||
|
||||
REQUIREMENTS ON range
|
||||
range is swappable by a global swap() and
|
||||
range must have a default constructor
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents the same thing as pair_remover except
|
||||
that remove_any() will remove domain elements in ascending
|
||||
order according to the compare functor.
|
||||
!*/
|
||||
public:
|
||||
typedef compare compare_type;
|
||||
|
||||
protected:
|
||||
// restricted functions
|
||||
asc_pair_remover& operator=(const asc_pair_remover&) {return *this;} // assignment operator
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
// destructor does nothing
|
||||
template <typename T>
|
||||
remover<T>::~remover() {}
|
||||
|
||||
// destructor does nothing
|
||||
template <typename domain, typename range>
|
||||
pair_remover<domain,range>::~pair_remover() {}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_REMOVER_KERNEl_INTERFACE_
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlib_include_path_tutorial.txt"
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlib_include_path_tutorial.txt"
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlib_include_path_tutorial.txt"
|
||||
162
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/is_kind.h
vendored
Normal file
162
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/is_kind.h
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_IS_KINd_H_
|
||||
#define DLIB_IS_KINd_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
/*!
|
||||
This file contains a set of templates that enable you to determine if
|
||||
a given type implements an abstract interface defined in one of the
|
||||
dlib *_abstract.h files.
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
struct default_is_kind_value { static const bool value = false; };
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct is_graph : public default_is_kind_value
|
||||
{
|
||||
/*!
|
||||
- if (T is an implementation of graph/graph_kernel_abstract.h) then
|
||||
- is_graph<T>::value == true
|
||||
- else
|
||||
- is_graph<T>::value == false
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct is_directed_graph : public default_is_kind_value
|
||||
{
|
||||
/*!
|
||||
- if (T is an implementation of directed_graph/directed_graph_kernel_abstract.h) then
|
||||
- is_directed_graph<T>::value == true
|
||||
- else
|
||||
- is_directed_graph<T>::value == false
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T, typename helper = void>
|
||||
struct is_matrix : public default_is_kind_value
|
||||
{
|
||||
/*!
|
||||
- if (T is some kind of matrix expression from the matrix/matrix_exp_abstract.h component) then
|
||||
- is_matrix<T>::value == true
|
||||
- else
|
||||
- is_matrix<T>::value == false
|
||||
!*/
|
||||
|
||||
// Don't set the helper to anything. Just let it be void.
|
||||
ASSERT_ARE_SAME_TYPE(helper,void);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct is_array2d : public default_is_kind_value
|
||||
{
|
||||
/*!
|
||||
- if (T is an implementation of array2d/array2d_kernel_abstract.h) then
|
||||
- is_array2d<T>::value == true
|
||||
- else
|
||||
- is_array2d<T>::value == false
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct is_array : public default_is_kind_value
|
||||
{
|
||||
/*!
|
||||
- if (T is an implementation of array/array_kernel_abstract.h) then
|
||||
- is_array<T>::value == true
|
||||
- else
|
||||
- is_array<T>::value == false
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct is_std_vector : public default_is_kind_value
|
||||
{
|
||||
/*!
|
||||
- if (T is an implementation of the standard C++ std::vector object) then
|
||||
- is_std_vector<T>::value == true
|
||||
- else
|
||||
- is_std_vector<T>::value == false
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct is_pair : public default_is_kind_value
|
||||
{
|
||||
/*!
|
||||
- if (T is a std::pair object) then
|
||||
- is_std_vector<T>::value == true
|
||||
- else
|
||||
- is_std_vector<T>::value == false
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct is_rand : public default_is_kind_value
|
||||
{
|
||||
/*!
|
||||
- if (T is an implementation of rand/rand_kernel_abstract.h) then
|
||||
- is_rand<T>::value == true
|
||||
- else
|
||||
- is_rand<T>::value == false
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
struct is_config_reader : public default_is_kind_value
|
||||
{
|
||||
/*!
|
||||
- if (T is an implementation of config_reader/config_reader_kernel_abstract.h) then
|
||||
- is_config_reader<T>::value == true
|
||||
- else
|
||||
- is_config_reader<T>::value == false
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Implementation details
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T, typename alloc>
|
||||
struct is_std_vector<std::vector<T,alloc> > { const static bool value = true; };
|
||||
template <typename T> struct is_std_vector<T&> { const static bool value = is_std_vector<T>::value; };
|
||||
template <typename T> struct is_std_vector<const T&>{ const static bool value = is_std_vector<T>::value; };
|
||||
template <typename T> struct is_std_vector<const T> { const static bool value = is_std_vector<T>::value; };
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T, typename U>
|
||||
struct is_pair<std::pair<T,U> > { const static bool value = true; };
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_IS_KINd_H_
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlib_include_path_tutorial.txt"
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlib_include_path_tutorial.txt"
|
||||
11
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/logger.h
vendored
Normal file
11
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/logger.h
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_LOGGEr_
|
||||
#define DLIB_LOGGEr_
|
||||
|
||||
#include "logger/logger_kernel_1.h"
|
||||
#include "logger/extra_logger_headers.h"
|
||||
#include "logger/logger_config_file.h"
|
||||
|
||||
#endif // DLIB_LOGGEr_
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_EXTRA_LOGGER_HEADERs_
|
||||
#define DLIB_EXTRA_LOGGER_HEADERs_
|
||||
|
||||
#include "logger_kernel_abstract.h"
|
||||
#include "logger_kernel_1.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "../uintn.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
void print_datetime_logger_header (
|
||||
std::ostream& out,
|
||||
const std::string& logger_name,
|
||||
const log_level& l,
|
||||
const uint64 thread_id
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- is not called more than once at a time (i.e. is not called from multiple
|
||||
threads at the same time).
|
||||
ensures
|
||||
- let DATE be the current date and time (e.g. Thu Aug 31 16:41:52 2006).
|
||||
- prints a string to out in the form: "l.name (DATE) [thread_id] logger_name:"
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef NO_MAKEFILE
|
||||
#include "extra_logger_headers.cpp"
|
||||
#endif
|
||||
|
||||
#endif // DLIB_EXTRA_LOGGER_HEADERs_
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_LOGGER_CONFIg_FILE_
|
||||
#define DLIB_LOGGER_CONFIg_FILE_
|
||||
|
||||
#include "logger_kernel_abstract.h"
|
||||
#include "logger_kernel_1.h"
|
||||
#include <string>
|
||||
#include "../config_reader.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
class logger_config_file_error : public error
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This is the exception class used by the configure_loggers_from_file()
|
||||
function defined below.
|
||||
!*/
|
||||
public:
|
||||
logger_config_file_error(const std::string& s):error(s){}
|
||||
};
|
||||
|
||||
void configure_loggers_from_file (
|
||||
const std::string& file_name
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- configures the loggers with the contents of the file_name file
|
||||
throws
|
||||
- dlib::logger_config_file_error
|
||||
this exception is thrown if there is a problem reading the config file
|
||||
!*/
|
||||
|
||||
void configure_loggers_from_file (
|
||||
const config_reader& cr
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- configures the loggers with the contents of cr. This function is just like
|
||||
the above version that reads from a file except that it reads from an in-memory
|
||||
config_reader instead.
|
||||
throws
|
||||
- dlib::logger_config_file_error
|
||||
this exception is thrown if there is a problem reading the config file
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
# -----------------------------------------------
|
||||
# ------------- EXAMPLE CONFIG FILE -------------
|
||||
# -----------------------------------------------
|
||||
|
||||
# The overall format of the config file is the same as the one defined by
|
||||
# the config_reader component of this library.
|
||||
|
||||
# This line is a comment line
|
||||
|
||||
# The config file always has a block named logger_config. This is where all the
|
||||
# config data for the loggers reside.
|
||||
logger_config
|
||||
{
|
||||
# This sets all loggers to the level LINFO since it is just inside the
|
||||
# logger_config block
|
||||
logging_level = info
|
||||
|
||||
# Alternatively we could specify a user defined logging level by
|
||||
# supplying a priority number. The following line would specify
|
||||
# that only logging levels at or above 100 are printed. (note that
|
||||
# you would have to comment out the logging_level statement above
|
||||
# to avoid a conflict).
|
||||
# logging_level = 100
|
||||
|
||||
parent_logger
|
||||
{
|
||||
# This sets all loggers named "parent_logger" or children of
|
||||
# loggers with that name to not log at all (i.e. to logging level
|
||||
# LNONE).
|
||||
logging_level = none
|
||||
}
|
||||
|
||||
|
||||
parent_logger2
|
||||
{
|
||||
# set loggers named "parent_logger2" and its children loggers
|
||||
# to write their output to a file named out.txt
|
||||
output = file out.txt
|
||||
|
||||
child_logger
|
||||
{
|
||||
# Set loggers named "parent_logger2.child_logger" and children of loggers
|
||||
# with this name to logging level LALL
|
||||
logging_level = all
|
||||
|
||||
# Note that this logger will also log to out.txt because that is what
|
||||
# its parent does and we haven't overridden it here with something else.
|
||||
# if we wanted this logger to write to cout instead we could uncomment
|
||||
# the following line:
|
||||
# output = cout
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# So in summary, all logger config stuff goes inside a block named logger_config. Then
|
||||
# inside that block all blocks must be the names of loggers. There are only two keys,
|
||||
# logging_level and output.
|
||||
#
|
||||
# The valid values of logging_level are:
|
||||
# "LALL", "LNONE", "LTRACE", "LDEBUG", "LINFO", "LWARN", "LERROR", "LFATAL",
|
||||
# "ALL", "NONE", "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL",
|
||||
# "all", "none", "trace", "debug", "info", "warn", "error", "fatal", or
|
||||
# any integral value
|
||||
#
|
||||
# The valid values of output are:
|
||||
# "cout", "cerr", "clog", or a string of the form "file some_file_name"
|
||||
# which causes the output to be logged to the specified file.
|
||||
#
|
||||
!*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef NO_MAKEFILE
|
||||
#include "logger_config_file.cpp"
|
||||
#endif
|
||||
|
||||
#endif // DLIB_LOGGER_CONFIg_FILE_
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,687 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_LOGGER_KERNEl_1_
|
||||
#define DLIB_LOGGER_KERNEl_1_
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
#include <streambuf>
|
||||
#include <vector>
|
||||
|
||||
#include "../threads.h"
|
||||
#include "../misc_api.h"
|
||||
#include "../set.h"
|
||||
#include "logger_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../assert.h"
|
||||
#include "../uintn.h"
|
||||
#include "../map.h"
|
||||
#include "../member_function_pointer.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class log_level
|
||||
{
|
||||
public:
|
||||
log_level(
|
||||
int priority_,
|
||||
const char* name_
|
||||
) :
|
||||
priority(priority_)
|
||||
{
|
||||
strncpy(name,name_,19);
|
||||
name[19] = '\0';
|
||||
}
|
||||
|
||||
bool operator< (const log_level& rhs) const { return priority < rhs.priority; }
|
||||
bool operator<=(const log_level& rhs) const { return priority <= rhs.priority; }
|
||||
bool operator> (const log_level& rhs) const { return priority > rhs.priority; }
|
||||
bool operator>=(const log_level& rhs) const { return priority >= rhs.priority; }
|
||||
|
||||
int priority;
|
||||
char name[20];
|
||||
};
|
||||
|
||||
inline std::ostream& operator<< (std::ostream& out, const log_level& item)
|
||||
{
|
||||
out << item.name;
|
||||
return out;
|
||||
}
|
||||
|
||||
const log_level LALL (std::numeric_limits<int>::min(),"ALL");
|
||||
const log_level LNONE (std::numeric_limits<int>::max(),"NONE");
|
||||
const log_level LTRACE(-100,"TRACE");
|
||||
const log_level LDEBUG(0 ,"DEBUG");
|
||||
const log_level LINFO (100,"INFO ");
|
||||
const log_level LWARN (200,"WARN ");
|
||||
const log_level LERROR(300,"ERROR");
|
||||
const log_level LFATAL(400,"FATAL");
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void set_all_logging_output_streams (
|
||||
std::ostream& out
|
||||
);
|
||||
|
||||
void set_all_logging_levels (
|
||||
const log_level& new_level
|
||||
);
|
||||
|
||||
typedef void (*print_header_type)(
|
||||
std::ostream& out,
|
||||
const std::string& logger_name,
|
||||
const log_level& l,
|
||||
const uint64 thread_id
|
||||
);
|
||||
|
||||
void set_all_logging_headers (
|
||||
const print_header_type& new_header
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void print_default_logger_header (
|
||||
std::ostream& out,
|
||||
const std::string& logger_name,
|
||||
const log_level& l,
|
||||
const uint64 thread_id
|
||||
);
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void set_all_logging_output_hooks (
|
||||
T& object,
|
||||
void (T::*hook_)(const std::string& logger_name,
|
||||
const log_level& l,
|
||||
const uint64 thread_id,
|
||||
const char* message_to_log)
|
||||
);
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void set_all_logging_output_hooks (
|
||||
T& object
|
||||
)
|
||||
{
|
||||
set_all_logging_output_hooks(object, &T::log);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class logger
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
- print_header == print_default_logger_header
|
||||
- out.rdbuf() == std::cout.rdbuf()
|
||||
- cur_level == LERROR
|
||||
- auto_flush_enabled == true
|
||||
- hook.is_set() == false
|
||||
|
||||
CONVENTION
|
||||
- print_header == logger_header()
|
||||
- if (hook.is_set() == false) then
|
||||
- out.rdbuf() == output_streambuf()
|
||||
- else
|
||||
- out.rdbuf() == &gd.hookbuf
|
||||
- output_streambuf() == 0
|
||||
|
||||
- cur_level == level()
|
||||
- logger_name == name()
|
||||
- auto_flush_enabled == auto_flush()
|
||||
|
||||
- logger::gd::loggers == a set containing all currently existing loggers.
|
||||
- logger::gd::m == the mutex used to lock everything in the logger
|
||||
- logger::gd::thread_names == a map of thread ids to thread names.
|
||||
- logger::gd::next_thread_name == the next thread name that will be given out
|
||||
to a thread when we find that it isn't already in thread_names.
|
||||
!*/
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
class logger_stream
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
- been_used == false
|
||||
|
||||
CONVENTION
|
||||
- enabled == is_enabled()
|
||||
- if (been_used) then
|
||||
- logger::gd::m is locked
|
||||
- someone has used the << operator to write something to the
|
||||
output stream.
|
||||
!*/
|
||||
public:
|
||||
logger_stream (
|
||||
const log_level& l_,
|
||||
logger& log_
|
||||
) :
|
||||
l(l_),
|
||||
log(log_),
|
||||
been_used(false),
|
||||
enabled (l.priority >= log.cur_level.priority)
|
||||
{}
|
||||
|
||||
inline ~logger_stream(
|
||||
)
|
||||
{
|
||||
if (!been_used)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
print_end_of_line();
|
||||
}
|
||||
}
|
||||
|
||||
bool is_enabled (
|
||||
) const { return enabled; }
|
||||
|
||||
template <typename T>
|
||||
inline logger_stream& operator << (
|
||||
const T& item
|
||||
)
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
else
|
||||
{
|
||||
print_header_and_stuff();
|
||||
log.out << item;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void print_header_and_stuff (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (!been_used) then
|
||||
- prints the logger header
|
||||
- locks log.gd.m
|
||||
- #been_used == true
|
||||
!*/
|
||||
|
||||
void print_end_of_line (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- prints a newline to log.out
|
||||
- unlocks log.gd.m
|
||||
!*/
|
||||
|
||||
const log_level& l;
|
||||
logger& log;
|
||||
bool been_used;
|
||||
const bool enabled;
|
||||
}; // end of class logger_stream
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
friend class logger_stream;
|
||||
public:
|
||||
|
||||
typedef member_function_pointer<const std::string&, const log_level&,
|
||||
const uint64, const char*> hook_mfp;
|
||||
|
||||
logger (
|
||||
const std::string& name_
|
||||
);
|
||||
|
||||
virtual ~logger (
|
||||
);
|
||||
|
||||
const std::string& name (
|
||||
) const { return logger_name; }
|
||||
|
||||
logger_stream operator << (
|
||||
const log_level& l
|
||||
) const { return logger_stream(l,const_cast<logger&>(*this)); }
|
||||
|
||||
bool is_child_of (
|
||||
const logger& log
|
||||
) const
|
||||
{
|
||||
return (name().find(log.name() + ".") == 0) || (log.name() == name());
|
||||
}
|
||||
|
||||
const log_level level (
|
||||
) const
|
||||
{
|
||||
auto_mutex M(gd.m);
|
||||
return log_level(cur_level);
|
||||
};
|
||||
|
||||
void set_level (
|
||||
const log_level& new_level
|
||||
)
|
||||
{
|
||||
auto_mutex M(gd.m);
|
||||
gd.loggers.reset();
|
||||
while (gd.loggers.move_next())
|
||||
{
|
||||
if (gd.loggers.element()->is_child_of(*this))
|
||||
gd.loggers.element()->cur_level = new_level;
|
||||
}
|
||||
|
||||
gd.set_level(logger_name, new_level);
|
||||
}
|
||||
|
||||
bool auto_flush (
|
||||
) const
|
||||
{
|
||||
auto_mutex M(gd.m);
|
||||
return auto_flush_enabled;
|
||||
};
|
||||
|
||||
void set_auto_flush (
|
||||
bool enabled
|
||||
)
|
||||
{
|
||||
auto_mutex M(gd.m);
|
||||
gd.loggers.reset();
|
||||
while (gd.loggers.move_next())
|
||||
{
|
||||
if (gd.loggers.element()->is_child_of(*this))
|
||||
gd.loggers.element()->auto_flush_enabled = enabled;
|
||||
}
|
||||
|
||||
gd.set_auto_flush(logger_name, enabled);
|
||||
}
|
||||
|
||||
std::streambuf* output_streambuf (
|
||||
)
|
||||
{
|
||||
auto_mutex M(gd.m);
|
||||
|
||||
// if there is an output hook set then we are supposed to return 0.
|
||||
if (hook)
|
||||
return 0;
|
||||
else
|
||||
return out.rdbuf();
|
||||
}
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void set_output_hook (
|
||||
T& object,
|
||||
void (T::*hook_)(const std::string& logger_name,
|
||||
const log_level& l,
|
||||
const uint64 thread_id,
|
||||
const char* message_to_log)
|
||||
)
|
||||
{
|
||||
auto_mutex M(gd.m);
|
||||
hook.set(object, hook_);
|
||||
|
||||
gd.loggers.reset();
|
||||
while (gd.loggers.move_next())
|
||||
{
|
||||
if (gd.loggers.element()->is_child_of(*this))
|
||||
{
|
||||
gd.loggers.element()->out.rdbuf(&gd.hookbuf);
|
||||
gd.loggers.element()->hook = hook;
|
||||
}
|
||||
}
|
||||
|
||||
gd.set_output_hook(logger_name, hook);
|
||||
gd.set_output_stream(logger_name, gd.hookbuf);
|
||||
}
|
||||
|
||||
void set_output_stream (
|
||||
std::ostream& out_
|
||||
)
|
||||
{
|
||||
auto_mutex M(gd.m);
|
||||
gd.loggers.reset();
|
||||
while (gd.loggers.move_next())
|
||||
{
|
||||
if (gd.loggers.element()->is_child_of(*this))
|
||||
{
|
||||
gd.loggers.element()->out.rdbuf(out_.rdbuf());
|
||||
gd.loggers.element()->hook.clear();
|
||||
}
|
||||
}
|
||||
|
||||
gd.set_output_stream(logger_name, out_);
|
||||
|
||||
hook.clear();
|
||||
gd.set_output_hook(logger_name, hook);
|
||||
}
|
||||
|
||||
print_header_type logger_header (
|
||||
) const { return print_header; }
|
||||
|
||||
void set_logger_header (
|
||||
print_header_type ph
|
||||
)
|
||||
{
|
||||
auto_mutex M(gd.m);
|
||||
gd.loggers.reset();
|
||||
while (gd.loggers.move_next())
|
||||
{
|
||||
if (gd.loggers.element()->is_child_of(*this))
|
||||
gd.loggers.element()->print_header = ph;
|
||||
}
|
||||
|
||||
gd.set_logger_header(logger_name, ph);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
struct global_data
|
||||
{
|
||||
rmutex m;
|
||||
set<logger*>::kernel_1b loggers;
|
||||
map<thread_id_type,uint64>::kernel_1b thread_names;
|
||||
uint64 next_thread_name;
|
||||
|
||||
// Make a very simple streambuf that writes characters into a std::vector<char>. We can
|
||||
// use this as the output target for hooks. The reason we don't just use a std::ostringstream
|
||||
// instead is that this way we can be guaranteed that logging doesn't perform memory allocations.
|
||||
// This is because a std::vector never frees memory. I.e. its capacity() doesn't go down when
|
||||
// you resize it back to 0. It just stays the same.
|
||||
class hook_streambuf : public std::streambuf
|
||||
{
|
||||
public:
|
||||
std::vector<char> buffer;
|
||||
int_type overflow ( int_type c)
|
||||
{
|
||||
if (c != EOF) buffer.push_back(static_cast<char>(c));
|
||||
return c;
|
||||
}
|
||||
|
||||
std::streamsize xsputn ( const char* s, std::streamsize num)
|
||||
{
|
||||
buffer.insert(buffer.end(), s, s+num);
|
||||
return num;
|
||||
}
|
||||
};
|
||||
|
||||
hook_streambuf hookbuf;
|
||||
|
||||
global_data (
|
||||
);
|
||||
|
||||
~global_data(
|
||||
);
|
||||
|
||||
uint64 get_thread_name (
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- m is locked
|
||||
ensures
|
||||
- returns a unique id for the calling thread. also makes the number
|
||||
small and nice unlike what you get from get_thread_id()
|
||||
!*/
|
||||
|
||||
void thread_end_handler (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- removes the terminated thread from thread_names
|
||||
!*/
|
||||
|
||||
struct level_container
|
||||
{
|
||||
level_container ();
|
||||
|
||||
log_level val;
|
||||
map<std::string,std::unique_ptr<level_container> >::kernel_1b_c table;
|
||||
} level_table;
|
||||
|
||||
const log_level level (
|
||||
const std::string& name
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the level loggers with the given name are supposed
|
||||
to have
|
||||
!*/
|
||||
|
||||
void set_level (
|
||||
const std::string& name,
|
||||
const log_level& new_level
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all children C of name:
|
||||
- #level(C) == new_level
|
||||
- if name == "" then
|
||||
- for all loggers L:
|
||||
- #level(L) == new_level
|
||||
!*/
|
||||
|
||||
struct auto_flush_container
|
||||
{
|
||||
bool val;
|
||||
map<std::string,std::unique_ptr<auto_flush_container> >::kernel_1b_c table;
|
||||
} auto_flush_table;
|
||||
|
||||
bool auto_flush (
|
||||
const std::string& name
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the auto_flush value loggers with the given name are supposed
|
||||
to have
|
||||
!*/
|
||||
|
||||
void set_auto_flush (
|
||||
const std::string& name,
|
||||
bool enabled
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all children C of name:
|
||||
- #auto_flush_enabled(C) == enabled
|
||||
- if name == "" then
|
||||
- for all loggers L:
|
||||
- #auto_flush_enabled(L) == enabled
|
||||
!*/
|
||||
|
||||
struct output_streambuf_container
|
||||
{
|
||||
std::streambuf* val;
|
||||
map<std::string,std::unique_ptr<output_streambuf_container> >::kernel_1b_c table;
|
||||
} streambuf_table;
|
||||
|
||||
std::streambuf* output_streambuf (
|
||||
const std::string& name
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns the streambuf loggers with the given name are supposed
|
||||
to have
|
||||
!*/
|
||||
|
||||
void set_output_stream (
|
||||
const std::string& name,
|
||||
std::ostream& out_
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all children C of name:
|
||||
- #output_streambuf(C) == out_.rdbuf()
|
||||
- if name == "" then
|
||||
- for all loggers L:
|
||||
- #output_streambuf(L) == out_.rdbuf()
|
||||
!*/
|
||||
|
||||
void set_output_stream (
|
||||
const std::string& name,
|
||||
std::streambuf& buf
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all children C of name:
|
||||
- #output_streambuf(C) == &buf
|
||||
- if name == "" then
|
||||
- for all loggers L:
|
||||
- #output_streambuf(L) == &buf
|
||||
!*/
|
||||
|
||||
struct output_hook_container
|
||||
{
|
||||
hook_mfp val;
|
||||
map<std::string,std::unique_ptr<output_hook_container> >::kernel_1b_c table;
|
||||
} hook_table;
|
||||
|
||||
hook_mfp output_hook (
|
||||
const std::string& name
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns the hook loggers with the given name are supposed
|
||||
to have
|
||||
!*/
|
||||
|
||||
void set_output_hook (
|
||||
const std::string& name,
|
||||
const hook_mfp& hook
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all children C of name:
|
||||
- #output_hook(C) == hook
|
||||
- if name == "" then
|
||||
- for all loggers L:
|
||||
- #output_hook(L) == hook
|
||||
!*/
|
||||
|
||||
struct logger_header_container
|
||||
{
|
||||
print_header_type val;
|
||||
map<std::string,std::unique_ptr<logger_header_container> >::kernel_1b_c table;
|
||||
} header_table;
|
||||
|
||||
print_header_type logger_header (
|
||||
const std::string& name
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns the header function loggers with the given name are supposed
|
||||
to have
|
||||
!*/
|
||||
|
||||
void set_logger_header (
|
||||
const std::string& name,
|
||||
print_header_type ph
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all children C of name:
|
||||
- #logger_header(C) == ph
|
||||
- if name == "" then
|
||||
- for all loggers L:
|
||||
- #logger_header(L) == ph
|
||||
!*/
|
||||
|
||||
}; // end of struct global_data
|
||||
|
||||
static global_data& get_global_data();
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
friend void set_all_logging_levels (
|
||||
const log_level& new_level
|
||||
);
|
||||
|
||||
friend void set_all_logging_headers (
|
||||
const print_header_type& new_header
|
||||
);
|
||||
|
||||
friend void set_all_logging_output_streams (
|
||||
std::ostream& out
|
||||
);
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
friend void set_all_logging_output_hooks (
|
||||
T& object,
|
||||
void (T::*hook_)(const std::string& logger_name,
|
||||
const log_level& l,
|
||||
const uint64 thread_id,
|
||||
const char* message_to_log)
|
||||
)
|
||||
{
|
||||
logger::hook_mfp hook;
|
||||
|
||||
// There is a bug in one of the versions (but not all apparently) of
|
||||
// Visual studio 2005 that causes it to error out if <T> isn't in the
|
||||
// following line of code. However, there is also a bug in gcc-3.3
|
||||
// that causes it to error out if <T> is present. So this works around
|
||||
// this problem.
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1400
|
||||
hook.set<T>(object, hook_);
|
||||
#else
|
||||
hook.set(object, hook_);
|
||||
#endif
|
||||
|
||||
logger::global_data& gd = logger::get_global_data();
|
||||
auto_mutex M(gd.m);
|
||||
gd.loggers.reset();
|
||||
while (gd.loggers.move_next())
|
||||
{
|
||||
gd.loggers.element()->out.rdbuf(&gd.hookbuf);
|
||||
gd.loggers.element()->hook = hook;
|
||||
}
|
||||
|
||||
gd.set_output_stream("",gd.hookbuf);
|
||||
gd.set_output_hook("",hook);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
global_data& gd;
|
||||
|
||||
const std::string logger_name;
|
||||
|
||||
print_header_type print_header;
|
||||
bool auto_flush_enabled;
|
||||
std::ostream out;
|
||||
log_level cur_level;
|
||||
|
||||
hook_mfp hook;
|
||||
|
||||
|
||||
// restricted functions
|
||||
logger(const logger&); // copy constructor
|
||||
logger& operator=(const logger&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifdef NO_MAKEFILE
|
||||
#include "logger_kernel_1.cpp"
|
||||
#endif
|
||||
|
||||
#endif // DLIB_LOGGER_KERNEl_1_
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_LOGGER_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_LOGGER_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../threads.h"
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "../uintn.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class log_level
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object is a simple named level to log at. It contains a numeric
|
||||
priority and a name to use in the logging messages.
|
||||
!*/
|
||||
public:
|
||||
log_level(
|
||||
int priority_,
|
||||
const char* name_
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #priority = priority_
|
||||
- the first 19 characters of name_ are copied into name and name
|
||||
is null terminated.
|
||||
!*/
|
||||
|
||||
bool operator< (const log_level& rhs) const { return priority < rhs.priority; }
|
||||
bool operator<=(const log_level& rhs) const { return priority <= rhs.priority; }
|
||||
bool operator> (const log_level& rhs) const { return priority > rhs.priority; }
|
||||
bool operator>=(const log_level& rhs) const { return priority >= rhs.priority; }
|
||||
|
||||
int priority;
|
||||
char name[20];
|
||||
};
|
||||
|
||||
inline std::ostream& operator<< (std::ostream& out, const log_level& item);
|
||||
/*!
|
||||
ensures
|
||||
- performs out << item.name
|
||||
- returns out
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
const log_level LALL (std::numeric_limits<int>::min(),"ALL");
|
||||
const log_level LNONE (std::numeric_limits<int>::max(),"NONE");
|
||||
const log_level LTRACE(-100,"TRACE");
|
||||
const log_level LDEBUG(0 ,"DEBUG");
|
||||
const log_level LINFO (100 ,"INFO ");
|
||||
const log_level LWARN (200 ,"WARN ");
|
||||
const log_level LERROR(300 ,"ERROR");
|
||||
const log_level LFATAL(400 ,"FATAL");
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void set_all_logging_output_streams (
|
||||
std::ostream& out
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all loggers L (even loggers not yet constructed):
|
||||
- #L.output_streambuf() == out.rdbuf()
|
||||
- Removes any previous output hook from L. So now the logger
|
||||
L will write all its messages to the given output stream.
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
typedef void (*print_header_type)(
|
||||
std::ostream& out,
|
||||
const std::string& logger_name,
|
||||
const log_level& l,
|
||||
const uint64 thread_id
|
||||
);
|
||||
|
||||
void set_all_logging_headers (
|
||||
const print_header_type& new_header
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all loggers L (even loggers not yet constructed):
|
||||
- #L.logger_header() == new_header
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void set_all_logging_output_hooks (
|
||||
T& object,
|
||||
void (T::*hook)(const std::string& logger_name,
|
||||
const log_level& l,
|
||||
const uint64 thread_id,
|
||||
const char* message_to_log)
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all loggers L (even loggers not yet constructed):
|
||||
- #L.output_streambuf() == 0
|
||||
- performs the equivalent to calling L.set_output_hook(object, hook);
|
||||
(i.e. sets all loggers so that they will use the given hook function)
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void set_all_logging_output_hooks (
|
||||
T& object
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- calls set_all_logging_output_hooks(object, &T::log);
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void set_all_logging_levels (
|
||||
const log_level& new_level
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all loggers L (even loggers not yet constructed):
|
||||
- #L.level() == new_level
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void print_default_logger_header (
|
||||
std::ostream& out,
|
||||
const std::string& logger_name,
|
||||
const log_level& l,
|
||||
const uint64 thread_id
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- is not called more than once at a time (i.e. is not called from multiple
|
||||
threads at the same time).
|
||||
ensures
|
||||
- let MS be the number of milliseconds since program start.
|
||||
- prints a string to out in the form: "MS l.name [thread_id] logger_name:"
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class logger
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
- name() == a user supplied value given to the constructor
|
||||
- The values of level(), output_streambuf(), logger_header(), and
|
||||
auto_flush() are inherited from the parent of this logger.
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents a logging output stream in the style of the log4j
|
||||
logger available for Java.
|
||||
|
||||
Additionally, the logger doesn't perform any memory allocations during
|
||||
each logging action. It just writes directly into the user supplied output
|
||||
stream. Alternatively, if you use a logging output hook no memory allocations
|
||||
are performed either. Logging just goes straight into a memory buffer
|
||||
which gets passed to the user supplied logging hook.
|
||||
|
||||
DEFAULTS
|
||||
If the user hasn't specified values for the four inherited values level(),
|
||||
output_streambuf(), logger_header(), or auto_flush() then the default
|
||||
values will be used. The defaults are as follows:
|
||||
- level() == LERROR
|
||||
- output_streambuf() == std::cout.rdbuf() (i.e. the default is to log
|
||||
to standard output).
|
||||
- logger_header() == print_default_logger_header
|
||||
- auto_flush() == true
|
||||
|
||||
THREAD SAFETY
|
||||
All methods of this class are thread safe. Note that it is safe to
|
||||
chain calls to operator << such as:
|
||||
log << LINFO << "message " << variable << " more message";
|
||||
The logger ensures that the entire statement executes atomically so the
|
||||
message won't be broken up by other loggers in other threads.
|
||||
!*/
|
||||
|
||||
class logger_stream
|
||||
{
|
||||
public:
|
||||
|
||||
bool is_enabled (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns true if this logger stream will print out items
|
||||
given to it by the << operator. returns false otherwise.
|
||||
!*/
|
||||
|
||||
template <typename T>
|
||||
logger_stream& operator << (
|
||||
const T& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (is_enabled()) then
|
||||
- writes item to this output stream
|
||||
- returns *this
|
||||
!*/
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
logger (
|
||||
const std::string& name_
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- name_ != ""
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
- #name() == name_
|
||||
throws
|
||||
- std::bad_alloc
|
||||
- dlib::thread_error
|
||||
!*/
|
||||
|
||||
virtual ~logger (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- any resources associated with *this have been released
|
||||
!*/
|
||||
|
||||
const std::string& name (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the name of this logger
|
||||
!*/
|
||||
|
||||
logger_stream operator << (
|
||||
const log_level& l
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (l.priority >= level().priority) then
|
||||
- returns a logger_stream with is_enabled() == true. I.e. this
|
||||
returned stream will write its output to the I/O destination
|
||||
used by this logger object.
|
||||
- else
|
||||
- returns a logger stream with is_enabled() == false
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
bool is_child_of (
|
||||
const logger& log
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if ( (name().find(log.name() + ".") == 0) || (log.name() == name()) ) then
|
||||
- returns true
|
||||
(i.e. if log.name() + "." is a prefix of name() or if both *this and log
|
||||
have the same name then return true)
|
||||
- else
|
||||
- returns false
|
||||
!*/
|
||||
|
||||
const log_level level (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the current log level of this logger.
|
||||
!*/
|
||||
|
||||
void set_level (
|
||||
const log_level& new_level
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all loggers L such that L.is_child_of(*this) == true:
|
||||
- #L.level() == new_level
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
bool auto_flush (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns true if the output stream is flushed after every logged message.
|
||||
returns false otherwise. (Note that flushing only does anything if
|
||||
the logger is set to use an output stream rather than a hook)
|
||||
!*/
|
||||
|
||||
void set_auto_flush (
|
||||
bool enabled
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all loggers L such that L.is_child_of(*this) == true:
|
||||
- #L.auto_flush() == enabled
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void set_output_hook (
|
||||
T& object,
|
||||
void (T::*hook)(const std::string& logger_name,
|
||||
const log_level& l,
|
||||
const uint64 thread_id,
|
||||
const char* message_to_log)
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- hook is a valid pointer to a member function in T
|
||||
ensures
|
||||
- for all loggers L such that L.is_child_of(*this) == true:
|
||||
- #L.output_streambuf() == 0
|
||||
- #L will not send its log messages to an ostream object anymore. Instead
|
||||
it will call the given hook member function (i.e. (object.*hook)(name,l,id,msg) )
|
||||
for each message that needs to be logged.
|
||||
- The arguments to the hook function have the following meanings:
|
||||
- logger_name == The name of the logger that is printing the log message.
|
||||
- l == The level of the logger that is printing the log message.
|
||||
- thread_id == A number that uniquely identifies the thread trying to log
|
||||
the message. Note that this number is unique among all threads, past and
|
||||
present. Also note that this id is not the same one returned by
|
||||
get_thread_id().
|
||||
- message_to_log == the actual text of the message the user is giving to
|
||||
the logger object to log.
|
||||
- All hook functions will also only be called one at a time. This means
|
||||
that hook functions don't need to be thread safe.
|
||||
!*/
|
||||
|
||||
std::streambuf* output_streambuf (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (an output hook isn't set) then
|
||||
- returns the output stream buffer that this logger writes all
|
||||
messages to.
|
||||
- else
|
||||
- returns 0
|
||||
!*/
|
||||
|
||||
void set_output_stream (
|
||||
std::ostream& out
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all loggers L such that L.is_child_of(*this) == true:
|
||||
- #L.output_streambuf() == out.rdbuf()
|
||||
- Removes any previous output hook from L. So now the logger
|
||||
L will write all its messages to the given output stream.
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
print_header_type logger_header (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the function that is called to print the header information
|
||||
onto each logged message. The arguments to the function have the following
|
||||
meanings:
|
||||
- out == The output stream this function writes the header to.
|
||||
- logger_name == The name of the logger that is printing the log message.
|
||||
- l == The level of the logger that is printing the log message.
|
||||
- thread_id == A number that uniquely identifies the thread trying to log
|
||||
the message. Note that this number is unique among all threads, past and
|
||||
present. Also note that this id is not the same one returned by
|
||||
get_thread_id().
|
||||
- This logger_header function will also only be called once at a time. This means
|
||||
the logger_header function doesn't need to be thread safe.
|
||||
- the logger_header function is only used when output_streambuf() != 0
|
||||
!*/
|
||||
|
||||
void set_logger_header (
|
||||
print_header_type print_header
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all loggers L such that L.is_child_of(*this) == true:
|
||||
- #L.logger_header() == print_header
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
logger(const logger&); // copy constructor
|
||||
logger& operator=(const logger&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_LOGGER_KERNEl_ABSTRACT_
|
||||
|
||||
59
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/map.h
vendored
Normal file
59
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/map.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MAp_
|
||||
#define DLIB_MAp_
|
||||
|
||||
#include "map/map_kernel_1.h"
|
||||
#include "map/map_kernel_c.h"
|
||||
|
||||
#include "binary_search_tree.h"
|
||||
|
||||
|
||||
#include "algs.h"
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager = default_memory_manager,
|
||||
typename compare = std::less<domain>
|
||||
>
|
||||
class map
|
||||
{
|
||||
map() {}
|
||||
|
||||
|
||||
// a typedef for the binary search tree used by kernel_2
|
||||
typedef typename binary_search_tree<domain,range,mem_manager,compare>::kernel_1a
|
||||
binary_search_tree_1;
|
||||
|
||||
// a typedef for the binary search tree used by kernel_2
|
||||
typedef typename binary_search_tree<domain,range,mem_manager,compare>::kernel_2a
|
||||
binary_search_tree_2;
|
||||
|
||||
public:
|
||||
|
||||
//----------- kernels ---------------
|
||||
|
||||
// kernel_1a
|
||||
typedef map_kernel_1<domain,range,binary_search_tree_1,mem_manager>
|
||||
kernel_1a;
|
||||
typedef map_kernel_c<kernel_1a >
|
||||
kernel_1a_c;
|
||||
|
||||
// kernel_1b
|
||||
typedef map_kernel_1<domain,range,binary_search_tree_2,mem_manager>
|
||||
kernel_1b;
|
||||
typedef map_kernel_c<kernel_1b >
|
||||
kernel_1b_c;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_MAp_
|
||||
|
||||
@@ -0,0 +1,436 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MAP_KERNEl_1_
|
||||
#define DLIB_MAP_KERNEl_1_
|
||||
|
||||
#include "map_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/map_pair.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../serialize.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager = default_memory_manager
|
||||
>
|
||||
class map_kernel_1 : public enumerable<map_pair<domain,range> >,
|
||||
public asc_pair_remover<domain,range,typename bst_base::compare_type>
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON BST_BASE
|
||||
bst_base is instantiated with domain and range and
|
||||
implements binary_search_tree/binary_search_tree_kernel_abstract.h
|
||||
|
||||
INITIAL VALUE
|
||||
bst has its initial value
|
||||
|
||||
CONVENTION
|
||||
bst.size() == the number of elements in the map and
|
||||
the elements in map are stored in bst_base
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef domain domain_type;
|
||||
typedef range range_type;
|
||||
typedef typename bst_base::compare_type compare_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
map_kernel_1(
|
||||
)
|
||||
{}
|
||||
|
||||
virtual ~map_kernel_1(
|
||||
)
|
||||
{}
|
||||
|
||||
inline void clear(
|
||||
);
|
||||
|
||||
inline void add (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
inline bool is_in_domain (
|
||||
const domain& d
|
||||
) const;
|
||||
|
||||
inline void remove_any (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
inline void remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
);
|
||||
|
||||
inline void destroy (
|
||||
const domain& d
|
||||
);
|
||||
|
||||
inline range& operator[] (
|
||||
const domain& d
|
||||
);
|
||||
|
||||
inline const range& operator[] (
|
||||
const domain& d
|
||||
) const;
|
||||
|
||||
inline void swap (
|
||||
map_kernel_1& item
|
||||
);
|
||||
|
||||
// functions from the enumerable interface
|
||||
inline size_t size (
|
||||
) const;
|
||||
|
||||
inline bool at_start (
|
||||
) const;
|
||||
|
||||
inline void reset (
|
||||
) const;
|
||||
|
||||
inline bool current_element_valid (
|
||||
) const;
|
||||
|
||||
inline const map_pair<domain,range>& element (
|
||||
) const;
|
||||
|
||||
inline map_pair<domain,range>& element (
|
||||
);
|
||||
|
||||
inline bool move_next (
|
||||
) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
bst_base bst;
|
||||
|
||||
// restricted functions
|
||||
map_kernel_1(map_kernel_1&);
|
||||
map_kernel_1& operator= ( map_kernel_1&);
|
||||
};
|
||||
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
inline void swap (
|
||||
map_kernel_1<domain,range,bst_base,mem_manager>& a,
|
||||
map_kernel_1<domain,range,bst_base,mem_manager>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
map_kernel_1<domain,range,bst_base,mem_manager>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.clear();
|
||||
unsigned long size;
|
||||
deserialize(size,in);
|
||||
domain d;
|
||||
range r;
|
||||
for (unsigned long i = 0; i < size; ++i)
|
||||
{
|
||||
deserialize(d,in);
|
||||
deserialize(r,in);
|
||||
item.add(d,r);
|
||||
}
|
||||
}
|
||||
catch (serialization_error& e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type map_kernel_1");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
clear (
|
||||
)
|
||||
{
|
||||
bst.clear();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
add(
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
// try to add pair to bst_base
|
||||
bst.add(d,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
bool map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
is_in_domain(
|
||||
const domain& d
|
||||
) const
|
||||
{
|
||||
return (bst[d] != 0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
remove_any(
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
bst.remove_any(d,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
bst.remove(d,d_copy,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
destroy (
|
||||
const domain& d
|
||||
)
|
||||
{
|
||||
bst.destroy(d);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
range& map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
operator[](
|
||||
const domain& d
|
||||
)
|
||||
{
|
||||
return *bst[d];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
const range& map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
operator[](
|
||||
const domain& d
|
||||
) const
|
||||
{
|
||||
return *bst[d];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
size_t map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
size (
|
||||
) const
|
||||
{
|
||||
return bst.size();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
swap (
|
||||
map_kernel_1<domain,range,bst_base,mem_manager>& item
|
||||
)
|
||||
{
|
||||
bst.swap(item.bst);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// enumerable function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
bool map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
at_start (
|
||||
) const
|
||||
{
|
||||
return bst.at_start();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
reset (
|
||||
) const
|
||||
{
|
||||
bst.reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
bool map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
current_element_valid (
|
||||
) const
|
||||
{
|
||||
return bst.current_element_valid();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
const map_pair<domain,range>& map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
element (
|
||||
) const
|
||||
{
|
||||
return bst.element();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
map_pair<domain,range>& map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
element (
|
||||
)
|
||||
{
|
||||
return bst.element();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
bool map_kernel_1<domain,range,bst_base,mem_manager>::
|
||||
move_next (
|
||||
) const
|
||||
{
|
||||
return bst.move_next();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MAP_KERNEl_1_
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_MAP_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_MAP_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../interfaces/map_pair.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../serialize.h"
|
||||
#include "../algs.h"
|
||||
#include <functional>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager = default_memory_manager,
|
||||
typename compare = std::less<domain>
|
||||
>
|
||||
class map : public enumerable<map_pair<domain,range> >,
|
||||
public asc_pair_remover<domain,range,compare>
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON domain
|
||||
domain must be comparable by compare where compare is a functor compatible with std::less and
|
||||
domain is swappable by a global swap() and
|
||||
domain must have a default constructor
|
||||
|
||||
REQUIREMENTS ON range
|
||||
range is swappable by a global swap() and
|
||||
range must have a default constructor
|
||||
|
||||
REQUIREMENTS ON mem_manager
|
||||
must be an implementation of memory_manager/memory_manager_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_global/memory_manager_global_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
|
||||
mem_manager::type can be set to anything.
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
swap(), is_in_domain(), and operator[] functions do not invalidate
|
||||
pointers or references to internal data.
|
||||
All other functions have no such guarantee.
|
||||
|
||||
INITIAL VALUE
|
||||
size() == 0
|
||||
|
||||
ENUMERATION ORDER
|
||||
The enumerator will iterate over the domain (and each associated
|
||||
range element) elements in ascending order according to the compare functor.
|
||||
(i.e. the elements are enumerated in sorted order)
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
map contains items of type domain and range
|
||||
|
||||
This object is similar an array. It maps items of type domain on to
|
||||
items of type range.
|
||||
|
||||
Also note that unless specified otherwise, no member functions
|
||||
of this object throw exceptions.
|
||||
|
||||
definition of equivalent:
|
||||
a is equivalent to b if
|
||||
a < b == false and
|
||||
b < a == false
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef domain domain_type;
|
||||
typedef range range_type;
|
||||
typedef compare compare_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
map(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by domain's or range's
|
||||
constructor.
|
||||
!*/
|
||||
|
||||
virtual ~map(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- all memory associated with *this has been released
|
||||
!*/
|
||||
|
||||
void clear(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this has its initial value
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by domain's or range's
|
||||
constructor.
|
||||
if this exception is thrown then *this is unusable
|
||||
until clear() is called and succeeds
|
||||
!*/
|
||||
|
||||
void add (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- &d != &r (i.e. d and r cannot be the same variable)
|
||||
- is_in_domain(d) == false
|
||||
ensures
|
||||
- #is_in_domain(d) == true
|
||||
- #operator[](d) == r
|
||||
- #d and #r have initial values for their types
|
||||
- #size() == size() + 1
|
||||
- #at_start() == true
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by domain's or range's
|
||||
constructor.
|
||||
if add() throws then it has no effect
|
||||
!*/
|
||||
|
||||
bool is_in_domain (
|
||||
const domain& d
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns whether or not an element equivalent to d is in the
|
||||
domain of *this
|
||||
!*/
|
||||
|
||||
void remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- &d != &r (i.e. d and r cannot be the same variable)
|
||||
- &d != &d_copy (i.e. d and d_copy cannot be the same variable)
|
||||
- &r != &d_copy (i.e. r and d_copy cannot be the same variable)
|
||||
- is_in_domain(d) == true
|
||||
ensures
|
||||
- #is_in_domain(d) == false
|
||||
- #d_copy is equivalent to d
|
||||
- the element in the range of *this associated with #d_copy has been
|
||||
swapped into #r
|
||||
- #size() == size() - 1
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
void destroy (
|
||||
const domain& d
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- is_in_domain(d) == true
|
||||
ensures
|
||||
- #is_in_domain(d) == false
|
||||
- #size() == size() - 1
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
range& operator[] (
|
||||
const domain& d
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- is_in_domain(d) == true
|
||||
ensures
|
||||
- returns a non-const reference to the element in the range of *this
|
||||
associated with the element equivalent to d
|
||||
!*/
|
||||
|
||||
const range& operator[] (
|
||||
const domain& d
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- is_in_domain(d) == true
|
||||
ensures
|
||||
- returns a const reference to the element in the range of *this
|
||||
associated with the element equivalent to d
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
map& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
map(map&); // copy constructor
|
||||
map& operator=(map&); // assignment operator
|
||||
};
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
inline void swap (
|
||||
map<domain,range,mem_manager,compare>& a,
|
||||
map<domain,range,mem_manager,compare>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename domain,
|
||||
typename range,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void deserialize (
|
||||
map<domain,range,mem_manager,compare>& item,
|
||||
std::istream& in
|
||||
);
|
||||
/*!
|
||||
provides deserialization support
|
||||
!*/
|
||||
}
|
||||
|
||||
#endif // DLIB_MAP_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MAP_KERNEl_C_
|
||||
#define DLIB_MAP_KERNEl_C_
|
||||
|
||||
#include "map_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../assert.h"
|
||||
#include "../interfaces/map_pair.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename map_base
|
||||
>
|
||||
class map_kernel_c : public map_base
|
||||
{
|
||||
|
||||
typedef typename map_base::domain_type domain;
|
||||
typedef typename map_base::range_type range;
|
||||
|
||||
public:
|
||||
void add (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
void remove_any (
|
||||
domain& d,
|
||||
range& r
|
||||
);
|
||||
|
||||
void remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
);
|
||||
|
||||
void destroy (
|
||||
const domain& d
|
||||
);
|
||||
|
||||
range& operator[] (
|
||||
const domain& d
|
||||
);
|
||||
|
||||
const range& operator[] (
|
||||
const domain& d
|
||||
) const;
|
||||
|
||||
const map_pair<domain,range>& element (
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tconst map_pair<domain,range>& map::element"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return map_base::element();
|
||||
}
|
||||
|
||||
map_pair<domain,range>& element (
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tmap_pair<domain,range>& map::element"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return map_base::element();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename map_base
|
||||
>
|
||||
inline void swap (
|
||||
map_kernel_c<map_base>& a,
|
||||
map_kernel_c<map_base>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename map_base
|
||||
>
|
||||
void map_kernel_c<map_base>::
|
||||
add (
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( (!this->is_in_domain(d)) &&
|
||||
(static_cast<void*>(&d) != static_cast<void*>(&r)),
|
||||
"\tvoid map::add"
|
||||
<< "\n\tdomain element being added must not already be in the map"
|
||||
<< "\n\tand d and r must not be the same variable"
|
||||
<< "\n\tis_in_domain(d): " << (this->is_in_domain(d) ? "true" : "false")
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << static_cast<void*>(&d)
|
||||
<< "\n\t&r: " << static_cast<void*>(&r)
|
||||
);
|
||||
|
||||
// call the real function
|
||||
map_base::add(d,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename map_base
|
||||
>
|
||||
void map_kernel_c<map_base>::
|
||||
remove_any (
|
||||
domain& d,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( (this->size() > 0) &&
|
||||
(static_cast<void*>(&d) != static_cast<void*>(&r)),
|
||||
"\tvoid map::remove_any"
|
||||
<< "\n\tsize() must be greater than zero if something is going to be removed"
|
||||
<< "\n\tand d and r must not be the same variable."
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << static_cast<void*>(&d)
|
||||
<< "\n\t&r: " << static_cast<void*>(&r)
|
||||
);
|
||||
|
||||
// call the real function
|
||||
map_base::remove_any(d,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename map_base
|
||||
>
|
||||
void map_kernel_c<map_base>::
|
||||
remove (
|
||||
const domain& d,
|
||||
domain& d_copy,
|
||||
range& r
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( (this->is_in_domain(d)) &&
|
||||
(static_cast<const void*>(&d) != static_cast<void*>(&r)) &&
|
||||
(static_cast<void*>(&r) != static_cast<void*>(&d_copy)) &&
|
||||
(static_cast<const void*>(&d) != static_cast<void*>(&d_copy)),
|
||||
"\tvoid map::remove"
|
||||
<< "\n\tcan't remove something that isn't in the map or if the paremeters actually"
|
||||
<< "\n\tare the same variable. Either way can't remove."
|
||||
<< "\n\tis_in_domain(d): " << (this->is_in_domain(d) ? "true" : "false")
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << static_cast<const void*>(&d)
|
||||
<< "\n\t&r: " << static_cast<void*>(&r)
|
||||
<< "\n\t&d_copy: " << static_cast<void*>(&d_copy)
|
||||
);
|
||||
|
||||
// call the real function
|
||||
map_base::remove(d,d_copy,r);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename map_base
|
||||
>
|
||||
void map_kernel_c<map_base>::
|
||||
destroy (
|
||||
const domain& d
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->is_in_domain(d),
|
||||
"\tvoid map::destroy"
|
||||
<< "\n\tcan't remove something that isn't in the map"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&d: " << static_cast<const void*>(&d)
|
||||
);
|
||||
|
||||
// call the real function
|
||||
map_base::destroy(d);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename map_base
|
||||
>
|
||||
typename map_base::range_type& map_kernel_c<map_base>::
|
||||
operator[] (
|
||||
const domain& d
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( this->is_in_domain(d),
|
||||
"\trange& map::operator[]"
|
||||
<< "\n\td must be in the domain of the map"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return map_base::operator[](d);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename map_base
|
||||
>
|
||||
const typename map_base::range_type& map_kernel_c<map_base>::
|
||||
operator[] (
|
||||
const domain& d
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( this->is_in_domain(d),
|
||||
"\tconst range& map::operator[]"
|
||||
<< "\n\td must be in the domain of the map"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return map_base::operator[](d);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MAP_KERNEl_C_
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright (C) 2005 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMBER_FUNCTION_POINTEr_
|
||||
#define DLIB_MEMBER_FUNCTION_POINTEr_
|
||||
|
||||
#include "member_function_pointer/member_function_pointer_kernel_1.h"
|
||||
#include "member_function_pointer/make_mfp.h"
|
||||
|
||||
#endif // DLIB_MEMBER_FUNCTION_POINTEr_
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MAKE_MFp_H_
|
||||
#define DLIB_MAKE_MFp_H_
|
||||
|
||||
#include "member_function_pointer_kernel_1.h"
|
||||
#include "make_mfp_abstract.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
member_function_pointer<> make_mfp (
|
||||
T& object,
|
||||
void (T::*cb)()
|
||||
)
|
||||
{
|
||||
member_function_pointer<> temp;
|
||||
temp.set(object, cb);
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
member_function_pointer<> make_mfp (
|
||||
const T& object,
|
||||
void (T::*cb)()const
|
||||
)
|
||||
{
|
||||
member_function_pointer<> temp;
|
||||
temp.set(object, cb);
|
||||
return temp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1
|
||||
>
|
||||
member_function_pointer<A1> make_mfp (
|
||||
T& object,
|
||||
void (T::*cb)(A1)
|
||||
)
|
||||
{
|
||||
member_function_pointer<A1> temp;
|
||||
temp.set(object, cb);
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1
|
||||
>
|
||||
member_function_pointer<A1> make_mfp (
|
||||
const T& object,
|
||||
void (T::*cb)(A1)const
|
||||
)
|
||||
{
|
||||
member_function_pointer<A1> temp;
|
||||
temp.set(object, cb);
|
||||
return temp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2
|
||||
>
|
||||
member_function_pointer<A1,A2> make_mfp (
|
||||
T& object,
|
||||
void (T::*cb)(A1,A2)
|
||||
)
|
||||
{
|
||||
member_function_pointer<A1,A2> temp;
|
||||
temp.set(object, cb);
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2
|
||||
>
|
||||
member_function_pointer<A1,A2> make_mfp (
|
||||
const T& object,
|
||||
void (T::*cb)(A1,A2)const
|
||||
)
|
||||
{
|
||||
member_function_pointer<A1,A2> temp;
|
||||
temp.set(object, cb);
|
||||
return temp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2,
|
||||
typename A3
|
||||
>
|
||||
member_function_pointer<A1,A2,A3> make_mfp (
|
||||
T& object,
|
||||
void (T::*cb)(A1,A2,A3)
|
||||
)
|
||||
{
|
||||
member_function_pointer<A1,A2,A3> temp;
|
||||
temp.set(object, cb);
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2,
|
||||
typename A3
|
||||
>
|
||||
member_function_pointer<A1,A2,A3> make_mfp (
|
||||
const T& object,
|
||||
void (T::*cb)(A1,A2,A3)const
|
||||
)
|
||||
{
|
||||
member_function_pointer<A1,A2,A3> temp;
|
||||
temp.set(object, cb);
|
||||
return temp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2,
|
||||
typename A3,
|
||||
typename A4
|
||||
>
|
||||
member_function_pointer<A1,A2,A3,A4> make_mfp (
|
||||
T& object,
|
||||
void (T::*cb)(A1,A2,A3,A4)
|
||||
)
|
||||
{
|
||||
member_function_pointer<A1,A2,A3,A4> temp;
|
||||
temp.set(object, cb);
|
||||
return temp;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2,
|
||||
typename A3,
|
||||
typename A4
|
||||
>
|
||||
member_function_pointer<A1,A2,A3,A4> make_mfp (
|
||||
const T& object,
|
||||
void (T::*cb)(A1,A2,A3,A4)const
|
||||
)
|
||||
{
|
||||
member_function_pointer<A1,A2,A3,A4> temp;
|
||||
temp.set(object, cb);
|
||||
return temp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MAKE_MFp_H_
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_MAKE_MFp_ABSTRACT_
|
||||
#ifdef DLIB_MAKE_MFp_ABSTRACT_
|
||||
|
||||
#include "member_function_pointer_kernel_abstract.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
member_function_pointer<> make_mfp (
|
||||
T& object,
|
||||
void (T::*cb)()
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- returns a member function pointer object MFP such that:
|
||||
- MFP.is_set() == true
|
||||
- calls to MFP() will call (object.*cb)()
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
member_function_pointer<> make_mfp (
|
||||
const T& object,
|
||||
void (T::*cb)()const
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- returns a member function pointer object MFP such that:
|
||||
- MFP.is_set() == true
|
||||
- calls to MFP() will call (object.*cb)()
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1
|
||||
>
|
||||
member_function_pointer<A1> make_mfp (
|
||||
T& object,
|
||||
void (T::*cb)(A1 a1)
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- returns a member function pointer object MFP such that:
|
||||
- MFP.is_set() == true
|
||||
- calls to MFP(a1) will call (object.*cb)(a1)
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1
|
||||
>
|
||||
member_function_pointer<A1> make_mfp (
|
||||
const T& object,
|
||||
void (T::*cb)(A1 a1)const
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- returns a member function pointer object MFP such that:
|
||||
- MFP.is_set() == true
|
||||
- calls to MFP(a1) will call (object.*cb)(a1)
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2
|
||||
>
|
||||
member_function_pointer<A1,A2> make_mfp (
|
||||
T& object,
|
||||
void (T::*cb)(A1 a1, A2 a2)
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- returns a member function pointer object MFP such that:
|
||||
- MFP.is_set() == true
|
||||
- calls to MFP(a1,a2) will call (object.*cb)(a1,a2)
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2
|
||||
>
|
||||
member_function_pointer<A1,A2> make_mfp (
|
||||
const T& object,
|
||||
void (T::*cb)(A1 a1, A2 a2)const
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- returns a member function pointer object MFP such that:
|
||||
- MFP.is_set() == true
|
||||
- calls to MFP(a1,a2) will call (object.*cb)(a1,a2)
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2,
|
||||
typename A3
|
||||
>
|
||||
member_function_pointer<A1,A2,A3> make_mfp (
|
||||
T& object,
|
||||
void (T::*cb)(A1 a1, A2 a2, A3 a3)
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- returns a member function pointer object MFP such that:
|
||||
- MFP.is_set() == true
|
||||
- calls to MFP(a1,a2,a3) will call (object.*cb)(a1,a2,a3)
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2,
|
||||
typename A3
|
||||
>
|
||||
member_function_pointer<A1,A2,A3> make_mfp (
|
||||
const T& object,
|
||||
void (T::*cb)(A1 a1, A2 a2, A3 a3)const
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- returns a member function pointer object MFP such that:
|
||||
- MFP.is_set() == true
|
||||
- calls to MFP(a1,a2,a3) will call (object.*cb)(a1,a2,a3)
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2,
|
||||
typename A3,
|
||||
typename A4
|
||||
>
|
||||
member_function_pointer<A1,A2,A3,A4> make_mfp (
|
||||
T& object,
|
||||
void (T::*cb)(A1 a1, A2 a2, A3 a3, A4 a4)
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- returns a member function pointer object MFP such that:
|
||||
- MFP.is_set() == true
|
||||
- calls to MFP(a1,a2,a3,a4) will call (object.*cb)(a1,a2,a3,a4)
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename A1,
|
||||
typename A2,
|
||||
typename A3,
|
||||
typename A4
|
||||
>
|
||||
member_function_pointer<A1,A2,A3,A4> make_mfp (
|
||||
const T& object,
|
||||
void (T::*cb)(A1 a1, A2 a2, A3 a3, A4 a4)const
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- returns a member function pointer object MFP such that:
|
||||
- MFP.is_set() == true
|
||||
- calls to MFP(a1,a2,a3,a4) will call (object.*cb)(a1,a2,a3,a4)
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MAKE_MFp_ABSTRACT_
|
||||
|
||||
|
||||
@@ -0,0 +1,509 @@
|
||||
// Copyright (C) 2005 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMBER_FUNCTION_POINTER_KERNEl_1_
|
||||
#define DLIB_MEMBER_FUNCTION_POINTER_KERNEl_1_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "member_function_pointer_kernel_abstract.h"
|
||||
#include "../enable_if.h"
|
||||
#include <new>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename PARAM1 = void,
|
||||
typename PARAM2 = void,
|
||||
typename PARAM3 = void,
|
||||
typename PARAM4 = void
|
||||
>
|
||||
class member_function_pointer;
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#define DLIB_MFP_SC DLIB_ASSERT(cb != 0, \
|
||||
"\tvoid member_function_pointer::set" \
|
||||
<< "\n\tthe member function pointer can't be null" \
|
||||
<< "\n\tthis: " << this );
|
||||
|
||||
|
||||
#define DLIB_MFP_OC DLIB_ASSERT(this->is_set() == true , \
|
||||
"\tvoid member_function_pointer::operator()" \
|
||||
<< "\n\tYou must call set() before you can use this function" \
|
||||
<< "\n\tthis: " << this);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <unsigned long num_args>
|
||||
class mfp_kernel_1_base_class
|
||||
{
|
||||
/*
|
||||
All member function pointer classes inherit from this class. This
|
||||
is where most of the things in a member function pointer are defined.
|
||||
|
||||
The reason for the num_args template argument to this class is to prevent
|
||||
any sort of implicit casting between derived member function pointer classes
|
||||
that take different numbers of arguments.
|
||||
*/
|
||||
protected:
|
||||
enum mfp_type { mfp_nonconst, mfp_const, mfp_null};
|
||||
|
||||
class mp_base_base
|
||||
{
|
||||
public:
|
||||
mp_base_base(void* ptr, mfp_type type_) : o(ptr),type(type_) {}
|
||||
virtual ~mp_base_base(){}
|
||||
virtual void clone(void* ptr) const = 0;
|
||||
virtual bool is_same (const mp_base_base* item) const = 0;
|
||||
bool is_set () const { return o!=0; }
|
||||
|
||||
void* const o;
|
||||
const mfp_type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_null : public mp_base_base
|
||||
{
|
||||
public:
|
||||
typedef void (T::*mfp_pointer_type)() ;
|
||||
|
||||
mp_null (void* , mfp_pointer_type ) : mp_base_base(0,mfp_null), callback(0) {}
|
||||
mp_null () : mp_base_base(0,mfp_null), callback(0) {}
|
||||
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
template <typename mp_impl>
|
||||
class mp_impl_T : public mp_impl
|
||||
{
|
||||
/*
|
||||
This class supplies the implementations clone() and is_same() for any
|
||||
classes that inherit from mp_base_base. It does this in a very
|
||||
roundabout way...
|
||||
*/
|
||||
|
||||
public:
|
||||
typedef typename mp_impl::mfp_pointer_type mfp_pointer_type;
|
||||
|
||||
mp_impl_T() : mp_impl(0,0) {}
|
||||
mp_impl_T(void* ptr, mfp_pointer_type cb) : mp_impl(ptr,cb) {}
|
||||
|
||||
template <unsigned long mem_size>
|
||||
void safe_clone(stack_based_memory_block<mem_size>& buf)
|
||||
{
|
||||
// This is here just to validate the assumption that our block of memory we have made
|
||||
// in mp_memory is the right size to store the data for this object. If you
|
||||
// get a compiler error on this line then email me :)
|
||||
COMPILE_TIME_ASSERT(sizeof(mp_impl_T) <= mem_size);
|
||||
clone(buf.get());
|
||||
}
|
||||
|
||||
void clone (void* ptr) const { new(ptr) mp_impl_T(this->o,this->callback); }
|
||||
bool is_same (const mp_base_base* item) const
|
||||
{
|
||||
if (item->o == 0 && this->o == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (item->o == this->o && this->type == item->type)
|
||||
{
|
||||
const mp_impl* i = reinterpret_cast<const mp_impl*>(item);
|
||||
return (i->callback == this->callback);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// MSVC with the /vms option, we get C2287 since the dummy class requires virtual
|
||||
// inheritance. Adding the __virtual_inheritance specifier explicitly fixes the issue,
|
||||
// but then Clang-CL no longer accepts it.
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define DLIB_MSVC_INHERITANCE_VIRTUAL __virtual_inheritance
|
||||
#else
|
||||
#define DLIB_MSVC_INHERITANCE_VIRTUAL
|
||||
#endif
|
||||
|
||||
struct dummy_base { virtual void nonnull() {}; virtual ~dummy_base(){}; int a; };
|
||||
struct DLIB_MSVC_INHERITANCE_VIRTUAL dummy : virtual public dummy_base{ void nonnull() {}; };
|
||||
|
||||
#undef DLIB_MSVC_INHERITANCE_VIRTUAL
|
||||
|
||||
typedef mp_impl_T<mp_null<dummy> > mp_null_impl;
|
||||
public:
|
||||
|
||||
mfp_kernel_1_base_class (
|
||||
const mfp_kernel_1_base_class& item
|
||||
) { item.mp()->clone(mp_memory.get()); }
|
||||
|
||||
mfp_kernel_1_base_class (
|
||||
) { mp_null_impl().safe_clone(mp_memory); }
|
||||
|
||||
bool operator == (
|
||||
const mfp_kernel_1_base_class& item
|
||||
) const { return mp()->is_same(item.mp()); }
|
||||
|
||||
bool operator != (
|
||||
const mfp_kernel_1_base_class& item
|
||||
) const { return !(*this == item); }
|
||||
|
||||
mfp_kernel_1_base_class& operator= (
|
||||
const mfp_kernel_1_base_class& item
|
||||
) { mfp_kernel_1_base_class(item).swap(*this); return *this; }
|
||||
|
||||
~mfp_kernel_1_base_class (
|
||||
) { destroy_mp_memory(); }
|
||||
|
||||
void clear(
|
||||
) { mfp_kernel_1_base_class().swap(*this); }
|
||||
|
||||
bool is_set (
|
||||
) const { return mp()->is_set(); }
|
||||
|
||||
private:
|
||||
typedef void (dummy::*safe_bool)();
|
||||
|
||||
public:
|
||||
operator safe_bool () const { return is_set() ? &dummy::nonnull : 0; }
|
||||
bool operator!() const { return !is_set(); }
|
||||
|
||||
void swap (
|
||||
mfp_kernel_1_base_class& item
|
||||
)
|
||||
{
|
||||
// make a temp copy of item
|
||||
mfp_kernel_1_base_class temp(item);
|
||||
|
||||
// destory the stuff in item
|
||||
item.destroy_mp_memory();
|
||||
// copy *this into item
|
||||
mp()->clone(item.mp_memory.get());
|
||||
|
||||
// destory the stuff in this
|
||||
destroy_mp_memory();
|
||||
// copy temp into *this
|
||||
temp.mp()->clone(mp_memory.get());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// The reason for adding 1 here is because visual studio 2003 will sometimes
|
||||
// try to compile this code with sizeof(mp_null_impl) == 0 (which is a bug in visual studio).
|
||||
// Fortunately, no actual real instances of this template seem to end up with that screwed up
|
||||
// value so everything works fine if we just add 1 so that this degenerate case doesn't cause
|
||||
// trouble. Note that we know it all works fine because safe_clone() checks the size of this
|
||||
// memory block whenever the member function pointer is used.
|
||||
stack_based_memory_block<sizeof(mp_null_impl)+1> mp_memory;
|
||||
|
||||
void destroy_mp_memory (
|
||||
)
|
||||
{
|
||||
// Honestly this probably doesn't even do anything but I'm putting
|
||||
// it here just for good measure.
|
||||
mp()->~mp_base_base();
|
||||
}
|
||||
|
||||
mp_base_base* mp () { return static_cast<mp_base_base*>(mp_memory.get()); }
|
||||
const mp_base_base* mp () const { return static_cast<const mp_base_base*>(mp_memory.get()); }
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <>
|
||||
class member_function_pointer<void,void,void,void> : public mfp_kernel_1_base_class<0>
|
||||
{
|
||||
class mp_base : public mp_base_base {
|
||||
public:
|
||||
mp_base(void* ptr, mfp_type type_) : mp_base_base(ptr,type_) {}
|
||||
virtual void call() const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_impl : public mp_base {
|
||||
public:
|
||||
typedef void (T::*mfp_pointer_type)() ;
|
||||
void call () const { (static_cast<T*>(this->o)->*callback)(); }
|
||||
|
||||
mp_impl ( void* object, mfp_pointer_type cb) : mp_base(object, mfp_nonconst), callback(cb) {}
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_impl_const : public mp_base {
|
||||
public:
|
||||
typedef void ((T::*mfp_pointer_type)()const);
|
||||
void call () const { (static_cast<const T*>(this->o)->*callback)(); }
|
||||
|
||||
mp_impl_const ( void* object, mfp_pointer_type cb) : mp_base(object,mfp_const), callback(cb) {}
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef void param1_type;
|
||||
typedef void param2_type;
|
||||
typedef void param3_type;
|
||||
typedef void param4_type;
|
||||
|
||||
// These two typedefs are here for backwards compatibility with previous versions
|
||||
// of dlib.
|
||||
typedef member_function_pointer kernel_1a;
|
||||
typedef member_function_pointer kernel_1a_c;
|
||||
|
||||
|
||||
void operator() () const { DLIB_MFP_OC; static_cast<const mp_base*>(mp_memory.get())->call(); }
|
||||
|
||||
// the reason for putting disable_if on this function is that it avoids an overload
|
||||
// resolution bug in visual studio.
|
||||
template <typename T> typename disable_if<is_const_type<T>,void>::type
|
||||
set(T& object, typename mp_impl<T>::mfp_pointer_type cb)
|
||||
{ DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl<T> >(&object,cb).safe_clone(mp_memory); }
|
||||
|
||||
template <typename T> void set(const T& object, typename mp_impl_const<T>::mfp_pointer_type cb)
|
||||
{ DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl_const<T> >((void*)&object,cb).safe_clone(mp_memory); }
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename PARAM1
|
||||
>
|
||||
class member_function_pointer<PARAM1,void,void,void> : public mfp_kernel_1_base_class<1>
|
||||
{
|
||||
class mp_base : public mp_base_base {
|
||||
public:
|
||||
mp_base(void* ptr, mfp_type type_) : mp_base_base(ptr,type_) {}
|
||||
virtual void call(PARAM1) const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_impl : public mp_base {
|
||||
public:
|
||||
typedef void (T::*mfp_pointer_type)(PARAM1) ;
|
||||
void call (PARAM1 p1) const { (static_cast<T*>(this->o)->*callback)(p1); }
|
||||
|
||||
mp_impl ( void* object, mfp_pointer_type cb) : mp_base(object, mfp_nonconst), callback(cb) {}
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_impl_const : public mp_base {
|
||||
public:
|
||||
typedef void ((T::*mfp_pointer_type)(PARAM1)const);
|
||||
void call (PARAM1 p1) const { (static_cast<const T*>(this->o)->*callback)(p1); }
|
||||
|
||||
mp_impl_const ( void* object, mfp_pointer_type cb) : mp_base(object,mfp_const), callback(cb) {}
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef PARAM1 param1_type;
|
||||
typedef void param2_type;
|
||||
typedef void param3_type;
|
||||
typedef void param4_type;
|
||||
|
||||
// These two typedefs are here for backwards compatibility with previous versions
|
||||
// of dlib.
|
||||
typedef member_function_pointer kernel_1a;
|
||||
typedef member_function_pointer kernel_1a_c;
|
||||
|
||||
|
||||
void operator() (PARAM1 p1) const { DLIB_MFP_OC; static_cast<const mp_base*>(mp_memory.get())->call(p1); }
|
||||
|
||||
// the reason for putting disable_if on this function is that it avoids an overload
|
||||
// resolution bug in visual studio.
|
||||
template <typename T> typename disable_if<is_const_type<T>,void>::type
|
||||
set(T& object, typename mp_impl<T>::mfp_pointer_type cb)
|
||||
{ DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl<T> >(&object,cb).safe_clone(mp_memory); }
|
||||
|
||||
template <typename T> void set(const T& object, typename mp_impl_const<T>::mfp_pointer_type cb)
|
||||
{ DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl_const<T> >((void*)&object,cb).safe_clone(mp_memory); }
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename PARAM1,
|
||||
typename PARAM2
|
||||
>
|
||||
class member_function_pointer<PARAM1,PARAM2,void,void> : public mfp_kernel_1_base_class<2>
|
||||
{
|
||||
class mp_base : public mp_base_base {
|
||||
public:
|
||||
mp_base(void* ptr, mfp_type type_) : mp_base_base(ptr,type_) {}
|
||||
virtual void call(PARAM1,PARAM2) const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_impl : public mp_base {
|
||||
public:
|
||||
typedef void (T::*mfp_pointer_type)(PARAM1,PARAM2) ;
|
||||
void call (PARAM1 p1, PARAM2 p2) const { (static_cast<T*>(this->o)->*callback)(p1,p2); }
|
||||
|
||||
mp_impl ( void* object, mfp_pointer_type cb) : mp_base(object, mfp_nonconst), callback(cb) {}
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_impl_const : public mp_base {
|
||||
public:
|
||||
typedef void ((T::*mfp_pointer_type)(PARAM1,PARAM2)const);
|
||||
void call (PARAM1 p1, PARAM2 p2) const { (static_cast<const T*>(this->o)->*callback)(p1,p2); }
|
||||
|
||||
mp_impl_const ( void* object, mfp_pointer_type cb) : mp_base(object,mfp_const), callback(cb) {}
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef PARAM1 param1_type;
|
||||
typedef PARAM2 param2_type;
|
||||
typedef void param3_type;
|
||||
typedef void param4_type;
|
||||
|
||||
// These two typedefs are here for backwards compatibility with previous versions
|
||||
// of dlib.
|
||||
typedef member_function_pointer kernel_1a;
|
||||
typedef member_function_pointer kernel_1a_c;
|
||||
|
||||
void operator() (PARAM1 p1, PARAM2 p2) const { DLIB_MFP_OC; static_cast<const mp_base*>(mp_memory.get())->call(p1,p2); }
|
||||
|
||||
// the reason for putting disable_if on this function is that it avoids an overload
|
||||
// resolution bug in visual studio.
|
||||
template <typename T> typename disable_if<is_const_type<T>,void>::type
|
||||
set(T& object, typename mp_impl<T>::mfp_pointer_type cb)
|
||||
{ DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl<T> >(&object,cb).safe_clone(mp_memory); }
|
||||
|
||||
template <typename T> void set(const T& object, typename mp_impl_const<T>::mfp_pointer_type cb)
|
||||
{ DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl_const<T> >((void*)&object,cb).safe_clone(mp_memory); }
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename PARAM1,
|
||||
typename PARAM2,
|
||||
typename PARAM3
|
||||
>
|
||||
class member_function_pointer<PARAM1,PARAM2,PARAM3,void> : public mfp_kernel_1_base_class<3>
|
||||
{
|
||||
class mp_base : public mp_base_base {
|
||||
public:
|
||||
mp_base(void* ptr, mfp_type type_) : mp_base_base(ptr,type_) {}
|
||||
virtual void call(PARAM1,PARAM2,PARAM3) const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_impl : public mp_base {
|
||||
public:
|
||||
typedef void (T::*mfp_pointer_type)(PARAM1,PARAM2,PARAM3) ;
|
||||
void call (PARAM1 p1, PARAM2 p2, PARAM3 p3) const { (static_cast<T*>(this->o)->*callback)(p1,p2,p3); }
|
||||
|
||||
mp_impl ( void* object, mfp_pointer_type cb) : mp_base(object, mfp_nonconst), callback(cb) {}
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_impl_const : public mp_base {
|
||||
public:
|
||||
typedef void ((T::*mfp_pointer_type)(PARAM1,PARAM2,PARAM3)const);
|
||||
void call (PARAM1 p1, PARAM2 p2, PARAM3 p3) const { (static_cast<const T*>(this->o)->*callback)(p1,p2,p3); }
|
||||
|
||||
mp_impl_const ( void* object, mfp_pointer_type cb) : mp_base(object,mfp_const), callback(cb) {}
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef PARAM1 param1_type;
|
||||
typedef PARAM2 param2_type;
|
||||
typedef PARAM3 param3_type;
|
||||
typedef void param4_type;
|
||||
|
||||
// These two typedefs are here for backwards compatibility with previous versions
|
||||
// of dlib.
|
||||
typedef member_function_pointer kernel_1a;
|
||||
typedef member_function_pointer kernel_1a_c;
|
||||
|
||||
void operator() (PARAM1 p1, PARAM2 p2, PARAM3 p3) const { DLIB_MFP_OC; static_cast<const mp_base*>(mp_memory.get())->call(p1,p2,p3); }
|
||||
|
||||
// the reason for putting disable_if on this function is that it avoids an overload
|
||||
// resolution bug in visual studio.
|
||||
template <typename T> typename disable_if<is_const_type<T>,void>::type
|
||||
set(T& object, typename mp_impl<T>::mfp_pointer_type cb)
|
||||
{ DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl<T> >(&object,cb).safe_clone(mp_memory); }
|
||||
|
||||
template <typename T> void set(const T& object, typename mp_impl_const<T>::mfp_pointer_type cb)
|
||||
{ DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl_const<T> >((void*)&object,cb).safe_clone(mp_memory); }
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename PARAM1,
|
||||
typename PARAM2,
|
||||
typename PARAM3,
|
||||
typename PARAM4
|
||||
>
|
||||
class member_function_pointer : public mfp_kernel_1_base_class<4>
|
||||
{
|
||||
class mp_base : public mp_base_base {
|
||||
public:
|
||||
mp_base(void* ptr, mfp_type type_) : mp_base_base(ptr,type_) {}
|
||||
virtual void call(PARAM1,PARAM2,PARAM3,PARAM4) const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_impl : public mp_base {
|
||||
public:
|
||||
typedef void (T::*mfp_pointer_type)(PARAM1,PARAM2,PARAM3, PARAM4) ;
|
||||
void call (PARAM1 p1, PARAM2 p2, PARAM3 p3, PARAM4 p4) const { (static_cast<T*>(this->o)->*callback)(p1,p2,p3,p4); }
|
||||
|
||||
mp_impl ( void* object, mfp_pointer_type cb) : mp_base(object, mfp_nonconst), callback(cb) {}
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class mp_impl_const : public mp_base {
|
||||
public:
|
||||
typedef void ((T::*mfp_pointer_type)(PARAM1,PARAM2,PARAM3,PARAM4)const);
|
||||
void call (PARAM1 p1, PARAM2 p2, PARAM3 p3, PARAM4 p4) const { (static_cast<const T*>(this->o)->*callback)(p1,p2,p3,p4); }
|
||||
|
||||
mp_impl_const ( void* object, mfp_pointer_type cb) : mp_base(object,mfp_const), callback(cb) {}
|
||||
const mfp_pointer_type callback;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef PARAM1 param1_type;
|
||||
typedef PARAM2 param2_type;
|
||||
typedef PARAM3 param3_type;
|
||||
typedef PARAM4 param4_type;
|
||||
|
||||
// These two typedefs are here for backwards compatibility with previous versions
|
||||
// of dlib.
|
||||
typedef member_function_pointer kernel_1a;
|
||||
typedef member_function_pointer kernel_1a_c;
|
||||
|
||||
void operator() (PARAM1 p1, PARAM2 p2, PARAM3 p3, PARAM4 p4) const
|
||||
{ DLIB_MFP_OC; static_cast<const mp_base*>(mp_memory.get())->call(p1,p2,p3,p4); }
|
||||
|
||||
// the reason for putting disable_if on this function is that it avoids an overload
|
||||
// resolution bug in visual studio.
|
||||
template <typename T> typename disable_if<is_const_type<T>,void>::type
|
||||
set(T& object, typename mp_impl<T>::mfp_pointer_type cb)
|
||||
{ DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl<T> >(&object,cb).safe_clone(mp_memory); }
|
||||
|
||||
template <typename T> void set(const T& object, typename mp_impl_const<T>::mfp_pointer_type cb)
|
||||
{ DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl_const<T> >((void*)&object,cb).safe_clone(mp_memory); }
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMBER_FUNCTION_POINTER_KERNEl_1_
|
||||
|
||||
@@ -0,0 +1,483 @@
|
||||
// Copyright (C) 2005 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_MEMBER_FUNCTION_POINTER_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_MEMBER_FUNCTION_POINTER_KERNEl_ABSTRACT_
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename PARAM1 = void,
|
||||
typename PARAM2 = void,
|
||||
typename PARAM3 = void,
|
||||
typename PARAM4 = void
|
||||
>
|
||||
class member_function_pointer;
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <>
|
||||
class member_function_pointer<void,void,void,void>
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
is_set() == false
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents a member function pointer. It is useful because
|
||||
instances of this object can be created without needing to know the type
|
||||
of object whose member function we will be calling.
|
||||
|
||||
There are five template specializations of this object. The first
|
||||
represents a pointer to a member function taking no parameters, the
|
||||
second represents a pointer to a member function taking one parameter,
|
||||
the third to one taking two parameters, and so on.
|
||||
|
||||
You specify the parameters to your member function pointer by filling in
|
||||
the PARAM template parameters. For example:
|
||||
|
||||
To use a pointer to a function with no parameters you would say:
|
||||
member_function_pointer<> my_pointer;
|
||||
To use a pointer to a function that takes a single int you would say:
|
||||
member_function_pointer<int> my_pointer;
|
||||
To use a pointer to a function that takes an int and then a reference
|
||||
to a string you would say:
|
||||
member_function_pointer<int,string&> my_pointer;
|
||||
|
||||
Also note that the formal comments are only present for the first
|
||||
template specialization. They are all exactly the same except for the
|
||||
number of parameters each takes in its member function pointer.
|
||||
!*/
|
||||
|
||||
public:
|
||||
typedef void param1_type;
|
||||
typedef void param2_type;
|
||||
typedef void param3_type;
|
||||
typedef void param4_type;
|
||||
|
||||
member_function_pointer (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
!*/
|
||||
|
||||
member_function_pointer(
|
||||
const member_function_pointer& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- *this == item
|
||||
!*/
|
||||
|
||||
~member_function_pointer (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- any resources associated with *this have been released
|
||||
!*/
|
||||
|
||||
member_function_pointer& operator=(
|
||||
const member_function_pointer& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- *this == item
|
||||
!*/
|
||||
|
||||
bool operator == (
|
||||
const member_function_pointer& item
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (is_set() == false && item.is_set() == false) then
|
||||
- returns true
|
||||
- else if (both *this and item point to the same member function
|
||||
in the same object instance) then
|
||||
- returns true
|
||||
- else
|
||||
- returns false
|
||||
!*/
|
||||
|
||||
bool operator != (
|
||||
const member_function_pointer& item
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns !(*this == item)
|
||||
!*/
|
||||
|
||||
void clear(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this has its initial value
|
||||
!*/
|
||||
|
||||
bool is_set (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (this->set() has been called) then
|
||||
- returns true
|
||||
- else
|
||||
- returns false
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*cb)()
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*cb)()
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*cb)()const
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- cb == a valid member function pointer for class T
|
||||
ensures
|
||||
- #is_set() == true
|
||||
- calls to this->operator() will call (object.*cb)()
|
||||
!*/
|
||||
|
||||
operator some_undefined_pointer_type (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- if (is_set()) then
|
||||
- returns a non 0 value
|
||||
- else
|
||||
- returns a 0 value
|
||||
!*/
|
||||
|
||||
bool operator! (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns !is_set()
|
||||
!*/
|
||||
|
||||
void operator () (
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- is_set() == true
|
||||
ensures
|
||||
- calls the member function on the object specified by the last
|
||||
call to this->set()
|
||||
throws
|
||||
- any exception thrown by the member function specified by
|
||||
the previous call to this->set().
|
||||
If any of these exceptions are thrown then the call to this
|
||||
function will have no effect on *this.
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
member_function_pointer& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename PARAM1
|
||||
>
|
||||
class member_function_pointer<PARAM1,void,void,void>
|
||||
{
|
||||
public:
|
||||
typedef PARAM1 param1_type;
|
||||
typedef void param2_type;
|
||||
typedef void param3_type;
|
||||
typedef void param4_type;
|
||||
|
||||
member_function_pointer ();
|
||||
|
||||
member_function_pointer(
|
||||
const member_function_pointer& item
|
||||
);
|
||||
|
||||
~member_function_pointer (
|
||||
);
|
||||
|
||||
member_function_pointer& operator=(
|
||||
const member_function_pointer& item
|
||||
);
|
||||
|
||||
bool operator == (
|
||||
const member_function_pointer& item
|
||||
) const;
|
||||
|
||||
bool operator != (
|
||||
const member_function_pointer& item
|
||||
) const;
|
||||
|
||||
void clear();
|
||||
|
||||
bool is_set () const;
|
||||
|
||||
template <typename T>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*cb)(PARAM1)
|
||||
);
|
||||
|
||||
template <typename T>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*cb)(PARAM1)const
|
||||
);
|
||||
|
||||
operator some_undefined_pointer_type (
|
||||
) const;
|
||||
|
||||
bool operator! (
|
||||
) const;
|
||||
|
||||
void operator () (
|
||||
PARAM1 param1
|
||||
) const;
|
||||
|
||||
void swap (
|
||||
member_function_pointer& item
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename PARAM1,
|
||||
typename PARAM2
|
||||
>
|
||||
class member_function_pointer<PARAM1,PARAM2,void,void>
|
||||
{
|
||||
public:
|
||||
typedef PARAM1 param1_type;
|
||||
typedef PARAM2 param2_type;
|
||||
typedef void param3_type;
|
||||
typedef void param4_type;
|
||||
|
||||
member_function_pointer ();
|
||||
|
||||
member_function_pointer(
|
||||
const member_function_pointer& item
|
||||
);
|
||||
|
||||
~member_function_pointer (
|
||||
);
|
||||
|
||||
member_function_pointer& operator=(
|
||||
const member_function_pointer& item
|
||||
);
|
||||
|
||||
bool operator == (
|
||||
const member_function_pointer& item
|
||||
) const;
|
||||
|
||||
bool operator != (
|
||||
const member_function_pointer& item
|
||||
) const;
|
||||
|
||||
void clear();
|
||||
|
||||
bool is_set () const;
|
||||
|
||||
template <typename T>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*cb)(PARAM1,PARAM2)
|
||||
);
|
||||
|
||||
template <typename T>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*cb)(PARAM1,PARAM2)const
|
||||
);
|
||||
|
||||
operator some_undefined_pointer_type (
|
||||
) const;
|
||||
|
||||
bool operator! (
|
||||
) const;
|
||||
|
||||
void operator () (
|
||||
PARAM1 param1,
|
||||
PARAM2 param2
|
||||
) const;
|
||||
|
||||
void swap (
|
||||
member_function_pointer& item
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename PARAM1,
|
||||
typename PARAM2,
|
||||
typename PARAM3
|
||||
>
|
||||
class member_function_pointer<PARAM1,PARAM2,PARAM3,void>
|
||||
{
|
||||
public:
|
||||
typedef PARAM1 param1_type;
|
||||
typedef PARAM2 param2_type;
|
||||
typedef PARAM3 param3_type;
|
||||
typedef void param4_type;
|
||||
|
||||
member_function_pointer ();
|
||||
|
||||
member_function_pointer(
|
||||
const member_function_pointer& item
|
||||
);
|
||||
|
||||
~member_function_pointer (
|
||||
);
|
||||
|
||||
member_function_pointer& operator=(
|
||||
const member_function_pointer& item
|
||||
);
|
||||
|
||||
bool operator == (
|
||||
const member_function_pointer& item
|
||||
) const;
|
||||
|
||||
bool operator != (
|
||||
const member_function_pointer& item
|
||||
) const;
|
||||
|
||||
void clear();
|
||||
|
||||
bool is_set () const;
|
||||
|
||||
template <typename T>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*cb)(PARAM1,PARAM2,PARAM3)
|
||||
);
|
||||
|
||||
template <typename T>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*cb)(PARAM1,PARAM2,PARAM3)const
|
||||
);
|
||||
|
||||
operator some_undefined_pointer_type (
|
||||
) const;
|
||||
|
||||
bool operator! (
|
||||
) const;
|
||||
|
||||
void operator () (
|
||||
PARAM1 param1,
|
||||
PARAM2 param2,
|
||||
PARAM2 param3
|
||||
) const;
|
||||
|
||||
void swap (
|
||||
member_function_pointer& item
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename PARAM1,
|
||||
typename PARAM2,
|
||||
typename PARAM3,
|
||||
typename PARAM4
|
||||
>
|
||||
class member_function_pointer
|
||||
{
|
||||
public:
|
||||
typedef PARAM1 param1_type;
|
||||
typedef PARAM2 param2_type;
|
||||
typedef PARAM3 param3_type;
|
||||
typedef PARAM4 param4_type;
|
||||
|
||||
member_function_pointer ();
|
||||
|
||||
member_function_pointer(
|
||||
const member_function_pointer& item
|
||||
);
|
||||
|
||||
~member_function_pointer (
|
||||
);
|
||||
|
||||
member_function_pointer& operator=(
|
||||
const member_function_pointer& item
|
||||
);
|
||||
|
||||
bool operator == (
|
||||
const member_function_pointer& item
|
||||
) const;
|
||||
|
||||
bool operator != (
|
||||
const member_function_pointer& item
|
||||
) const;
|
||||
|
||||
void clear();
|
||||
|
||||
bool is_set () const;
|
||||
|
||||
template <typename T>
|
||||
void set (
|
||||
T& object,
|
||||
void (T::*cb)(PARAM1,PARAM2,PARAM3,PARAM4)
|
||||
);
|
||||
|
||||
template <typename T>
|
||||
void set (
|
||||
const T& object,
|
||||
void (T::*cb)(PARAM1,PARAM2,PARAM3,PARAM4)const
|
||||
);
|
||||
|
||||
operator some_undefined_pointer_type (
|
||||
) const;
|
||||
|
||||
bool operator! (
|
||||
) const;
|
||||
|
||||
void operator () (
|
||||
PARAM1 param1,
|
||||
PARAM2 param2,
|
||||
PARAM2 param3,
|
||||
PARAM2 param4
|
||||
) const;
|
||||
|
||||
void swap (
|
||||
member_function_pointer& item
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMBER_FUNCTION_POINTER_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMORY_MANAGEr_
|
||||
#define DLIB_MEMORY_MANAGEr_
|
||||
|
||||
#include "memory_manager/memory_manager_kernel_1.h"
|
||||
#include "memory_manager/memory_manager_kernel_2.h"
|
||||
#include "memory_manager/memory_manager_kernel_3.h"
|
||||
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class memory_manager
|
||||
{
|
||||
memory_manager() {}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//----------- kernels ---------------
|
||||
|
||||
// kernel_1
|
||||
typedef memory_manager_kernel_1<T,0>
|
||||
kernel_1a;
|
||||
typedef memory_manager_kernel_1<T,10>
|
||||
kernel_1b;
|
||||
typedef memory_manager_kernel_1<T,100>
|
||||
kernel_1c;
|
||||
typedef memory_manager_kernel_1<T,1000>
|
||||
kernel_1d;
|
||||
typedef memory_manager_kernel_1<T,10000>
|
||||
kernel_1e;
|
||||
typedef memory_manager_kernel_1<T,100000>
|
||||
kernel_1f;
|
||||
|
||||
// kernel_2
|
||||
typedef memory_manager_kernel_2<T,10>
|
||||
kernel_2a;
|
||||
typedef memory_manager_kernel_2<T,100>
|
||||
kernel_2b;
|
||||
typedef memory_manager_kernel_2<T,1000>
|
||||
kernel_2c;
|
||||
typedef memory_manager_kernel_2<T,10000>
|
||||
kernel_2d;
|
||||
typedef memory_manager_kernel_2<T,100000>
|
||||
kernel_2e;
|
||||
|
||||
|
||||
// kernel_3
|
||||
typedef memory_manager_kernel_3<T,10>
|
||||
kernel_3a;
|
||||
typedef memory_manager_kernel_3<T,100>
|
||||
kernel_3b;
|
||||
typedef memory_manager_kernel_3<T,1000>
|
||||
kernel_3c;
|
||||
typedef memory_manager_kernel_3<T,10000>
|
||||
kernel_3d;
|
||||
typedef memory_manager_kernel_3<T,100000>
|
||||
kernel_3e;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGEr_
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMORY_MANAGER_KERNEl_1_
|
||||
#define DLIB_MEMORY_MANAGER_KERNEl_1_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "memory_manager_kernel_abstract.h"
|
||||
#include "../assert.h"
|
||||
#include <new>
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
size_t max_pool_size
|
||||
>
|
||||
class memory_manager_kernel_1
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
allocations == 0
|
||||
next == 0
|
||||
pool_size == 0
|
||||
|
||||
REQUIREMENTS ON max_pool_size
|
||||
max_pool_size is the maximum number of nodes we will keep in our linked list at once.
|
||||
So you can put any value in for this argument.
|
||||
|
||||
CONVENTION
|
||||
This memory manager implementation allocates T objects one at a time when there are
|
||||
allocation requests. Then when there is a deallocate request the returning T object
|
||||
is place into a list of free blocks if that list has less than max_pool_size
|
||||
blocks in it. subsequent allocation requests will be serviced by drawing from the
|
||||
free list whenever it isn't empty.
|
||||
|
||||
|
||||
allocations == get_number_of_allocations()
|
||||
|
||||
- if (next != 0) then
|
||||
- next == the next pointer to return from allocate()
|
||||
and next == pointer to the first node in a linked list. each node
|
||||
is one item in the memory pool.
|
||||
- the last node in the linked list has next set to 0
|
||||
- pool_size == the number of nodes in the linked list
|
||||
- pool_size <= max_pool_size
|
||||
- else
|
||||
- we need to call new to get the next pointer to return from allocate()
|
||||
|
||||
!*/
|
||||
|
||||
union node
|
||||
{
|
||||
node* next;
|
||||
char item[sizeof(T)];
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
typedef memory_manager_kernel_1<U,max_pool_size> other;
|
||||
};
|
||||
|
||||
|
||||
memory_manager_kernel_1(
|
||||
) :
|
||||
allocations(0),
|
||||
next(0),
|
||||
pool_size(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~memory_manager_kernel_1(
|
||||
)
|
||||
{
|
||||
|
||||
while (next != 0)
|
||||
{
|
||||
node* temp = next;
|
||||
next = next->next;
|
||||
::operator delete ( static_cast<void*>(temp));
|
||||
}
|
||||
}
|
||||
|
||||
size_t get_number_of_allocations (
|
||||
) const { return allocations; }
|
||||
|
||||
T* allocate_array (
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
T* temp = new T[size];
|
||||
++allocations;
|
||||
return temp;
|
||||
}
|
||||
|
||||
void deallocate_array (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
--allocations;
|
||||
delete [] item;
|
||||
}
|
||||
|
||||
T* allocate (
|
||||
)
|
||||
{
|
||||
T* temp;
|
||||
if (next != 0)
|
||||
{
|
||||
temp = reinterpret_cast<T*>(next);
|
||||
|
||||
node* n = next->next;
|
||||
|
||||
try
|
||||
{
|
||||
// construct this new T object with placement new.
|
||||
new (static_cast<void*>(temp))T();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
next->next = n;
|
||||
throw;
|
||||
}
|
||||
|
||||
next = n;
|
||||
|
||||
--pool_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = static_cast<T*>(::operator new(sizeof(node)));
|
||||
try
|
||||
{
|
||||
// construct this new T object with placement new.
|
||||
new (static_cast<void*>(temp))T();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// construction of the new object threw so delete the block of memory
|
||||
::operator delete ( static_cast<void*>(temp));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
++allocations;
|
||||
return temp;
|
||||
}
|
||||
|
||||
void deallocate (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
--allocations;
|
||||
item->~T();
|
||||
|
||||
if (pool_size >= max_pool_size)
|
||||
{
|
||||
::operator delete ( static_cast<void*>(item));
|
||||
return;
|
||||
}
|
||||
|
||||
// add this memory chunk into our linked list.
|
||||
node* temp = reinterpret_cast<node*>(item);
|
||||
temp->next = next;
|
||||
next = temp;
|
||||
++pool_size;
|
||||
}
|
||||
|
||||
void swap (
|
||||
memory_manager_kernel_1& item
|
||||
)
|
||||
{
|
||||
exchange(allocations,item.allocations);
|
||||
exchange(next,item.next);
|
||||
exchange(pool_size,item.pool_size);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// data members
|
||||
size_t allocations;
|
||||
node* next;
|
||||
size_t pool_size;
|
||||
|
||||
// restricted functions
|
||||
memory_manager_kernel_1(memory_manager_kernel_1&); // copy constructor
|
||||
memory_manager_kernel_1& operator=(memory_manager_kernel_1&); // assignment operator
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class memory_manager_kernel_1<T,0>
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
allocations == 0
|
||||
|
||||
CONVENTION
|
||||
This memory manager just calls new and delete directly so it doesn't
|
||||
really do anything.
|
||||
|
||||
allocations == get_number_of_allocations()
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
typedef memory_manager_kernel_1<U,0> other;
|
||||
};
|
||||
|
||||
|
||||
memory_manager_kernel_1(
|
||||
) :
|
||||
allocations(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~memory_manager_kernel_1(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
size_t get_number_of_allocations (
|
||||
) const { return allocations; }
|
||||
|
||||
T* allocate_array (
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
T* temp = new T[size];
|
||||
++allocations;
|
||||
return temp;
|
||||
}
|
||||
|
||||
void deallocate_array (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
--allocations;
|
||||
delete [] item;
|
||||
}
|
||||
|
||||
T* allocate (
|
||||
)
|
||||
{
|
||||
T* temp = new T;
|
||||
++allocations;
|
||||
return temp;
|
||||
}
|
||||
|
||||
void deallocate (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
delete item;
|
||||
--allocations;
|
||||
}
|
||||
|
||||
void swap (
|
||||
memory_manager_kernel_1& item
|
||||
)
|
||||
{
|
||||
exchange(allocations,item.allocations);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// data members
|
||||
size_t allocations;
|
||||
|
||||
// restricted functions
|
||||
memory_manager_kernel_1(memory_manager_kernel_1&); // copy constructor
|
||||
memory_manager_kernel_1& operator=(memory_manager_kernel_1&); // assignment operator
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
size_t max_pool_size
|
||||
>
|
||||
inline void swap (
|
||||
memory_manager_kernel_1<T,max_pool_size>& a,
|
||||
memory_manager_kernel_1<T,max_pool_size>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_KERNEl_1_
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMORY_MANAGER_KERNEl_2_
|
||||
#define DLIB_MEMORY_MANAGER_KERNEl_2_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "memory_manager_kernel_abstract.h"
|
||||
#include "../assert.h"
|
||||
#include <new>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
size_t chunk_size
|
||||
>
|
||||
class memory_manager_kernel_2
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
allocations == 0
|
||||
next == 0
|
||||
first_chunk == 0
|
||||
|
||||
REQUIREMENTS ON chunk_size
|
||||
chunk_size is the number of items of type T we will allocate at a time. so
|
||||
it must be > 0.
|
||||
|
||||
CONVENTION
|
||||
This memory manager implementation allocates memory in blocks of chunk_size*sizeof(T)
|
||||
bytes. All the sizeof(T) subblocks are kept in a linked list of free memory blocks
|
||||
and are given out whenever an allocation request occurs. Also, memory is not freed
|
||||
until this object is destructed.
|
||||
|
||||
Note that array allocations are not memory managed.
|
||||
|
||||
|
||||
|
||||
allocations == get_number_of_allocations()
|
||||
|
||||
- if (next != 0) then
|
||||
- next == the next pointer to return from allocate()
|
||||
and next == pointer to the first node in a linked list. each node
|
||||
is one item in the memory pool.
|
||||
- the last node in the linked list has next set to 0
|
||||
- else
|
||||
- we need to call new to get the next pointer to return from allocate()
|
||||
|
||||
|
||||
- if (first_chunk != 0) then
|
||||
- first_chunk == the first node in a linked list that contains pointers
|
||||
to all the chunks we have ever allocated. The last link in the list
|
||||
has its next pointer set to 0.
|
||||
!*/
|
||||
|
||||
union node
|
||||
{
|
||||
node* next;
|
||||
char item[sizeof(T)];
|
||||
};
|
||||
|
||||
struct chunk_node
|
||||
{
|
||||
node* chunk;
|
||||
chunk_node* next;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
typedef memory_manager_kernel_2<U,chunk_size> other;
|
||||
};
|
||||
|
||||
|
||||
memory_manager_kernel_2(
|
||||
) :
|
||||
allocations(0),
|
||||
next(0),
|
||||
first_chunk(0)
|
||||
{
|
||||
// You FOOL! You can't have a zero chunk_size.
|
||||
COMPILE_TIME_ASSERT(chunk_size > 0);
|
||||
}
|
||||
|
||||
virtual ~memory_manager_kernel_2(
|
||||
)
|
||||
{
|
||||
if (allocations == 0)
|
||||
{
|
||||
while (first_chunk != 0)
|
||||
{
|
||||
chunk_node* temp = first_chunk;
|
||||
first_chunk = first_chunk->next;
|
||||
// delete the memory chunk
|
||||
::operator delete ( static_cast<void*>(temp->chunk));
|
||||
// delete the chunk_node
|
||||
delete temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t get_number_of_allocations (
|
||||
) const { return allocations; }
|
||||
|
||||
T* allocate_array (
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
T* temp = new T[size];
|
||||
++allocations;
|
||||
return temp;
|
||||
}
|
||||
|
||||
void deallocate_array (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
--allocations;
|
||||
delete [] item;
|
||||
}
|
||||
|
||||
T* allocate (
|
||||
)
|
||||
{
|
||||
T* temp = 0;
|
||||
if (next != 0)
|
||||
{
|
||||
temp = reinterpret_cast<T*>(next);
|
||||
node* n = next->next;
|
||||
|
||||
try
|
||||
{
|
||||
// construct this new T object with placement new.
|
||||
new (static_cast<void*>(temp))T();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
next->next = n;
|
||||
throw;
|
||||
}
|
||||
|
||||
next = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
// the linked list is empty so we need to allocate some more memory
|
||||
node* block = 0;
|
||||
block = static_cast<node*>(::operator new (sizeof(node)*chunk_size));
|
||||
|
||||
// the first part of this block can be our new object
|
||||
temp = reinterpret_cast<T*>(block);
|
||||
|
||||
try
|
||||
{
|
||||
// construct this new T object with placement new.
|
||||
new (static_cast<void*>(temp))T();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// construction of the new object threw so delete the block of memory
|
||||
::operator delete ( static_cast<void*>(block));
|
||||
throw;
|
||||
}
|
||||
|
||||
// allocate a new chunk_node
|
||||
chunk_node* chunk;
|
||||
try {chunk = new chunk_node; }
|
||||
catch (...)
|
||||
{
|
||||
temp->~T();
|
||||
::operator delete ( static_cast<void*>(block));
|
||||
throw;
|
||||
}
|
||||
|
||||
// add this block into the chunk list
|
||||
chunk->chunk = block;
|
||||
chunk->next = first_chunk;
|
||||
first_chunk = chunk;
|
||||
|
||||
|
||||
++block;
|
||||
// now add the rest of the block into the linked list of free nodes.
|
||||
for (size_t i = 0; i < chunk_size-1; ++i)
|
||||
{
|
||||
block->next = next;
|
||||
next = block;
|
||||
++block;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
++allocations;
|
||||
return temp;
|
||||
}
|
||||
|
||||
void deallocate (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
--allocations;
|
||||
item->~T();
|
||||
|
||||
// add this memory into our linked list.
|
||||
node* temp = reinterpret_cast<node*>(item);
|
||||
temp->next = next;
|
||||
next = temp;
|
||||
}
|
||||
|
||||
void swap (
|
||||
memory_manager_kernel_2& item
|
||||
)
|
||||
{
|
||||
exchange(allocations,item.allocations);
|
||||
exchange(next,item.next);
|
||||
exchange(first_chunk,item.first_chunk);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// data members
|
||||
size_t allocations;
|
||||
node* next;
|
||||
|
||||
chunk_node* first_chunk;
|
||||
|
||||
|
||||
|
||||
|
||||
// restricted functions
|
||||
memory_manager_kernel_2(memory_manager_kernel_2&); // copy constructor
|
||||
memory_manager_kernel_2& operator=(memory_manager_kernel_2&); // assignment operator
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
size_t chunk_size
|
||||
>
|
||||
inline void swap (
|
||||
memory_manager_kernel_2<T,chunk_size>& a,
|
||||
memory_manager_kernel_2<T,chunk_size>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_KERNEl_2_
|
||||
|
||||
@@ -0,0 +1,385 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMORY_MANAGER_KERNEl_3_
|
||||
#define DLIB_MEMORY_MANAGER_KERNEl_3_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "memory_manager_kernel_abstract.h"
|
||||
#include "../assert.h"
|
||||
#include <new>
|
||||
#include "memory_manager_kernel_2.h"
|
||||
#include "../binary_search_tree/binary_search_tree_kernel_2.h"
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
size_t chunk_size
|
||||
>
|
||||
class memory_manager_kernel_3
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
allocations == 0
|
||||
next == 0
|
||||
first_chunk == 0
|
||||
bst_of_arrays == 0
|
||||
|
||||
REQUIREMENTS ON chunk_size
|
||||
chunk_size is the number of items of type T we will allocate at a time. so
|
||||
it must be > 0.
|
||||
|
||||
CONVENTION
|
||||
This memory manager implementation allocates memory in blocks of chunk_size*sizeof(T)
|
||||
bytes. All the sizeof(T) subblocks are kept in a linked list of free memory blocks
|
||||
and are given out whenever an allocation request occurs. Also, memory is not freed
|
||||
until this object is destructed.
|
||||
|
||||
|
||||
|
||||
allocations == get_number_of_allocations()
|
||||
|
||||
- if (next != 0) then
|
||||
- next == the next pointer to return from allocate()
|
||||
and next == pointer to the first node in a linked list. each node
|
||||
is one item in the memory pool.
|
||||
- the last node in the linked list has next set to 0
|
||||
- else
|
||||
- we need to call new to get the next pointer to return from allocate()
|
||||
|
||||
- if (arrays != 0) then
|
||||
- someone has called allocate_array()
|
||||
- (*arrays)[size] == an array of size bytes of memory
|
||||
|
||||
- if (first_chunk != 0) then
|
||||
- first_chunk == the first node in a linked list that contains pointers
|
||||
to all the chunks we have ever allocated. The last link in the list
|
||||
has its next pointer set to 0.
|
||||
!*/
|
||||
|
||||
union node
|
||||
{
|
||||
node* next;
|
||||
char item[sizeof(T)];
|
||||
};
|
||||
|
||||
struct chunk_node
|
||||
{
|
||||
node* chunk;
|
||||
chunk_node* next;
|
||||
};
|
||||
|
||||
|
||||
typedef binary_search_tree_kernel_2<
|
||||
size_t,
|
||||
char*,
|
||||
memory_manager_kernel_2<char,5>
|
||||
> bst_of_arrays;
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
typedef memory_manager_kernel_3<U,chunk_size> other;
|
||||
};
|
||||
|
||||
|
||||
memory_manager_kernel_3(
|
||||
) :
|
||||
allocations(0),
|
||||
next(0),
|
||||
first_chunk(0),
|
||||
arrays(0)
|
||||
{
|
||||
// You FOOL! You can't have a zero chunk_size.
|
||||
COMPILE_TIME_ASSERT(chunk_size > 0);
|
||||
}
|
||||
|
||||
virtual ~memory_manager_kernel_3(
|
||||
)
|
||||
{
|
||||
if (allocations == 0)
|
||||
{
|
||||
while (first_chunk != 0)
|
||||
{
|
||||
chunk_node* temp = first_chunk;
|
||||
first_chunk = first_chunk->next;
|
||||
// delete the memory chunk
|
||||
::operator delete ( static_cast<void*>(temp->chunk));
|
||||
// delete the chunk_node
|
||||
delete temp;
|
||||
}
|
||||
}
|
||||
|
||||
if (arrays)
|
||||
{
|
||||
arrays->reset();
|
||||
while (arrays->move_next())
|
||||
{
|
||||
::operator delete (arrays->element().value());
|
||||
}
|
||||
delete arrays;
|
||||
}
|
||||
}
|
||||
|
||||
size_t get_number_of_allocations (
|
||||
) const { return allocations; }
|
||||
|
||||
T* allocate_array (
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
size_t block_size = sizeof(T)*size + sizeof(size_t)*2;
|
||||
|
||||
// make sure we have initialized the arrays object.
|
||||
if (arrays == 0)
|
||||
{
|
||||
arrays = new bst_of_arrays;
|
||||
}
|
||||
|
||||
char* temp;
|
||||
|
||||
// see if we have a suitable block of memory already.
|
||||
arrays->position_enumerator(block_size);
|
||||
if (arrays->current_element_valid())
|
||||
{
|
||||
// we have a suitable block of memory already so use that one.
|
||||
arrays->remove_current_element(block_size,temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = static_cast<char*>(::operator new(block_size));
|
||||
}
|
||||
|
||||
reinterpret_cast<size_t*>(temp)[0] = block_size;
|
||||
reinterpret_cast<size_t*>(temp)[1] = size;
|
||||
temp += sizeof(size_t)*2;
|
||||
|
||||
try
|
||||
{
|
||||
initialize_array(reinterpret_cast<T*>(temp),size);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// something was thrown while we were initializing the array so
|
||||
// stick our memory block into arrays and rethrow the exception
|
||||
temp -= sizeof(size_t)*2;
|
||||
arrays->add(block_size,temp);
|
||||
throw;
|
||||
}
|
||||
|
||||
++allocations;
|
||||
return reinterpret_cast<T*>(temp);
|
||||
}
|
||||
|
||||
void deallocate_array (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
char* temp = reinterpret_cast<char*>(item);
|
||||
temp -= sizeof(size_t)*2;
|
||||
size_t block_size = reinterpret_cast<size_t*>(temp)[0];
|
||||
size_t size = reinterpret_cast<size_t*>(temp)[1];
|
||||
|
||||
deinitialize_array(item,size);
|
||||
|
||||
arrays->add(block_size,temp);
|
||||
|
||||
--allocations;
|
||||
}
|
||||
|
||||
T* allocate (
|
||||
)
|
||||
{
|
||||
T* temp;
|
||||
if (next != 0)
|
||||
{
|
||||
temp = reinterpret_cast<T*>(next);
|
||||
node* n = next->next;
|
||||
|
||||
try
|
||||
{
|
||||
// construct this new T object with placement new.
|
||||
new (static_cast<void*>(temp))T();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
next->next = n;
|
||||
throw;
|
||||
}
|
||||
|
||||
next = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
// the linked list is empty so we need to allocate some more memory
|
||||
node* block = static_cast<node*>(::operator new (sizeof(node)*chunk_size));
|
||||
|
||||
// the first part of this block can be our new object
|
||||
temp = reinterpret_cast<T*>(block);
|
||||
|
||||
try
|
||||
{
|
||||
// construct this new T object with placement new.
|
||||
new (static_cast<void*>(temp))T();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// construction of the new object threw so delete the block of memory
|
||||
::operator delete ( static_cast<void*>(block));
|
||||
throw;
|
||||
}
|
||||
|
||||
// allocate a new chunk_node
|
||||
chunk_node* chunk;
|
||||
try {chunk = new chunk_node; }
|
||||
catch (...)
|
||||
{
|
||||
temp->~T();
|
||||
::operator delete ( static_cast<void*>(block));
|
||||
throw;
|
||||
}
|
||||
|
||||
// add this block into the chunk list
|
||||
chunk->chunk = block;
|
||||
chunk->next = first_chunk;
|
||||
first_chunk = chunk;
|
||||
|
||||
|
||||
++block;
|
||||
// now add the rest of the block into the linked list of free nodes.
|
||||
for (size_t i = 0; i < chunk_size-1; ++i)
|
||||
{
|
||||
block->next = next;
|
||||
next = block;
|
||||
++block;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
++allocations;
|
||||
return temp;
|
||||
}
|
||||
|
||||
void deallocate (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
--allocations;
|
||||
item->~T();
|
||||
|
||||
// add this memory into our linked list.
|
||||
node* temp = reinterpret_cast<node*>(item);
|
||||
temp->next = next;
|
||||
next = temp;
|
||||
}
|
||||
|
||||
void swap (
|
||||
memory_manager_kernel_3& item
|
||||
)
|
||||
{
|
||||
exchange(allocations,item.allocations);
|
||||
exchange(next,item.next);
|
||||
exchange(first_chunk,item.first_chunk);
|
||||
exchange(arrays,item.arrays);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// data members
|
||||
size_t allocations;
|
||||
node* next;
|
||||
|
||||
chunk_node* first_chunk;
|
||||
bst_of_arrays* arrays;
|
||||
|
||||
|
||||
void initialize_array (
|
||||
T* array,
|
||||
size_t size
|
||||
) const
|
||||
{
|
||||
size_t i;
|
||||
try
|
||||
{
|
||||
for (i = 0; i < size; ++i)
|
||||
{
|
||||
// construct this new T object with placement new.
|
||||
new (static_cast<void*>(array+i))T();
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// Catch any exceptions thrown during the construction process
|
||||
// and then destruct any T objects that actually were successfully
|
||||
// constructed.
|
||||
for (size_t j = 0; j < i; ++j)
|
||||
{
|
||||
array[i].~T();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void deinitialize_array (
|
||||
T* array,
|
||||
size_t size
|
||||
) const
|
||||
{
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
array[i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
// don't do any initialization for the built in types
|
||||
void initialize_array(unsigned char*, size_t) {}
|
||||
void deinitialize_array(unsigned char*, size_t) {}
|
||||
void initialize_array(signed char*, size_t) {}
|
||||
void deinitialize_array(signed char*, size_t) {}
|
||||
void initialize_array(char*, size_t) {}
|
||||
void deinitialize_array(char*, size_t) {}
|
||||
void initialize_array(int*, size_t) {}
|
||||
void deinitialize_array(int*, size_t) {}
|
||||
void initialize_array(unsigned int*, size_t) {}
|
||||
void deinitialize_array(unsigned int*, size_t) {}
|
||||
void initialize_array(unsigned long*, size_t) {}
|
||||
void deinitialize_array(unsigned long*, size_t) {}
|
||||
void initialize_array(long*, size_t) {}
|
||||
void deinitialize_array(long*, size_t) {}
|
||||
void initialize_array(float*, size_t) {}
|
||||
void deinitialize_array(float*, size_t) {}
|
||||
void initialize_array(double*, size_t) {}
|
||||
void deinitialize_array(double*, size_t) {}
|
||||
void initialize_array(short*, size_t) {}
|
||||
void deinitialize_array(short*, size_t) {}
|
||||
void initialize_array(unsigned short*, size_t) {}
|
||||
void deinitialize_array(unsigned short*, size_t) {}
|
||||
|
||||
|
||||
|
||||
// restricted functions
|
||||
memory_manager_kernel_3(memory_manager_kernel_3&); // copy constructor
|
||||
memory_manager_kernel_3& operator=(memory_manager_kernel_3&); // assignment operator
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
size_t chunk_size
|
||||
>
|
||||
inline void swap (
|
||||
memory_manager_kernel_3<T,chunk_size>& a,
|
||||
memory_manager_kernel_3<T,chunk_size>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_KERNEl_3_
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_MEMORY_MANAGER_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_MEMORY_MANAGER_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../algs.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class memory_manager
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T must have a default constructor.
|
||||
|
||||
INITIAL VALUE
|
||||
get_number_of_allocations() == 0
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents some kind of memory manager or memory pool.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
typedef memory_manager<U> other;
|
||||
};
|
||||
|
||||
memory_manager(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
virtual ~memory_manager(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (get_number_of_allocations() == 0) then
|
||||
- all resources associated with *this have been released.
|
||||
- else
|
||||
- The memory still allocated will not be deleted and this
|
||||
causes a memory leak.
|
||||
!*/
|
||||
|
||||
size_t get_number_of_allocations (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the current number of outstanding allocations
|
||||
!*/
|
||||
|
||||
T* allocate (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- allocates a new object of type T and returns a pointer to it.
|
||||
- #get_number_of_allocations() == get_number_of_allocations() + 1
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If this exception is thrown then the call to allocate()
|
||||
has no effect on #*this.
|
||||
!*/
|
||||
|
||||
void deallocate (
|
||||
T* item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- item == is a pointer to memory that was obtained from a call to
|
||||
this->allocate(). (i.e. you can't deallocate a pointer you
|
||||
got from a different memory_manager instance.)
|
||||
- the memory pointed to by item hasn't already been deallocated.
|
||||
ensures
|
||||
- deallocates the object pointed to by item
|
||||
- #get_number_of_allocations() == get_number_of_allocations() - 1
|
||||
!*/
|
||||
|
||||
T* allocate_array (
|
||||
size_t size
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- allocates a new array of size objects of type T and returns a
|
||||
pointer to it.
|
||||
- #get_number_of_allocations() == get_number_of_allocations() + 1
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If this exception is thrown then the call to allocate()
|
||||
has no effect on #*this.
|
||||
!*/
|
||||
|
||||
void deallocate_array (
|
||||
T* item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- item == is a pointer to memory that was obtained from a call to
|
||||
this->allocate_array(). (i.e. you can't deallocate a pointer you
|
||||
got from a different memory_manager instance and it must be an
|
||||
array.)
|
||||
- the memory pointed to by item hasn't already been deallocated.
|
||||
ensures
|
||||
- deallocates the array pointed to by item
|
||||
- #get_number_of_allocations() == get_number_of_allocations() - 1
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
memory_manager& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
memory_manager(memory_manager&); // copy constructor
|
||||
memory_manager& operator=(memory_manager&); // assignment operator
|
||||
};
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
inline void swap (
|
||||
memory_manager<T>& a,
|
||||
memory_manager<T>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMORY_MANAGER_GLOBAl_
|
||||
#define DLIB_MEMORY_MANAGER_GLOBAl_
|
||||
|
||||
#include "memory_manager_global/memory_manager_global_kernel_1.h"
|
||||
#include "memory_manager.h"
|
||||
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename factory
|
||||
>
|
||||
class memory_manager_global
|
||||
{
|
||||
memory_manager_global() {}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//----------- kernels ---------------
|
||||
|
||||
// kernel_1
|
||||
typedef memory_manager_global_kernel_1<T,factory>
|
||||
kernel_1a;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_GLOBAl_
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMORY_MANAGER_GLOBAl_1_
|
||||
#define DLIB_MEMORY_MANAGER_GLOBAl_1_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "../memory_manager/memory_manager_kernel_abstract.h"
|
||||
#include "memory_manager_global_kernel_abstract.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
template <
|
||||
typename T,
|
||||
typename factory
|
||||
>
|
||||
class memory_manager_global_kernel_1
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
- *global_mm == get_global_memory_manager()
|
||||
|
||||
CONVENTION
|
||||
- global_mm->get_number_of_allocations() == get_number_of_allocations()
|
||||
- *global_mm == get_global_memory_manager()
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef typename factory::template return_type<T>::type mm_global_type;
|
||||
|
||||
typedef T type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
typedef memory_manager_global_kernel_1<U,factory> other;
|
||||
};
|
||||
|
||||
memory_manager_global_kernel_1(
|
||||
) :
|
||||
global_mm(factory::template get_instance<T>())
|
||||
{}
|
||||
|
||||
virtual ~memory_manager_global_kernel_1(
|
||||
) {}
|
||||
|
||||
size_t get_number_of_allocations (
|
||||
) const { return global_mm->get_number_of_allocations(); }
|
||||
|
||||
mm_global_type& get_global_memory_manager (
|
||||
) { return *global_mm; }
|
||||
|
||||
T* allocate (
|
||||
)
|
||||
{
|
||||
return global_mm->allocate();
|
||||
}
|
||||
|
||||
void deallocate (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
global_mm->deallocate(item);
|
||||
}
|
||||
|
||||
T* allocate_array (
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
return global_mm->allocate_array(size);
|
||||
}
|
||||
|
||||
void deallocate_array (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
global_mm->deallocate_array(item);
|
||||
}
|
||||
|
||||
void swap (
|
||||
memory_manager_global_kernel_1& item
|
||||
)
|
||||
{
|
||||
exchange(item.global_mm, global_mm);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
mm_global_type* global_mm;
|
||||
|
||||
|
||||
// restricted functions
|
||||
memory_manager_global_kernel_1(memory_manager_global_kernel_1&); // copy constructor
|
||||
memory_manager_global_kernel_1& operator=(memory_manager_global_kernel_1&); // assignment operator
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename factory
|
||||
>
|
||||
inline void swap (
|
||||
memory_manager_global_kernel_1<T,factory>& a,
|
||||
memory_manager_global_kernel_1<T,factory>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_GLOBAl_1_
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_MEMORY_MANAGER_GLOBAl_ABSTRACT_
|
||||
#ifdef DLIB_MEMORY_MANAGER_GLOBAl_ABSTRACT_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "../memory_manager/memory_manager_kernel_abstract.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
template <
|
||||
typename T,
|
||||
typename factory
|
||||
>
|
||||
class memory_manager_global
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T must have a default constructor.
|
||||
|
||||
REQUIREMENTS ON factory
|
||||
factory must be defined as follows:
|
||||
struct factory
|
||||
{
|
||||
template <typename U>
|
||||
struct return_type {
|
||||
typedef typename memory_manager_type<U> type;
|
||||
};
|
||||
|
||||
template <typename U>
|
||||
static typename return_type<U>::type* get_instance (
|
||||
);
|
||||
/ *!
|
||||
ensures
|
||||
- returns a pointer to an instance of a memory_manager object
|
||||
where memory_manager_type implements the interface defined
|
||||
by dlib/memory_manager/memory_manager_kernel_abstract.h
|
||||
!* /
|
||||
};
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents some kind of global memory manager or memory pool.
|
||||
It is identical to the memory_manager object except that it gets all of
|
||||
its allocations from a global instance of a memory_manager object which
|
||||
is provided by the factory object's static member get_instance().
|
||||
|
||||
THREAD SAFETY
|
||||
This object is, by itself, threadsafe. However, if you want to use this
|
||||
object in multiple threads then you must ensure that your factory is
|
||||
threadsafe. This means its factory::get_instance() method should be
|
||||
threadsafe and the memory_manager object it returns must also be threadsafe.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef typename factory::template return_type<T>::type mm_global_type;
|
||||
|
||||
typedef T type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
typedef memory_manager_global<U,factory> other;
|
||||
};
|
||||
|
||||
memory_manager_global(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
- #get_global_memory_manager() == the memory manager that was
|
||||
returned by a call to factory::get_instance<T>()
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
virtual ~memory_manager_global(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- This destructor has no effect on the global memory_manager
|
||||
get_global_memory_manager().
|
||||
!*/
|
||||
|
||||
size_t get_number_of_allocations (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns get_global_memory_manager().get_number_of_allocations()
|
||||
!*/
|
||||
|
||||
mm_global_type& get_global_memory_manager (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- returns a reference to the global memory manager instance being
|
||||
used by *this.
|
||||
!*/
|
||||
|
||||
T* allocate (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #get_number_of_allocations() == get_number_of_allocations() + 1
|
||||
- returns get_global_memory_manager().allocate()
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If this exception is thrown then the call to allocate()
|
||||
has no effect on #*this.
|
||||
!*/
|
||||
|
||||
void deallocate (
|
||||
T* item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- item == is a pointer to memory that was obtained from a call to
|
||||
the get_global_memory_manager() object's allocate() method.
|
||||
- the memory pointed to by item hasn't already been deallocated.
|
||||
ensures
|
||||
- calls get_global_memory_manager().deallocate(item)
|
||||
- #get_number_of_allocations() == get_number_of_allocations() - 1
|
||||
!*/
|
||||
|
||||
T* allocate_array (
|
||||
size_t size
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #get_number_of_allocations() == get_number_of_allocations() + 1
|
||||
- returns get_global_memory_manager().allocate_array()
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If this exception is thrown then the call to allocate_array()
|
||||
has no effect on #*this.
|
||||
!*/
|
||||
|
||||
void deallocate_array (
|
||||
T* item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- item == is a pointer to memory that was obtained from a call to
|
||||
the get_global_memory_manager() object's allocate_array() method.
|
||||
- the memory pointed to by item hasn't already been deallocated.
|
||||
ensures
|
||||
- calls get_global_memory_manager().deallocate_array(item)
|
||||
- #get_number_of_allocations() == get_number_of_allocations() - 1
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
memory_manager_global& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
memory_manager_global(memory_manager_global&); // copy constructor
|
||||
memory_manager_global& operator=(memory_manager_global&); // assignment operator
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename factory
|
||||
>
|
||||
inline void swap (
|
||||
memory_manager_global<T,factory>& a,
|
||||
memory_manager_global<T,factory>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_GLOBAl_ABSTRACT_
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMORY_MANAGER_STATELESs_
|
||||
#define DLIB_MEMORY_MANAGER_STATELESs_
|
||||
|
||||
#include "memory_manager_stateless/memory_manager_stateless_kernel_1.h"
|
||||
#include "memory_manager_stateless/memory_manager_stateless_kernel_2.h"
|
||||
#include "memory_manager.h"
|
||||
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class memory_manager_stateless
|
||||
{
|
||||
memory_manager_stateless() {}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//----------- kernels ---------------
|
||||
|
||||
// kernel_1
|
||||
typedef memory_manager_stateless_kernel_1<T>
|
||||
kernel_1a;
|
||||
|
||||
// kernel_2
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_1a>
|
||||
kernel_2_1a;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_1b>
|
||||
kernel_2_1b;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_1c>
|
||||
kernel_2_1c;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_1d>
|
||||
kernel_2_1d;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_1e>
|
||||
kernel_2_1e;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_1f>
|
||||
kernel_2_1f;
|
||||
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_2a>
|
||||
kernel_2_2a;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_2b>
|
||||
kernel_2_2b;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_2c>
|
||||
kernel_2_2c;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_2d>
|
||||
kernel_2_2d;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_2e>
|
||||
kernel_2_2e;
|
||||
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_3a>
|
||||
kernel_2_3a;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_3b>
|
||||
kernel_2_3b;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_3c>
|
||||
kernel_2_3c;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_3d>
|
||||
kernel_2_3d;
|
||||
typedef memory_manager_stateless_kernel_2<T,memory_manager<char>::kernel_3e>
|
||||
kernel_2_3e;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_STATELESs_
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMORY_MANAGER_STATELESs_1_
|
||||
#define DLIB_MEMORY_MANAGER_STATELESs_1_
|
||||
|
||||
#include "memory_manager_stateless_kernel_abstract.h"
|
||||
#include <memory>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class memory_manager_stateless_kernel_1
|
||||
{
|
||||
/*!
|
||||
this implementation just calls new and delete directly
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
const static bool is_stateless = true;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
typedef memory_manager_stateless_kernel_1<U> other;
|
||||
};
|
||||
|
||||
memory_manager_stateless_kernel_1(
|
||||
)
|
||||
{}
|
||||
|
||||
virtual ~memory_manager_stateless_kernel_1(
|
||||
) {}
|
||||
|
||||
T* allocate (
|
||||
)
|
||||
{
|
||||
return new T;
|
||||
}
|
||||
|
||||
void deallocate (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
delete item;
|
||||
}
|
||||
|
||||
T* allocate_array (
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
return new T[size];
|
||||
}
|
||||
|
||||
void deallocate_array (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
delete [] item;
|
||||
}
|
||||
|
||||
void swap (memory_manager_stateless_kernel_1&)
|
||||
{}
|
||||
|
||||
std::unique_ptr<T> extract(
|
||||
T* item
|
||||
)
|
||||
{
|
||||
return std::unique_ptr<T>(item);
|
||||
}
|
||||
|
||||
std::unique_ptr<T[]> extract_array(
|
||||
T* item
|
||||
)
|
||||
{
|
||||
return std::unique_ptr<T[]>(item);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
memory_manager_stateless_kernel_1(memory_manager_stateless_kernel_1&); // copy constructor
|
||||
memory_manager_stateless_kernel_1& operator=(memory_manager_stateless_kernel_1&); // assignment operator
|
||||
};
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
inline void swap (
|
||||
memory_manager_stateless_kernel_1<T>& a,
|
||||
memory_manager_stateless_kernel_1<T>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_STATELESs_1_
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MEMORY_MANAGER_STATELESs_2_
|
||||
#define DLIB_MEMORY_MANAGER_STATELESs_2_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "memory_manager_stateless_kernel_abstract.h"
|
||||
#include "../threads.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
class memory_manager_stateless_kernel_2
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON mem_manager
|
||||
mem_manager must be an implementation of memory_manager/memory_manager_kernel_abstract.h
|
||||
|
||||
CONVENTION
|
||||
this object has a single global instance of mem_manager
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
const static bool is_stateless = true;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
typedef memory_manager_stateless_kernel_2<U,mem_manager> other;
|
||||
};
|
||||
|
||||
memory_manager_stateless_kernel_2(
|
||||
)
|
||||
{
|
||||
// call this just to make sure the mutex is is initialized before
|
||||
// multiple threads start calling the member functions.
|
||||
global_mutex();
|
||||
}
|
||||
|
||||
virtual ~memory_manager_stateless_kernel_2(
|
||||
) {}
|
||||
|
||||
T* allocate (
|
||||
)
|
||||
{
|
||||
auto_mutex M(global_mutex());
|
||||
return global_mm().allocate();
|
||||
}
|
||||
|
||||
void deallocate (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
auto_mutex M(global_mutex());
|
||||
return global_mm().deallocate(item);
|
||||
}
|
||||
|
||||
T* allocate_array (
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
auto_mutex M(global_mutex());
|
||||
return global_mm().allocate_array(size);
|
||||
}
|
||||
|
||||
void deallocate_array (
|
||||
T* item
|
||||
)
|
||||
{
|
||||
auto_mutex M(global_mutex());
|
||||
return global_mm().deallocate_array(item);
|
||||
}
|
||||
|
||||
void swap (memory_manager_stateless_kernel_2&)
|
||||
{}
|
||||
|
||||
private:
|
||||
|
||||
static mutex& global_mutex (
|
||||
)
|
||||
{
|
||||
static mutex lock;
|
||||
return lock;
|
||||
}
|
||||
|
||||
typedef typename mem_manager::template rebind<T>::other rebound_mm_type;
|
||||
|
||||
static rebound_mm_type& global_mm (
|
||||
)
|
||||
{
|
||||
static rebound_mm_type mm;
|
||||
return mm;
|
||||
}
|
||||
|
||||
// restricted functions
|
||||
memory_manager_stateless_kernel_2(memory_manager_stateless_kernel_2&); // copy constructor
|
||||
memory_manager_stateless_kernel_2& operator=(memory_manager_stateless_kernel_2&); // assignment operator
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
inline void swap (
|
||||
memory_manager_stateless_kernel_2<T,mem_manager>& a,
|
||||
memory_manager_stateless_kernel_2<T,mem_manager>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_STATELESs_2_
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_MEMORY_MANAGER_STATELESs_ABSTRACT_
|
||||
#ifdef DLIB_MEMORY_MANAGER_STATELESs_ABSTRACT_
|
||||
|
||||
#include "../algs.h"
|
||||
#include <memory>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class memory_manager_stateless
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T must have a default constructor.
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents some kind of stateless memory manager or memory pool.
|
||||
Stateless means that all instances (instances of the same kernel implementation that is)
|
||||
of this object are identical and can be used interchangeably. Note that
|
||||
implementations are allowed to have some shared global state such as a
|
||||
global memory pool.
|
||||
|
||||
THREAD SAFETY
|
||||
This object is thread safe. You may access it from any thread at any time
|
||||
without synchronizing access.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
const static bool is_stateless = true;
|
||||
|
||||
template <typename U>
|
||||
struct rebind {
|
||||
typedef memory_manager_stateless<U> other;
|
||||
};
|
||||
|
||||
memory_manager_stateless(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
virtual ~memory_manager_stateless(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- frees any resources used by *this but has no effect on any shared global
|
||||
resources used by the implementation.
|
||||
!*/
|
||||
|
||||
T* allocate (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- allocates a new object of type T and returns a pointer to it.
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If this exception is thrown then the call to allocate()
|
||||
has no effect on #*this.
|
||||
!*/
|
||||
|
||||
void deallocate (
|
||||
T* item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- item == is a pointer to memory that was obtained from a call to
|
||||
allocate(). (i.e. The pointer you are deallocating must have
|
||||
come from the same implementation of memory_manager_stateless
|
||||
that is trying to deallocate it.)
|
||||
- the memory pointed to by item hasn't already been deallocated.
|
||||
ensures
|
||||
- deallocates the object pointed to by item
|
||||
!*/
|
||||
|
||||
T* allocate_array (
|
||||
size_t size
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- allocates a new array of size objects of type T and returns a
|
||||
pointer to it.
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor.
|
||||
If this exception is thrown then the call to allocate()
|
||||
has no effect on #*this.
|
||||
!*/
|
||||
|
||||
void deallocate_array (
|
||||
T* item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- item == is a pointer to memory that was obtained from a call to
|
||||
allocate_array(). (i.e. The pointer you are deallocating must have
|
||||
come from the same implementation of memory_manager_stateless
|
||||
that is trying to deallocate it.)
|
||||
- the memory pointed to by item hasn't already been deallocated.
|
||||
ensures
|
||||
- deallocates the array pointed to by item
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
memory_manager_stateless& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- this function has no effect on *this or item. It is just provided
|
||||
to make this object's interface more compatible with the other
|
||||
memory managers.
|
||||
!*/
|
||||
|
||||
std::unique_ptr<T> extract(
|
||||
T* item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- item == is a pointer to memory that was obtained from a call to
|
||||
allocate().
|
||||
ensures
|
||||
- returns a unique_ptr that owns item. That is, if the returned ptr is
|
||||
PTR then PTR.get() == item. Therefore, this function extracts item
|
||||
from the memory manager's internal pool. Therefore, you shouldn't
|
||||
call deallocate(item) after this.
|
||||
- Note that not all memory managers implement extract().
|
||||
!*/
|
||||
|
||||
std::unique_ptr<T[]> extract_array(
|
||||
T* item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- item == is a pointer to memory that was obtained from a call to
|
||||
allocate_array().
|
||||
ensures
|
||||
- returns a unique_ptr that owns item. That is, if the returned ptr is
|
||||
PTR then PTR.get() == item. Therefore, this function extracts item
|
||||
from the memory manager's internal pool. Therefore, you shouldn't
|
||||
call deallocate_array(item) after this.
|
||||
- Note that not all memory managers implement extract().
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
memory_manager_stateless(memory_manager_stateless&); // copy constructor
|
||||
memory_manager_stateless& operator=(memory_manager_stateless&); // assignment operator
|
||||
};
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
inline void swap (
|
||||
memory_manager_stateless<T>& a,
|
||||
memory_manager_stateless<T>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MEMORY_MANAGER_STATELESs_ABSTRACT_
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright (C) 2017 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_METApROGRAMMING_Hh_
|
||||
#define DLIB_METApROGRAMMING_Hh_
|
||||
|
||||
#include "algs.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <size_t... n>
|
||||
struct compile_time_integer_list
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
The point of this type is to, as the name suggests, hold a compile time list of integers.
|
||||
As an example, here is something simple you could do with it:
|
||||
|
||||
template <size_t... ints>
|
||||
void print_compile_time_ints (
|
||||
compile_time_integer_list<ints...>
|
||||
)
|
||||
{
|
||||
print(ints...);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
print_compile_time_ints(compile_time_integer_list<0,4,9>());
|
||||
}
|
||||
|
||||
Which just calls: print(0,4,9);
|
||||
|
||||
This is a simple example, but this kind of thing is useful in larger and
|
||||
more complex template metaprogramming constructs.
|
||||
!*/
|
||||
|
||||
template <size_t m>
|
||||
struct push_back
|
||||
{
|
||||
typedef compile_time_integer_list<n..., m> type;
|
||||
};
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <size_t max>
|
||||
struct make_compile_time_integer_range
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object makes a compile_time_integer_list containing the integers in the range [1,max] inclusive.
|
||||
For example:
|
||||
make_compile_time_integer_range<4>::type
|
||||
evaluates to:
|
||||
compile_time_integer_list<1,2,3,4>
|
||||
!*/
|
||||
|
||||
typedef typename make_compile_time_integer_range<max-1>::type::template push_back<max>::type type;
|
||||
};
|
||||
// base case
|
||||
template <> struct make_compile_time_integer_range<0> { typedef compile_time_integer_list<> type; };
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <
|
||||
typename Funct,
|
||||
typename... Args,
|
||||
typename int_<decltype(std::declval<Funct>()(std::declval<Args>()...))>::type = 0
|
||||
>
|
||||
bool call_if_valid (
|
||||
special_,
|
||||
Funct&& f, Args&&... args
|
||||
)
|
||||
{
|
||||
f(std::forward<Args>(args)...);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <
|
||||
typename Funct,
|
||||
typename... Args
|
||||
>
|
||||
bool call_if_valid (
|
||||
general_,
|
||||
Funct&& /*f*/, Args&&... /*args*/
|
||||
) { return false; }
|
||||
}
|
||||
|
||||
template <typename Funct, typename... Args>
|
||||
bool call_if_valid(Funct&& f, Args&&... args)
|
||||
/*!
|
||||
ensures
|
||||
- if f(std::forward<Args>(args)...) is a valid expression then we evaluate it and return
|
||||
true. Otherwise we do nothing and return false.
|
||||
!*/
|
||||
{
|
||||
return impl::call_if_valid(special_(), f, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_METApROGRAMMING_Hh_
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
|
||||
#ifndef DLIB_MISC_APi_
|
||||
#define DLIB_MISC_APi_
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include "misc_api/windows.h"
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#include "misc_api/posix.h"
|
||||
#endif
|
||||
|
||||
#include "misc_api/misc_api_shared.h"
|
||||
|
||||
#endif // DLIB_MISC_APi_
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MISC_API_KERNEl_1_
|
||||
#define DLIB_MISC_API_KERNEl_1_
|
||||
|
||||
#ifdef DLIB_ISO_CPP_ONLY
|
||||
#error "DLIB_ISO_CPP_ONLY is defined so you can't use this OS dependent code. Turn DLIB_ISO_CPP_ONLY off if you want to use it."
|
||||
#endif
|
||||
|
||||
|
||||
#include "misc_api_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include <string>
|
||||
#include "../uintn.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void sleep (
|
||||
unsigned long milliseconds
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
std::string get_current_dir (
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class set_current_dir_error : public error
|
||||
{
|
||||
public:
|
||||
set_current_dir_error(
|
||||
const std::string& a
|
||||
): error(a) {}
|
||||
};
|
||||
|
||||
void set_current_dir (
|
||||
const std::string& new_dir
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class timestamper
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
- last_time == 0
|
||||
- offset == 0
|
||||
- dword_max == 2^32
|
||||
|
||||
CONVENTION
|
||||
- last_time == the time returned by GetTickCount() the last time we
|
||||
called it.
|
||||
- offset == the number of microseconds we should add to the result of
|
||||
GetTickCount() so that it is correct.
|
||||
- dword_max == 2^32.
|
||||
This is the number of values representable by a DWORD.
|
||||
!*/
|
||||
|
||||
mutable unsigned long last_time;
|
||||
mutable uint64 offset;
|
||||
mutable uint64 dword_max;
|
||||
|
||||
public:
|
||||
timestamper(
|
||||
) :
|
||||
last_time(0),
|
||||
offset(0)
|
||||
{
|
||||
dword_max = 0xFFFFFFFF;
|
||||
++dword_max;
|
||||
}
|
||||
|
||||
uint64 get_timestamp (
|
||||
) const;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class dir_create_error : public error
|
||||
{
|
||||
public:
|
||||
dir_create_error(
|
||||
const std::string& dir_name
|
||||
) :
|
||||
error(EDIR_CREATE,"Error creating directory '" + dir_name + "'."),
|
||||
name(dir_name)
|
||||
{}
|
||||
|
||||
~dir_create_error() throw() {}
|
||||
const std::string name;
|
||||
};
|
||||
|
||||
void create_directory (
|
||||
const std::string& dir
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#ifdef NO_MAKEFILE
|
||||
#include "misc_api_kernel_1.cpp"
|
||||
#endif
|
||||
|
||||
#endif // DLIB_MISC_API_KERNEl_1_
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MISC_API_KERNEl_2_
|
||||
#define DLIB_MISC_API_KERNEl_2_
|
||||
|
||||
#ifdef DLIB_ISO_CPP_ONLY
|
||||
#error "DLIB_ISO_CPP_ONLY is defined so you can't use this OS dependent code. Turn DLIB_ISO_CPP_ONLY off if you want to use it."
|
||||
#endif
|
||||
|
||||
|
||||
#include "misc_api_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include <string>
|
||||
#include "../uintn.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void sleep (
|
||||
unsigned long milliseconds
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
std::string get_current_dir (
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class set_current_dir_error : public error
|
||||
{
|
||||
public:
|
||||
set_current_dir_error(
|
||||
const std::string& a
|
||||
): error(a) {}
|
||||
};
|
||||
|
||||
void set_current_dir (
|
||||
const std::string& new_dir
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class timestamper
|
||||
{
|
||||
public:
|
||||
uint64 get_timestamp (
|
||||
) const;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class dir_create_error : public error
|
||||
{
|
||||
public:
|
||||
dir_create_error(
|
||||
const std::string& dir_name
|
||||
) :
|
||||
error(EDIR_CREATE,"Error creating directory '" + dir_name + "'."),
|
||||
name(dir_name)
|
||||
{}
|
||||
const std::string& name;
|
||||
};
|
||||
|
||||
|
||||
void create_directory (
|
||||
const std::string& dir
|
||||
);
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#ifdef NO_MAKEFILE
|
||||
#include "misc_api_kernel_2.cpp"
|
||||
#endif
|
||||
|
||||
#endif // DLIB_MISC_API_KERNEl_2_
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_MISC_API_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_MISC_API_KERNEl_ABSTRACT_
|
||||
|
||||
#include <string>
|
||||
#include "../uintn.h"
|
||||
#include "../algs.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
GENERAL COMMENTS
|
||||
This file just contains miscellaneous api functions
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
void sleep (
|
||||
unsigned long milliseconds
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- causes the calling thread to sleep for the given number of
|
||||
milliseconds.
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
std::string get_current_dir (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (no errors occur) then
|
||||
- returns the path to the current working directory
|
||||
- else
|
||||
- returns ""
|
||||
throws
|
||||
- std::bad_alloc
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class set_current_dir_error : public error;
|
||||
|
||||
void set_current_dir (
|
||||
const std::string& new_dir
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- sets the current working directory to new_dir
|
||||
throws
|
||||
- std::bad_alloc
|
||||
- set_current_dir_error
|
||||
This exception is thrown if there is an error when attempting
|
||||
to change the current working directory.
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class locally_change_current_dir : noncopyable
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object is a RAII tool for safely switching the current directory
|
||||
to a new directory and then automatically switching back to the original
|
||||
directory upon this object's destruction.
|
||||
!*/
|
||||
public:
|
||||
explicit locally_change_current_dir (
|
||||
const std::string& new_dir
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- calls set_current_dir(new_dir)
|
||||
- #old_dir() == The value of get_current_dir() prior to switching to new_dir.
|
||||
!*/
|
||||
|
||||
const std::string& old_dir (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the directory we switch back to once this object is destructed.
|
||||
!*/
|
||||
|
||||
~locally_change_current_dir(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (revert() hasn't already been called) then
|
||||
- calls set_current_dir(old_dir())
|
||||
!*/
|
||||
|
||||
void revert (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (revert() hasn't already been called) then
|
||||
- calls set_current_dir(old_dir())
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class dir_create_error : public error {
|
||||
public:
|
||||
const std::string name
|
||||
};
|
||||
|
||||
void create_directory (
|
||||
const std::string& dir
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (dir does not already exist) then
|
||||
- creates the given directory.
|
||||
- else
|
||||
- the call to create_directory() has no effect.
|
||||
throws
|
||||
- dir_create_error
|
||||
This exception is thrown if we were unable to create the requested
|
||||
directory and it didn't already exist. The type member of the exception
|
||||
will bet set to EDIR_CREATE and the name member will be set to dir.
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class timestamper
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This object represents a timer that is capable of returning
|
||||
timestamps.
|
||||
|
||||
Note that the time is measured in microseconds but you are not
|
||||
guaranteed to have that level of resolution. The actual resolution
|
||||
is implementation dependent.
|
||||
!*/
|
||||
|
||||
public:
|
||||
uint64 get_timestamp (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns a timestamp that measures the time in microseconds since an
|
||||
arbitrary point in the past. Note that this arbitrary point remains
|
||||
the same between all calls to get_timestamp().
|
||||
!*/
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MISC_API_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2014 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MISC_API_ShARED_Hh_
|
||||
#define DLIB_MISC_API_ShARED_Hh_
|
||||
|
||||
#include <string>
|
||||
#include "../noncopyable.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class locally_change_current_dir : noncopyable
|
||||
{
|
||||
public:
|
||||
explicit locally_change_current_dir (
|
||||
const std::string& new_dir
|
||||
)
|
||||
{
|
||||
reverted = false;
|
||||
_old_dir = get_current_dir();
|
||||
set_current_dir(new_dir);
|
||||
}
|
||||
|
||||
~locally_change_current_dir()
|
||||
{
|
||||
revert();
|
||||
}
|
||||
|
||||
const std::string& old_dir (
|
||||
) const
|
||||
{
|
||||
return _old_dir;
|
||||
}
|
||||
|
||||
void revert (
|
||||
)
|
||||
{
|
||||
if (!reverted)
|
||||
{
|
||||
set_current_dir(_old_dir);
|
||||
reverted = true;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool reverted;
|
||||
std::string _old_dir;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_MISC_API_ShARED_Hh_
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MISC_API_KERNEl_1_
|
||||
#include "misc_api_kernel_2.h"
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_MISC_API_KERNEl_2_
|
||||
#include "misc_api_kernel_1.h"
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Contributed by Dave Abrahams
|
||||
// See http://www.boost.org/libs/utility for documentation.
|
||||
|
||||
#ifndef DLIB_BOOST_NONCOPYABLE_HPP_INCLUDED
|
||||
#define DLIB_BOOST_NONCOPYABLE_HPP_INCLUDED
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
class noncopyable
|
||||
{
|
||||
/*!
|
||||
This class makes it easier to declare a class as non-copyable.
|
||||
If you want to make an object that can't be copied just inherit
|
||||
from this object.
|
||||
!*/
|
||||
|
||||
protected:
|
||||
noncopyable() = default;
|
||||
~noncopyable() = default;
|
||||
private: // emphasize the following members are private
|
||||
noncopyable(const noncopyable&);
|
||||
const noncopyable& operator=(const noncopyable&);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_BOOST_NONCOPYABLE_HPP_INCLUDED
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
//Copyright (C) 2013 Steve Taylor (steve98654@gmail.com), Davis E. King
|
||||
//License: Boost Software License. See LICENSE.txt for full license.
|
||||
#ifndef DLIB_NUMERIC_CONSTANTs_H_
|
||||
#define DLIB_NUMERIC_CONSTANTs_H_
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// pi -- Pi
|
||||
const double pi = 3.1415926535897932385;
|
||||
|
||||
// e -- Euler's Constant
|
||||
const double e = 2.7182818284590452354;
|
||||
|
||||
// sqrt_2 -- The square root of 2
|
||||
const double sqrt_2 = 1.4142135623730950488;
|
||||
|
||||
// sqrt_3 -- The square root of 3
|
||||
const double sqrt_3 = 1.7320508075688772935;
|
||||
|
||||
// log10_2 -- The logarithm base 10 of two
|
||||
const double log10_2 = 0.30102999566398119521;
|
||||
|
||||
// light_spd -- The speed of light in vacuum in meters per second
|
||||
const double light_spd = 2.99792458e8;
|
||||
|
||||
// newton_G -- Newton's gravitational constant (in metric units of m^3/(kg*s^2))
|
||||
const double newton_G = 6.67384e-11;
|
||||
|
||||
// planck_cst -- Planck's constant (in units of Joules * seconds)
|
||||
const double planck_cst = 6.62606957e-34;
|
||||
|
||||
// golden_ratio -- The Golden Ratio
|
||||
const double golden_ratio = 1.6180339887498948482;
|
||||
|
||||
// euler_gamma -- The Euler Mascheroni Constant
|
||||
const double euler_gamma = 0.5772156649015328606065;
|
||||
|
||||
// catalan -- Catalan's Constant
|
||||
const double catalan = 0.91596559417721901505;
|
||||
|
||||
// glaisher -- Glaisher Kinkelin constant
|
||||
const double glaisher = 1.2824271291006226369;
|
||||
|
||||
// khinchin -- Khinchin's constant
|
||||
const double khinchin = 2.6854520010653064453;
|
||||
|
||||
// apery -- Apery's constant
|
||||
const double apery = 1.2020569031595942854;
|
||||
}
|
||||
|
||||
#endif //DLIB_NUMERIC_CONSTANTs_H_
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright (C) 2013 Steve Taylor (steve98654@gmail.com)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_INTEGRATE_FUNCTION_ADAPT_SIMPSON_HEADER
|
||||
#define DLIB_INTEGRATE_FUNCTION_ADAPT_SIMPSON_HEADER
|
||||
|
||||
#include "numerical_integration/integrate_function_adapt_simpson.h"
|
||||
|
||||
#endif // DLIB_INTEGRATE_FUNCTION_ADAPT_SIMPSON_HEADER
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright (C) 2013 Steve Taylor (steve98654@gmail.com)
|
||||
// License: Boost Software License See LICENSE.txt for full license
|
||||
#ifndef DLIB_INTEGRATE_FUNCTION_ADAPT_SIMPSONh_
|
||||
#define DLIB_INTEGRATE_FUNCTION_ADAPT_SIMPSONh_
|
||||
|
||||
#include "integrate_function_adapt_simpson_abstract.h"
|
||||
#include "../assert.h"
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
template <typename T, typename funct>
|
||||
T impl_adapt_simp_stop(const funct& f, T a, T b, T fa, T fm, T fb, T is, int cnt)
|
||||
{
|
||||
const int maxint = 500;
|
||||
|
||||
T m = (a + b)/2.0;
|
||||
T h = (b - a)/4.0;
|
||||
T fml = f(a + h);
|
||||
T fmr = f(b - h);
|
||||
T i1 = h/1.5*(fa+4.0*fm+fb);
|
||||
T i2 = h/3.0*(fa+4.0*(fml+fmr)+2.0*fm+fb);
|
||||
i1 = (16.0*i2 - i1)/15.0;
|
||||
T Q = 0;
|
||||
|
||||
if ((std::abs(i1-i2) <= std::abs(is)) || (m <= a) || (b <= m))
|
||||
{
|
||||
Q = i1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(cnt < maxint)
|
||||
{
|
||||
cnt = cnt + 1;
|
||||
|
||||
Q = impl_adapt_simp_stop(f,a,m,fa,fml,fm,is,cnt)
|
||||
+ impl_adapt_simp_stop(f,m,b,fm,fmr,fb,is,cnt);
|
||||
}
|
||||
}
|
||||
|
||||
return Q;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T, typename funct>
|
||||
T integrate_function_adapt_simp(
|
||||
const funct& f,
|
||||
T a,
|
||||
T b,
|
||||
T tol = 1e-10
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_ASSERT(b > a && tol > 0,
|
||||
"\t T integrate_function_adapt_simp()"
|
||||
<< "\n\t Invalid arguments were given to this function."
|
||||
<< "\n\t a: " << a
|
||||
<< "\n\t b: " << b
|
||||
<< "\n\t tol: " << tol
|
||||
);
|
||||
|
||||
T eps = std::numeric_limits<T>::epsilon();
|
||||
if(tol < eps)
|
||||
{
|
||||
tol = eps;
|
||||
}
|
||||
|
||||
const T ba = b-a;
|
||||
const T fa = f(a);
|
||||
const T fb = f(b);
|
||||
const T fm = f((a+b)/2);
|
||||
|
||||
T is = ba/8*(fa+fb+fm+ f(a + 0.9501*ba) + f(a + 0.2311*ba) + f(a + 0.6068*ba)
|
||||
+ f(a + 0.4860*ba) + f(a + 0.8913*ba));
|
||||
|
||||
if(is == 0)
|
||||
{
|
||||
is = b-a;
|
||||
}
|
||||
|
||||
is = is*tol;
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
return impl_adapt_simp_stop(f, a, b, fa, fm, fb, is, cnt);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
#endif // DLIB_INTEGRATE_FUNCTION_ADAPT_SIMPSONh_
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2013 Steve Taylor (steve98654@gmail.com)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_INTEGRATE_FUNCTION_ADAPT_SIMPSON_ABSTRACTh_
|
||||
#ifdef DLIB_INTEGRATE_FUNCTION_ADAPT_SIMPSON_ABSTRACTh_
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <typename T, typename funct>
|
||||
T integrate_function_adapt_simp(
|
||||
const funct& f,
|
||||
T a,
|
||||
T b,
|
||||
T tol = 1e-10
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- b > a
|
||||
- tol > 0
|
||||
- T should be either float, double, or long double
|
||||
- The expression f(a) should be a valid expression that evaluates to a T.
|
||||
I.e. f() should be a real valued function of a single variable.
|
||||
ensures
|
||||
- returns an approximation of the integral of f over the domain [a,b] using the
|
||||
adaptive Simpson method outlined in Gander, W. and W. Gautshi, "Adaptive
|
||||
Quadrature -- Revisited" BIT, Vol. 40, (2000), pp.84-101
|
||||
- tol is a tolerance parameter that determines the overall accuracy of
|
||||
approximated integral. We suggest a default value of 1e-10 for tol.
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_INTEGRATE_FUNCTION_ADAPT_SIMPSON_ABSTRACTh_
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include "dlib_include_path_tutorial.txt"
|
||||
10
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/pipe.h
vendored
Normal file
10
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/pipe.h
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_PIPe_
|
||||
#define DLIB_PIPe_
|
||||
|
||||
#include "pipe/pipe_kernel_1.h"
|
||||
|
||||
|
||||
#endif // DLIB_PIPe_
|
||||
|
||||
@@ -0,0 +1,756 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_PIPE_KERNEl_1_
|
||||
#define DLIB_PIPE_KERNEl_1_
|
||||
|
||||
#include "../algs.h"
|
||||
#include "../threads.h"
|
||||
#include "pipe_kernel_abstract.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class pipe
|
||||
{
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
- pipe_size == 0
|
||||
- pipe_max_size == defined by constructor
|
||||
- enabled == true
|
||||
- data == a pointer to an array of ((pipe_max_size>0)?pipe_max_size:1) T objects.
|
||||
- dequeue_waiters == 0
|
||||
- enqueue_waiters == 0
|
||||
- first == 1
|
||||
- last == 1
|
||||
- unblock_sig_waiters == 0
|
||||
|
||||
CONVENTION
|
||||
- size() == pipe_size
|
||||
- max_size() == pipe_max_size
|
||||
- is_enabled() == enabled
|
||||
|
||||
- m == the mutex used to lock access to all the members of this class
|
||||
|
||||
- dequeue_waiters == the number of threads blocked on calls to dequeue()
|
||||
- enqueue_waiters == the number of threads blocked on calls to enqueue() and
|
||||
wait_until_empty()
|
||||
- unblock_sig_waiters == the number of threads blocked on calls to
|
||||
wait_for_num_blocked_dequeues() and the destructor. (i.e. the number of
|
||||
blocking calls to unblock_sig.wait())
|
||||
|
||||
- dequeue_sig == the signaler that threads blocked on calls to dequeue() wait on
|
||||
- enqueue_sig == the signaler that threads blocked on calls to enqueue()
|
||||
or wait_until_empty() wait on.
|
||||
- unblock_sig == the signaler that is signaled when a thread stops blocking on a call
|
||||
to enqueue() or dequeue(). It is also signaled when a dequeue that will probably
|
||||
block is called. The destructor and wait_for_num_blocked_dequeues are the only
|
||||
things that will wait on this signaler.
|
||||
|
||||
- if (pipe_size > 0) then
|
||||
- data[first] == the next item to dequeue
|
||||
- data[last] == the item most recently added via enqueue, so the last to dequeue.
|
||||
- else if (pipe_max_size == 0)
|
||||
- if (first == 0 && last == 0) then
|
||||
- data[0] == the next item to dequeue
|
||||
- else if (first == 0 && last == 1) then
|
||||
- data[0] has been taken out already by a dequeue
|
||||
!*/
|
||||
|
||||
public:
|
||||
// this is here for backwards compatibility with older versions of dlib.
|
||||
typedef pipe kernel_1a;
|
||||
|
||||
typedef T type;
|
||||
|
||||
explicit pipe (
|
||||
size_t maximum_size
|
||||
);
|
||||
|
||||
virtual ~pipe (
|
||||
);
|
||||
|
||||
void empty (
|
||||
);
|
||||
|
||||
void wait_until_empty (
|
||||
) const;
|
||||
|
||||
void wait_for_num_blocked_dequeues (
|
||||
unsigned long num
|
||||
)const;
|
||||
|
||||
void enable (
|
||||
);
|
||||
|
||||
void disable (
|
||||
);
|
||||
|
||||
bool is_enqueue_enabled (
|
||||
) const;
|
||||
|
||||
void disable_enqueue (
|
||||
);
|
||||
|
||||
void enable_enqueue (
|
||||
);
|
||||
|
||||
bool is_dequeue_enabled (
|
||||
) const;
|
||||
|
||||
void disable_dequeue (
|
||||
);
|
||||
|
||||
void enable_dequeue (
|
||||
);
|
||||
|
||||
bool is_enabled (
|
||||
) const;
|
||||
|
||||
size_t max_size (
|
||||
) const;
|
||||
|
||||
size_t size (
|
||||
) const;
|
||||
|
||||
bool enqueue (
|
||||
T& item
|
||||
);
|
||||
|
||||
bool enqueue (
|
||||
T&& item
|
||||
) { return enqueue(item); }
|
||||
|
||||
bool dequeue (
|
||||
T& item
|
||||
);
|
||||
|
||||
bool enqueue_or_timeout (
|
||||
T& item,
|
||||
unsigned long timeout
|
||||
);
|
||||
|
||||
bool enqueue_or_timeout (
|
||||
T&& item,
|
||||
unsigned long timeout
|
||||
) { return enqueue_or_timeout(item,timeout); }
|
||||
|
||||
bool dequeue_or_timeout (
|
||||
T& item,
|
||||
unsigned long timeout
|
||||
);
|
||||
|
||||
private:
|
||||
|
||||
size_t pipe_size;
|
||||
const size_t pipe_max_size;
|
||||
bool enabled;
|
||||
|
||||
T* const data;
|
||||
|
||||
size_t first;
|
||||
size_t last;
|
||||
|
||||
mutex m;
|
||||
signaler dequeue_sig;
|
||||
signaler enqueue_sig;
|
||||
signaler unblock_sig;
|
||||
|
||||
unsigned long dequeue_waiters;
|
||||
mutable unsigned long enqueue_waiters;
|
||||
mutable unsigned long unblock_sig_waiters;
|
||||
bool enqueue_enabled;
|
||||
bool dequeue_enabled;
|
||||
|
||||
// restricted functions
|
||||
pipe(const pipe&); // copy constructor
|
||||
pipe& operator=(const pipe&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
pipe<T>::
|
||||
pipe (
|
||||
size_t maximum_size
|
||||
) :
|
||||
pipe_size(0),
|
||||
pipe_max_size(maximum_size),
|
||||
enabled(true),
|
||||
data(new T[(maximum_size>0) ? maximum_size : 1]),
|
||||
first(1),
|
||||
last(1),
|
||||
dequeue_sig(m),
|
||||
enqueue_sig(m),
|
||||
unblock_sig(m),
|
||||
dequeue_waiters(0),
|
||||
enqueue_waiters(0),
|
||||
unblock_sig_waiters(0),
|
||||
enqueue_enabled(true),
|
||||
dequeue_enabled(true)
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
pipe<T>::
|
||||
~pipe (
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
++unblock_sig_waiters;
|
||||
|
||||
// first make sure no one is blocked on any calls to enqueue() or dequeue()
|
||||
enabled = false;
|
||||
dequeue_sig.broadcast();
|
||||
enqueue_sig.broadcast();
|
||||
unblock_sig.broadcast();
|
||||
|
||||
// wait for all threads to unblock
|
||||
while (dequeue_waiters > 0 || enqueue_waiters > 0 || unblock_sig_waiters > 1)
|
||||
unblock_sig.wait();
|
||||
|
||||
delete [] data;
|
||||
--unblock_sig_waiters;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void pipe<T>::
|
||||
empty (
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
pipe_size = 0;
|
||||
|
||||
// let any calls to enqueue() know that the pipe is now empty
|
||||
if (enqueue_waiters > 0)
|
||||
enqueue_sig.broadcast();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void pipe<T>::
|
||||
wait_until_empty (
|
||||
) const
|
||||
{
|
||||
auto_mutex M(m);
|
||||
// this function is sort of like a call to enqueue so treat it like that
|
||||
++enqueue_waiters;
|
||||
|
||||
while (pipe_size > 0 && enabled && dequeue_enabled )
|
||||
enqueue_sig.wait();
|
||||
|
||||
// let the destructor know we are ending if it is blocked waiting
|
||||
if (enabled == false)
|
||||
unblock_sig.broadcast();
|
||||
|
||||
--enqueue_waiters;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void pipe<T>::
|
||||
enable (
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void pipe<T>::
|
||||
disable (
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
enabled = false;
|
||||
dequeue_sig.broadcast();
|
||||
enqueue_sig.broadcast();
|
||||
unblock_sig.broadcast();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
bool pipe<T>::
|
||||
is_enabled (
|
||||
) const
|
||||
{
|
||||
auto_mutex M(m);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
size_t pipe<T>::
|
||||
max_size (
|
||||
) const
|
||||
{
|
||||
auto_mutex M(m);
|
||||
return pipe_max_size;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
size_t pipe<T>::
|
||||
size (
|
||||
) const
|
||||
{
|
||||
auto_mutex M(m);
|
||||
return pipe_size;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
bool pipe<T>::
|
||||
enqueue (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
++enqueue_waiters;
|
||||
|
||||
// wait until there is room or we are disabled
|
||||
while (pipe_size == pipe_max_size && enabled && enqueue_enabled &&
|
||||
!(pipe_max_size == 0 && first == 1) )
|
||||
enqueue_sig.wait();
|
||||
|
||||
if (enabled == false || enqueue_enabled == false)
|
||||
{
|
||||
--enqueue_waiters;
|
||||
// let the destructor know we are unblocking
|
||||
unblock_sig.broadcast();
|
||||
return false;
|
||||
}
|
||||
|
||||
// set the appropriate values for first and last
|
||||
if (pipe_size == 0)
|
||||
{
|
||||
first = 0;
|
||||
last = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
last = (last+1)%pipe_max_size;
|
||||
}
|
||||
|
||||
|
||||
exchange(item,data[last]);
|
||||
|
||||
// wake up a call to dequeue() if there are any currently blocked
|
||||
if (dequeue_waiters > 0)
|
||||
dequeue_sig.signal();
|
||||
|
||||
if (pipe_max_size > 0)
|
||||
{
|
||||
++pipe_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// wait for a dequeue to take the item out
|
||||
while (last == 0 && enabled && enqueue_enabled)
|
||||
enqueue_sig.wait();
|
||||
|
||||
if (last == 0 && (enabled == false || enqueue_enabled == false))
|
||||
{
|
||||
last = 1;
|
||||
first = 1;
|
||||
|
||||
// no one dequeued this object to put it back into item
|
||||
exchange(item,data[0]);
|
||||
|
||||
--enqueue_waiters;
|
||||
// let the destructor know we are unblocking
|
||||
if (unblock_sig_waiters > 0)
|
||||
unblock_sig.broadcast();
|
||||
return false;
|
||||
}
|
||||
|
||||
last = 1;
|
||||
first = 1;
|
||||
|
||||
// tell any waiting calls to enqueue() that one of them can proceed
|
||||
if (enqueue_waiters > 1)
|
||||
enqueue_sig.broadcast();
|
||||
|
||||
// let the destructor know we are unblocking
|
||||
if (enabled == false && unblock_sig_waiters > 0)
|
||||
unblock_sig.broadcast();
|
||||
}
|
||||
|
||||
--enqueue_waiters;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
bool pipe<T>::
|
||||
dequeue (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
++dequeue_waiters;
|
||||
|
||||
if (pipe_size == 0)
|
||||
{
|
||||
// notify wait_for_num_blocked_dequeues()
|
||||
if (unblock_sig_waiters > 0)
|
||||
unblock_sig.broadcast();
|
||||
|
||||
// notify any blocked enqueue_or_timeout() calls
|
||||
if (enqueue_waiters > 0)
|
||||
enqueue_sig.broadcast();
|
||||
}
|
||||
|
||||
// wait until there is something in the pipe or we are disabled
|
||||
while (pipe_size == 0 && enabled && dequeue_enabled &&
|
||||
!(pipe_max_size == 0 && first == 0 && last == 0) )
|
||||
dequeue_sig.wait();
|
||||
|
||||
if (enabled == false || dequeue_enabled == false)
|
||||
{
|
||||
--dequeue_waiters;
|
||||
// let the destructor know we are unblocking
|
||||
unblock_sig.broadcast();
|
||||
return false;
|
||||
}
|
||||
|
||||
exchange(item,data[first]);
|
||||
|
||||
if (pipe_max_size > 0)
|
||||
{
|
||||
// set the appropriate values for first
|
||||
first = (first+1)%pipe_max_size;
|
||||
|
||||
--pipe_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// let the enqueue waiting on us know that we took the
|
||||
// item out already.
|
||||
last = 1;
|
||||
}
|
||||
|
||||
// wake up a call to enqueue() if there are any currently blocked
|
||||
if (enqueue_waiters > 0)
|
||||
enqueue_sig.broadcast();
|
||||
|
||||
--dequeue_waiters;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
bool pipe<T>::
|
||||
enqueue_or_timeout (
|
||||
T& item,
|
||||
unsigned long timeout
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
++enqueue_waiters;
|
||||
|
||||
// wait until there is room or we are disabled or
|
||||
// we run out of time.
|
||||
bool timed_out = false;
|
||||
while (pipe_size == pipe_max_size && enabled && enqueue_enabled &&
|
||||
!(pipe_max_size == 0 && dequeue_waiters > 0 && first == 1) )
|
||||
{
|
||||
if (timeout == 0 || enqueue_sig.wait_or_timeout(timeout) == false)
|
||||
{
|
||||
timed_out = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (enabled == false || timed_out || enqueue_enabled == false)
|
||||
{
|
||||
--enqueue_waiters;
|
||||
// let the destructor know we are unblocking
|
||||
unblock_sig.broadcast();
|
||||
return false;
|
||||
}
|
||||
|
||||
// set the appropriate values for first and last
|
||||
if (pipe_size == 0)
|
||||
{
|
||||
first = 0;
|
||||
last = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
last = (last+1)%pipe_max_size;
|
||||
}
|
||||
|
||||
|
||||
exchange(item,data[last]);
|
||||
|
||||
// wake up a call to dequeue() if there are any currently blocked
|
||||
if (dequeue_waiters > 0)
|
||||
dequeue_sig.signal();
|
||||
|
||||
if (pipe_max_size > 0)
|
||||
{
|
||||
++pipe_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// wait for a dequeue to take the item out
|
||||
while (last == 0 && enabled && enqueue_enabled)
|
||||
enqueue_sig.wait();
|
||||
|
||||
if (last == 0 && (enabled == false || enqueue_enabled == false))
|
||||
{
|
||||
last = 1;
|
||||
first = 1;
|
||||
|
||||
// no one dequeued this object to put it back into item
|
||||
exchange(item,data[0]);
|
||||
|
||||
--enqueue_waiters;
|
||||
// let the destructor know we are unblocking
|
||||
if (unblock_sig_waiters > 0)
|
||||
unblock_sig.broadcast();
|
||||
return false;
|
||||
}
|
||||
|
||||
last = 1;
|
||||
first = 1;
|
||||
|
||||
// tell any waiting calls to enqueue() that one of them can proceed
|
||||
if (enqueue_waiters > 1)
|
||||
enqueue_sig.broadcast();
|
||||
|
||||
// let the destructor know we are unblocking
|
||||
if (enabled == false && unblock_sig_waiters > 0)
|
||||
unblock_sig.broadcast();
|
||||
}
|
||||
|
||||
--enqueue_waiters;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
bool pipe<T>::
|
||||
dequeue_or_timeout (
|
||||
T& item,
|
||||
unsigned long timeout
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
++dequeue_waiters;
|
||||
|
||||
if (pipe_size == 0)
|
||||
{
|
||||
// notify wait_for_num_blocked_dequeues()
|
||||
if (unblock_sig_waiters > 0)
|
||||
unblock_sig.broadcast();
|
||||
|
||||
// notify any blocked enqueue_or_timeout() calls
|
||||
if (enqueue_waiters > 0)
|
||||
enqueue_sig.broadcast();
|
||||
}
|
||||
|
||||
bool timed_out = false;
|
||||
// wait until there is something in the pipe or we are disabled or we timeout.
|
||||
while (pipe_size == 0 && enabled && dequeue_enabled &&
|
||||
!(pipe_max_size == 0 && first == 0 && last == 0) )
|
||||
{
|
||||
if (timeout == 0 || dequeue_sig.wait_or_timeout(timeout) == false)
|
||||
{
|
||||
timed_out = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (enabled == false || timed_out || dequeue_enabled == false)
|
||||
{
|
||||
--dequeue_waiters;
|
||||
// let the destructor know we are unblocking
|
||||
unblock_sig.broadcast();
|
||||
return false;
|
||||
}
|
||||
|
||||
exchange(item,data[first]);
|
||||
|
||||
if (pipe_max_size > 0)
|
||||
{
|
||||
// set the appropriate values for first
|
||||
first = (first+1)%pipe_max_size;
|
||||
|
||||
--pipe_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// let the enqueue waiting on us know that we took the
|
||||
// item out already.
|
||||
last = 1;
|
||||
}
|
||||
|
||||
// wake up a call to enqueue() if there are any currently blocked
|
||||
if (enqueue_waiters > 0)
|
||||
enqueue_sig.broadcast();
|
||||
|
||||
--dequeue_waiters;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void pipe<T>::
|
||||
wait_for_num_blocked_dequeues (
|
||||
unsigned long num
|
||||
)const
|
||||
{
|
||||
auto_mutex M(m);
|
||||
++unblock_sig_waiters;
|
||||
|
||||
while ( (dequeue_waiters < num || pipe_size != 0) && enabled && dequeue_enabled)
|
||||
unblock_sig.wait();
|
||||
|
||||
// let the destructor know we are ending if it is blocked waiting
|
||||
if (enabled == false)
|
||||
unblock_sig.broadcast();
|
||||
|
||||
--unblock_sig_waiters;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
bool pipe<T>::
|
||||
is_enqueue_enabled (
|
||||
) const
|
||||
{
|
||||
auto_mutex M(m);
|
||||
return enqueue_enabled;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void pipe<T>::
|
||||
disable_enqueue (
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
enqueue_enabled = false;
|
||||
enqueue_sig.broadcast();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void pipe<T>::
|
||||
enable_enqueue (
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
enqueue_enabled = true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
bool pipe<T>::
|
||||
is_dequeue_enabled (
|
||||
) const
|
||||
{
|
||||
auto_mutex M(m);
|
||||
return dequeue_enabled;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void pipe<T>::
|
||||
disable_dequeue (
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
dequeue_enabled = false;
|
||||
dequeue_sig.broadcast();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
void pipe<T>::
|
||||
enable_dequeue (
|
||||
)
|
||||
{
|
||||
auto_mutex M(m);
|
||||
dequeue_enabled = true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_PIPE_KERNEl_1_
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_PIPE_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_PIPE_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../threads.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class pipe
|
||||
{
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T must be swappable by a global swap()
|
||||
T must have a default constructor
|
||||
|
||||
INITIAL VALUE
|
||||
size() == 0
|
||||
is_enabled() == true
|
||||
is_enqueue_enabled() == true
|
||||
is_dequeue_enabled() == true
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This is a first in first out queue with a fixed maximum size containing
|
||||
items of type T. It is suitable for passing objects between threads.
|
||||
|
||||
THREAD SAFETY
|
||||
All methods of this class are thread safe. You may call them from any
|
||||
thread and any number of threads my call them at once.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
|
||||
explicit pipe (
|
||||
size_t maximum_size
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
- #max_size() == maximum_size
|
||||
throws
|
||||
- std::bad_alloc
|
||||
- dlib::thread_error
|
||||
!*/
|
||||
|
||||
virtual ~pipe (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- any resources associated with *this have been released
|
||||
- disables (i.e. sets is_enabled() == false) this object so that
|
||||
all calls currently blocking on it will return immediately.
|
||||
!*/
|
||||
|
||||
void enable (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #is_enabled() == true
|
||||
!*/
|
||||
|
||||
void disable (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #is_enabled() == false
|
||||
- causes all current and future calls to enqueue(), dequeue(),
|
||||
enqueue_or_timeout() and dequeue_or_timeout() to not block but
|
||||
to return false immediately until enable() is called.
|
||||
- causes all current and future calls to wait_until_empty() and
|
||||
wait_for_num_blocked_dequeues() to not block but return
|
||||
immediately until enable() is called.
|
||||
!*/
|
||||
|
||||
bool is_enabled (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns true if this pipe is currently enabled, false otherwise.
|
||||
!*/
|
||||
|
||||
void empty (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #size() == 0
|
||||
!*/
|
||||
|
||||
void wait_until_empty (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- blocks until one of the following is the case:
|
||||
- size() == 0
|
||||
- is_enabled() == false
|
||||
- is_dequeue_enabled() == false
|
||||
!*/
|
||||
|
||||
void wait_for_num_blocked_dequeues (
|
||||
unsigned long num
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- blocks until one of the following is the case:
|
||||
- size() == 0 and the number of threads blocked on calls
|
||||
to dequeue() and dequeue_or_timeout() is greater than
|
||||
or equal to num.
|
||||
- is_enabled() == false
|
||||
- is_dequeue_enabled() == false
|
||||
!*/
|
||||
|
||||
bool is_enqueue_enabled (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns true if the enqueue() and enqueue_or_timeout() functions are
|
||||
currently enabled, returns false otherwise. (note that the higher
|
||||
level is_enabled() function can overrule this one. So if
|
||||
is_enabled() == false then enqueue functions are still disabled even
|
||||
if is_enqueue_enabled() returns true. But if is_enqueue_enabled() == false
|
||||
then enqueue functions are always disabled no matter the state of
|
||||
is_enabled())
|
||||
!*/
|
||||
|
||||
void disable_enqueue (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #is_enqueue_enabled() == false
|
||||
- causes all current and future calls to enqueue() and
|
||||
enqueue_or_timeout() to not block but to return false
|
||||
immediately until enable_enqueue() is called.
|
||||
!*/
|
||||
|
||||
void enable_enqueue (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #is_enqueue_enabled() == true
|
||||
!*/
|
||||
|
||||
bool is_dequeue_enabled (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns true if the dequeue() and dequeue_or_timeout() functions are
|
||||
currently enabled, returns false otherwise. (note that the higher
|
||||
level is_enabled() function can overrule this one. So if
|
||||
is_enabled() == false then dequeue functions are still disabled even
|
||||
if is_dequeue_enabled() returns true. But if is_dequeue_enabled() == false
|
||||
then dequeue functions are always disabled no matter the state of
|
||||
is_enabled())
|
||||
!*/
|
||||
|
||||
void disable_dequeue (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #is_dequeue_enabled() == false
|
||||
- causes all current and future calls to dequeue() and
|
||||
dequeue_or_timeout() to not block but to return false
|
||||
immediately until enable_dequeue() is called.
|
||||
!*/
|
||||
|
||||
void enable_dequeue (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #is_dequeue_enabled() == true
|
||||
!*/
|
||||
|
||||
size_t max_size (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the maximum number of objects of type T that this
|
||||
pipe can contain.
|
||||
!*/
|
||||
|
||||
size_t size (
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns the number of objects of type T that this
|
||||
object currently contains.
|
||||
!*/
|
||||
|
||||
bool enqueue (
|
||||
T& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (size() == max_size()) then
|
||||
- this call to enqueue() blocks until one of the following is the case:
|
||||
- there is room in the pipe for another item
|
||||
- max_size() == 0 and another thread is trying to dequeue from this
|
||||
pipe and we can pass our item object directly to that thread.
|
||||
- someone calls disable()
|
||||
- someone calls disable_enqueue()
|
||||
- else
|
||||
- this call does not block.
|
||||
- if (this call to enqueue() returns true) then
|
||||
- #is_enabled() == true
|
||||
- #is_enqueue_enabled() == true
|
||||
- if (max_size() == 0) then
|
||||
- using global swap, item was passed directly to a
|
||||
thread attempting to dequeue from this pipe
|
||||
- else
|
||||
- using global swap, item was added into this pipe.
|
||||
- #item is in an undefined but valid state for its type
|
||||
- else
|
||||
- item was NOT added into the pipe
|
||||
- #item == item (i.e. the value of item is unchanged)
|
||||
!*/
|
||||
|
||||
bool enqueue (T&& item) { return enqueue(item); }
|
||||
/*!
|
||||
enable enqueueing from rvalues
|
||||
!*/
|
||||
|
||||
bool enqueue_or_timeout (
|
||||
T& item,
|
||||
unsigned long timeout
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (size() == max_size() && timeout > 0) then
|
||||
- this call to enqueue_or_timeout() blocks until one of the following is the case:
|
||||
- there is room in the pipe to add another item
|
||||
- max_size() == 0 and another thread is trying to dequeue from this pipe
|
||||
and we can pass our item object directly to that thread.
|
||||
- someone calls disable()
|
||||
- someone calls disable_enqueue()
|
||||
- timeout milliseconds passes
|
||||
- else
|
||||
- this call does not block.
|
||||
- if (this call to enqueue() returns true) then
|
||||
- #is_enabled() == true
|
||||
- #is_enqueue_enabled() == true
|
||||
- if (max_size() == 0) then
|
||||
- using global swap, item was passed directly to a
|
||||
thread attempting to dequeue from this pipe
|
||||
- else
|
||||
- using global swap, item was added into this pipe.
|
||||
- #item is in an undefined but valid state for its type
|
||||
- else
|
||||
- item was NOT added into the pipe
|
||||
- #item == item (i.e. the value of item is unchanged)
|
||||
!*/
|
||||
|
||||
bool enqueue_or_timeout (T&& item, unsigned long timeout) { return enqueue_or_timeout(item,timeout); }
|
||||
/*!
|
||||
enable enqueueing from rvalues
|
||||
!*/
|
||||
|
||||
bool dequeue (
|
||||
T& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (size() == 0) then
|
||||
- this call to dequeue() blocks until one of the following is the case:
|
||||
- there is something in the pipe we can dequeue
|
||||
- max_size() == 0 and another thread is trying to enqueue an item
|
||||
onto this pipe and we can receive our item directly from that thread.
|
||||
- someone calls disable()
|
||||
- someone calls disable_dequeue()
|
||||
- else
|
||||
- this call does not block.
|
||||
- if (this call to dequeue() returns true) then
|
||||
- #is_enabled() == true
|
||||
- #is_dequeue_enabled() == true
|
||||
- the oldest item that was enqueued into this pipe has been
|
||||
swapped into #item.
|
||||
- else
|
||||
- nothing was dequeued from this pipe.
|
||||
- #item == item (i.e. the value of item is unchanged)
|
||||
!*/
|
||||
|
||||
bool dequeue_or_timeout (
|
||||
T& item,
|
||||
unsigned long timeout
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- if (size() == 0 && timeout > 0) then
|
||||
- this call to dequeue_or_timeout() blocks until one of the following is the case:
|
||||
- there is something in the pipe we can dequeue
|
||||
- max_size() == 0 and another thread is trying to enqueue an item onto this
|
||||
pipe and we can receive our item directly from that thread.
|
||||
- someone calls disable()
|
||||
- someone calls disable_dequeue()
|
||||
- timeout milliseconds passes
|
||||
- else
|
||||
- this call does not block.
|
||||
- if (this call to dequeue_or_timeout() returns true) then
|
||||
- #is_enabled() == true
|
||||
- #is_dequeue_enabled() == true
|
||||
- the oldest item that was enqueued into this pipe has been
|
||||
swapped into #item.
|
||||
- else
|
||||
- nothing was dequeued from this pipe.
|
||||
- #item == item (i.e. the value of item is unchanged)
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
pipe(const pipe&); // copy constructor
|
||||
pipe& operator=(const pipe&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_PIPE_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
|
||||
#ifdef DLIB_ALL_SOURCE_END
|
||||
#include "dlib_basic_cpp_build_tutorial.txt"
|
||||
#endif
|
||||
|
||||
#ifndef DLIB_PLATFORm_
|
||||
#define DLIB_PLATFORm_
|
||||
|
||||
|
||||
/*!
|
||||
This file ensures that:
|
||||
- if (we are compiling under a posix platform) then
|
||||
- DLIB_POSIX will be defined
|
||||
- if (this is also Mac OS X) then
|
||||
- MACOSX will be defined
|
||||
- if (this is also HP-UX) then
|
||||
- HPUX will be defined
|
||||
- if (we are compiling under an MS Windows platform) then
|
||||
- WIN32 will be defined
|
||||
!*/
|
||||
|
||||
|
||||
/*
|
||||
A good reference for this sort of information is
|
||||
http://predef.sourceforge.net/
|
||||
*/
|
||||
|
||||
// Define WIN32 if this is MS Windows
|
||||
#ifndef WIN32
|
||||
#if defined( _MSC_VER) || defined(__BORLANDC__) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
||||
#define WIN32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
// since this is the only other platform the library currently supports
|
||||
// just assume it is DLIB_POSIX if it isn't WIN32
|
||||
#ifndef DLIB_POSIX
|
||||
#define DLIB_POSIX
|
||||
#endif
|
||||
|
||||
#ifndef HPUX
|
||||
#if defined(__hpux ) || defined(hpux) || defined (_hpux)
|
||||
#define HPUX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MACOSX
|
||||
#ifdef __MACOSX__
|
||||
#define MACOSX
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#define MACOSX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // DLIB_PLATFORm_
|
||||
|
||||
84
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/queue.h
vendored
Normal file
84
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/queue.h
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_QUEUe_
|
||||
#define DLIB_QUEUe_
|
||||
|
||||
#include "queue/queue_kernel_1.h"
|
||||
#include "queue/queue_kernel_2.h"
|
||||
#include "queue/queue_kernel_c.h"
|
||||
|
||||
#include "queue/queue_sort_1.h"
|
||||
|
||||
|
||||
#include "algs.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager = default_memory_manager
|
||||
>
|
||||
class queue
|
||||
{
|
||||
queue() {}
|
||||
public:
|
||||
|
||||
|
||||
//----------- kernels ---------------
|
||||
|
||||
// kernel_1a
|
||||
typedef queue_kernel_1<T,mem_manager>
|
||||
kernel_1a;
|
||||
typedef queue_kernel_c<kernel_1a>
|
||||
kernel_1a_c;
|
||||
|
||||
|
||||
// kernel_2a
|
||||
typedef queue_kernel_2<T,20,mem_manager>
|
||||
kernel_2a;
|
||||
typedef queue_kernel_c<kernel_2a>
|
||||
kernel_2a_c;
|
||||
|
||||
|
||||
// kernel_2b
|
||||
typedef queue_kernel_2<T,100,mem_manager>
|
||||
kernel_2b;
|
||||
typedef queue_kernel_c<kernel_2b>
|
||||
kernel_2b_c;
|
||||
|
||||
|
||||
|
||||
|
||||
//---------- extensions ------------
|
||||
|
||||
// sort_1 extend kernel_1a
|
||||
typedef queue_sort_1<kernel_1a>
|
||||
sort_1a;
|
||||
typedef queue_sort_1<kernel_1a_c>
|
||||
sort_1a_c;
|
||||
|
||||
|
||||
// sort_1 extend kernel_2a
|
||||
typedef queue_sort_1<kernel_2a>
|
||||
sort_1b;
|
||||
typedef queue_sort_1<kernel_2a_c>
|
||||
sort_1b_c;
|
||||
|
||||
|
||||
|
||||
// sort_1 extend kernel_2b
|
||||
typedef queue_sort_1<kernel_2b>
|
||||
sort_1c;
|
||||
typedef queue_sort_1<kernel_2b_c>
|
||||
sort_1c_c;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_QUEUe_
|
||||
|
||||
@@ -0,0 +1,554 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_QUEUE_KERNEl_1_
|
||||
#define DLIB_QUEUE_KERNEl_1_
|
||||
|
||||
#include "queue_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../serialize.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager = default_memory_manager
|
||||
>
|
||||
class queue_kernel_1 : public enumerable<T>,
|
||||
public remover<T>
|
||||
{
|
||||
|
||||
/*!
|
||||
INITIAL VALUE
|
||||
queue_size == 0
|
||||
current_element == 0
|
||||
at_start_ == true
|
||||
|
||||
CONVENTION
|
||||
queue_size == the number of elements in the queue
|
||||
at_start() == at_start_
|
||||
current_element_valid() == (current_element != 0)
|
||||
element() == current_element->item
|
||||
|
||||
if (queue_size > 0)
|
||||
{
|
||||
in points to the last element to be inserted into the queue
|
||||
out points to the next element to be dequeued
|
||||
|
||||
each node points to the node inserted after it except for the most
|
||||
recently inserted node
|
||||
|
||||
current_element == 0
|
||||
}
|
||||
|
||||
!*/
|
||||
|
||||
|
||||
struct node
|
||||
{
|
||||
node* last;
|
||||
|
||||
T item;
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
queue_kernel_1 (
|
||||
) :
|
||||
in(0),
|
||||
out(0),
|
||||
queue_size(0),
|
||||
current_element(0),
|
||||
at_start_(true)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~queue_kernel_1 (
|
||||
);
|
||||
|
||||
inline void clear(
|
||||
);
|
||||
|
||||
void enqueue (
|
||||
T& item
|
||||
);
|
||||
|
||||
void dequeue (
|
||||
T& item
|
||||
);
|
||||
|
||||
void cat (
|
||||
queue_kernel_1& item
|
||||
);
|
||||
|
||||
T& current (
|
||||
);
|
||||
|
||||
const T& current (
|
||||
) const;
|
||||
|
||||
void swap (
|
||||
queue_kernel_1& item
|
||||
);
|
||||
|
||||
// functions from the remover interface
|
||||
inline void remove_any (
|
||||
T& item
|
||||
);
|
||||
|
||||
// functions from the enumerable interface
|
||||
inline size_t size (
|
||||
) const;
|
||||
|
||||
inline bool at_start (
|
||||
) const;
|
||||
|
||||
inline void reset (
|
||||
) const;
|
||||
|
||||
bool current_element_valid (
|
||||
) const;
|
||||
|
||||
inline const T& element (
|
||||
) const;
|
||||
|
||||
inline T& element (
|
||||
);
|
||||
|
||||
bool move_next (
|
||||
) const;
|
||||
|
||||
private:
|
||||
|
||||
void delete_nodes (
|
||||
node* start,
|
||||
unsigned long length
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- start points to a node in a singly linked list
|
||||
- start->last points to the next node in the list
|
||||
- there are at least length nodes in the list beginning with start
|
||||
ensures
|
||||
- length nodes have been deleted starting with the node pointed
|
||||
to by start
|
||||
!*/
|
||||
|
||||
// data members
|
||||
|
||||
node* in;
|
||||
node* out;
|
||||
unsigned long queue_size;
|
||||
mutable node* current_element;
|
||||
mutable bool at_start_;
|
||||
|
||||
// restricted functions
|
||||
queue_kernel_1(queue_kernel_1&); // copy constructor
|
||||
queue_kernel_1& operator=(queue_kernel_1&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
inline void swap (
|
||||
queue_kernel_1<T,mem_manager>& a,
|
||||
queue_kernel_1<T,mem_manager>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
queue_kernel_1<T,mem_manager>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.clear();
|
||||
unsigned long size;
|
||||
deserialize(size,in);
|
||||
T temp;
|
||||
for (unsigned long i = 0; i < size; ++i)
|
||||
{
|
||||
deserialize(temp,in);
|
||||
item.enqueue(temp);
|
||||
}
|
||||
}
|
||||
catch (serialization_error& e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type queue_kernel_1");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
queue_kernel_1<T,mem_manager>::
|
||||
~queue_kernel_1 (
|
||||
)
|
||||
{
|
||||
delete_nodes(out,queue_size);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_1<T,mem_manager>::
|
||||
clear (
|
||||
)
|
||||
{
|
||||
delete_nodes(out,queue_size);
|
||||
queue_size = 0;
|
||||
|
||||
// put the enumerator at the start
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_1<T,mem_manager>::
|
||||
enqueue (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
// make new node
|
||||
node* temp = new node;
|
||||
|
||||
// swap item into new node
|
||||
exchange(item,temp->item);
|
||||
|
||||
if (queue_size == 0)
|
||||
out = temp;
|
||||
else
|
||||
in->last = temp;
|
||||
|
||||
// make in point to the new node
|
||||
in = temp;
|
||||
|
||||
++queue_size;
|
||||
|
||||
// put the enumerator at the start
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_1<T,mem_manager>::
|
||||
dequeue (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
// swap out into item
|
||||
exchange(item,out->item);
|
||||
|
||||
--queue_size;
|
||||
|
||||
if (queue_size == 0)
|
||||
{
|
||||
delete out;
|
||||
}
|
||||
else
|
||||
{
|
||||
node* temp = out;
|
||||
|
||||
// move out pointer to the next element in the queue
|
||||
out = out->last;
|
||||
|
||||
// delete old node
|
||||
delete temp;
|
||||
}
|
||||
|
||||
// put the enumerator at the start
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_1<T,mem_manager>::
|
||||
cat (
|
||||
queue_kernel_1<T,mem_manager>& item
|
||||
)
|
||||
{
|
||||
if (item.queue_size > 0)
|
||||
{
|
||||
if (queue_size > 0)
|
||||
{
|
||||
in->last = item.out;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = item.out;
|
||||
}
|
||||
|
||||
|
||||
in = item.in;
|
||||
queue_size += item.queue_size;
|
||||
item.queue_size = 0;
|
||||
}
|
||||
|
||||
// put the enumerator at the start
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
T& queue_kernel_1<T,mem_manager>::
|
||||
current (
|
||||
)
|
||||
{
|
||||
return out->item;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
const T& queue_kernel_1<T,mem_manager>::
|
||||
current (
|
||||
) const
|
||||
{
|
||||
return out->item;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_1<T,mem_manager>::
|
||||
swap (
|
||||
queue_kernel_1<T,mem_manager>& item
|
||||
)
|
||||
{
|
||||
node* in_temp = in;
|
||||
node* out_temp = out;
|
||||
unsigned long queue_size_temp = queue_size;
|
||||
node* current_element_temp = current_element;
|
||||
bool at_start_temp = at_start_;
|
||||
|
||||
in = item.in;
|
||||
out = item.out;
|
||||
queue_size = item.queue_size;
|
||||
current_element = item.current_element;
|
||||
at_start_ = item.at_start_;
|
||||
|
||||
item.in = in_temp;
|
||||
item.out = out_temp;
|
||||
item.queue_size = queue_size_temp;
|
||||
item.current_element = current_element_temp;
|
||||
item.at_start_ = at_start_temp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// enumerable function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
bool queue_kernel_1<T,mem_manager>::
|
||||
at_start (
|
||||
) const
|
||||
{
|
||||
return at_start_;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
size_t queue_kernel_1<T,mem_manager>::
|
||||
size (
|
||||
) const
|
||||
{
|
||||
return queue_size;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_1<T,mem_manager>::
|
||||
reset (
|
||||
) const
|
||||
{
|
||||
at_start_ = true;
|
||||
current_element = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
bool queue_kernel_1<T,mem_manager>::
|
||||
current_element_valid (
|
||||
) const
|
||||
{
|
||||
return (current_element != 0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
const T& queue_kernel_1<T,mem_manager>::
|
||||
element (
|
||||
) const
|
||||
{
|
||||
return current_element->item;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
T& queue_kernel_1<T,mem_manager>::
|
||||
element (
|
||||
)
|
||||
{
|
||||
return current_element->item;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
bool queue_kernel_1<T,mem_manager>::
|
||||
move_next (
|
||||
) const
|
||||
{
|
||||
if (at_start_)
|
||||
{
|
||||
at_start_ = false;
|
||||
// if the queue is empty then there is nothing to do
|
||||
if (queue_size == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_element = out;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we are at the last element then the enumeration has finished
|
||||
if (current_element == in || current_element == 0)
|
||||
{
|
||||
current_element = 0;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_element = current_element->last;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// remover function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_1<T,mem_manager>::
|
||||
remove_any (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
dequeue(item);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// private member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_1<T,mem_manager>::
|
||||
delete_nodes (
|
||||
node* start,
|
||||
unsigned long length
|
||||
)
|
||||
{
|
||||
node* temp;
|
||||
while (length)
|
||||
{
|
||||
temp = start->last;
|
||||
delete start;
|
||||
start = temp;
|
||||
--length;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_QUEUE_KERNEl_1_
|
||||
|
||||
@@ -0,0 +1,600 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_QUEUE_KERNEl_2_
|
||||
#define DLIB_QUEUE_KERNEl_2_
|
||||
|
||||
#include "queue_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../assert.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../serialize.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager = default_memory_manager
|
||||
>
|
||||
class queue_kernel_2 : public enumerable<T>,
|
||||
public remover<T>
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON block_size
|
||||
0 < block_size < 2000000000
|
||||
|
||||
INITIAL VALUE
|
||||
queue_size == 0
|
||||
current_element == 0
|
||||
at_start_ == true
|
||||
|
||||
CONVENTION
|
||||
queue_size == the number of elements in the queue
|
||||
at_start() == at_start_
|
||||
current_element_valid() == (current_element != 0)
|
||||
if (current_element_valid()) then
|
||||
element() == current_element->item[current_element_pos]
|
||||
|
||||
if (queue_size > 0)
|
||||
{
|
||||
in->item[in_pos] == the spot where we will put the next item added
|
||||
into the queue
|
||||
out->item[out_pos] == current()
|
||||
|
||||
when enqueuing elements inside each node item[0] is filled first, then
|
||||
item[1], then item[2], etc.
|
||||
|
||||
|
||||
each node points to the node inserted after it except for the most
|
||||
recently inserted node.
|
||||
}
|
||||
|
||||
!*/
|
||||
|
||||
|
||||
struct node
|
||||
{
|
||||
node* next;
|
||||
|
||||
T item[block_size];
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
queue_kernel_2 (
|
||||
) :
|
||||
in(0),
|
||||
out(0),
|
||||
queue_size(0),
|
||||
current_element(0),
|
||||
at_start_(true)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~queue_kernel_2 (
|
||||
);
|
||||
|
||||
inline void clear(
|
||||
);
|
||||
|
||||
void enqueue (
|
||||
T& item
|
||||
);
|
||||
|
||||
void dequeue (
|
||||
T& item
|
||||
);
|
||||
|
||||
void cat (
|
||||
queue_kernel_2& item
|
||||
);
|
||||
|
||||
T& current (
|
||||
);
|
||||
|
||||
const T& current (
|
||||
) const;
|
||||
|
||||
void swap (
|
||||
queue_kernel_2& item
|
||||
);
|
||||
|
||||
// functions from the remover interface
|
||||
inline void remove_any (
|
||||
T& item
|
||||
);
|
||||
|
||||
// functions from the enumerable interface
|
||||
inline size_t size (
|
||||
) const;
|
||||
|
||||
inline bool at_start (
|
||||
) const;
|
||||
|
||||
inline void reset (
|
||||
) const;
|
||||
|
||||
bool current_element_valid (
|
||||
) const;
|
||||
|
||||
inline const T& element (
|
||||
) const;
|
||||
|
||||
inline T& element (
|
||||
);
|
||||
|
||||
bool move_next (
|
||||
) const;
|
||||
|
||||
private:
|
||||
|
||||
void delete_nodes (
|
||||
node* start,
|
||||
node* end
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- start points to a node in a singly linked list
|
||||
- start->next points to the next node in the list
|
||||
- by following the next pointers you eventually hit the node pointed
|
||||
to by end
|
||||
ensures
|
||||
- calls delete on the start node, the end node, and all nodes in between
|
||||
!*/
|
||||
|
||||
// data members
|
||||
|
||||
typename mem_manager::template rebind<node>::other pool;
|
||||
|
||||
node* in;
|
||||
node* out;
|
||||
size_t queue_size;
|
||||
size_t in_pos;
|
||||
size_t out_pos;
|
||||
|
||||
|
||||
mutable node* current_element;
|
||||
mutable size_t current_element_pos;
|
||||
mutable bool at_start_;
|
||||
|
||||
// restricted functions
|
||||
queue_kernel_2(queue_kernel_2&); // copy constructor
|
||||
queue_kernel_2& operator=(queue_kernel_2&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
inline void swap (
|
||||
queue_kernel_2<T,block_size,mem_manager>& a,
|
||||
queue_kernel_2<T,block_size,mem_manager>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
queue_kernel_2<T,block_size,mem_manager>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.clear();
|
||||
unsigned long size;
|
||||
deserialize(size,in);
|
||||
T temp;
|
||||
for (unsigned long i = 0; i < size; ++i)
|
||||
{
|
||||
deserialize(temp,in);
|
||||
item.enqueue(temp);
|
||||
}
|
||||
}
|
||||
catch (serialization_error& e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type queue_kernel_2");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
queue_kernel_2<T,block_size,mem_manager>::
|
||||
~queue_kernel_2 (
|
||||
)
|
||||
{
|
||||
COMPILE_TIME_ASSERT(0 < block_size && block_size < (unsigned long)(2000000000));
|
||||
|
||||
if (queue_size > 0)
|
||||
delete_nodes(out,in);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_2<T,block_size,mem_manager>::
|
||||
clear (
|
||||
)
|
||||
{
|
||||
if (queue_size > 0)
|
||||
{
|
||||
delete_nodes(out,in);
|
||||
queue_size = 0;
|
||||
}
|
||||
|
||||
// put the enumerator at the start
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_2<T,block_size,mem_manager>::
|
||||
enqueue (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
if (queue_size == 0)
|
||||
{
|
||||
out = in = pool.allocate();
|
||||
in_pos = 0;
|
||||
out_pos = 0;
|
||||
}
|
||||
else if (in_pos >= block_size)
|
||||
{
|
||||
in->next = pool.allocate();
|
||||
in_pos = 0;
|
||||
in = in->next;
|
||||
}
|
||||
|
||||
exchange(item,in->item[in_pos]);
|
||||
++in_pos;
|
||||
|
||||
++queue_size;
|
||||
|
||||
// put the enumerator at the start
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_2<T,block_size,mem_manager>::
|
||||
dequeue (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
// swap out into item
|
||||
exchange(item,out->item[out_pos]);
|
||||
|
||||
++out_pos;
|
||||
--queue_size;
|
||||
|
||||
// if this was the last element in this node then remove this node
|
||||
if (out_pos == block_size)
|
||||
{
|
||||
out_pos = 0;
|
||||
node* temp = out;
|
||||
out = out->next;
|
||||
pool.deallocate(temp);
|
||||
}
|
||||
else if (queue_size == 0)
|
||||
{
|
||||
pool.deallocate(out);
|
||||
}
|
||||
|
||||
// put the enumerator at the start
|
||||
reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_2<T,block_size,mem_manager>::
|
||||
cat (
|
||||
queue_kernel_2<T,block_size,mem_manager>& item
|
||||
)
|
||||
{
|
||||
if (queue_size > 0)
|
||||
{
|
||||
T temp;
|
||||
assign_zero_if_built_in_scalar_type(temp);
|
||||
while (item.size() > 0)
|
||||
{
|
||||
item.dequeue(temp);
|
||||
enqueue(temp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
in = item.in;
|
||||
out = item.out;
|
||||
out_pos = item.out_pos;
|
||||
in_pos = item.in_pos;
|
||||
|
||||
queue_size = item.queue_size;
|
||||
item.queue_size = 0;
|
||||
|
||||
// put the enumerator at the start
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
T& queue_kernel_2<T,block_size,mem_manager>::
|
||||
current (
|
||||
)
|
||||
{
|
||||
return out->item[out_pos];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
const T& queue_kernel_2<T,block_size,mem_manager>::
|
||||
current (
|
||||
) const
|
||||
{
|
||||
return out->item[out_pos];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_2<T,block_size,mem_manager>::
|
||||
swap (
|
||||
queue_kernel_2<T,block_size,mem_manager>& item
|
||||
)
|
||||
{
|
||||
exchange(in,item.in);
|
||||
exchange(out,item.out);
|
||||
exchange(queue_size,item.queue_size);
|
||||
exchange(in_pos,item.in_pos);
|
||||
exchange(out_pos,item.out_pos);
|
||||
exchange(current_element,item.current_element);
|
||||
exchange(current_element_pos,item.current_element_pos);
|
||||
exchange(at_start_,item.at_start_);
|
||||
pool.swap(item.pool);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// enumerable function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
size_t queue_kernel_2<T,block_size,mem_manager>::
|
||||
size (
|
||||
) const
|
||||
{
|
||||
return queue_size;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
bool queue_kernel_2<T,block_size,mem_manager>::
|
||||
at_start (
|
||||
) const
|
||||
{
|
||||
return at_start_;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_2<T,block_size,mem_manager>::
|
||||
reset (
|
||||
) const
|
||||
{
|
||||
at_start_ = true;
|
||||
current_element = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
bool queue_kernel_2<T,block_size,mem_manager>::
|
||||
current_element_valid (
|
||||
) const
|
||||
{
|
||||
return (current_element != 0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
const T& queue_kernel_2<T,block_size,mem_manager>::
|
||||
element (
|
||||
) const
|
||||
{
|
||||
return current_element->item[current_element_pos];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
T& queue_kernel_2<T,block_size,mem_manager>::
|
||||
element (
|
||||
)
|
||||
{
|
||||
return current_element->item[current_element_pos];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
bool queue_kernel_2<T,block_size,mem_manager>::
|
||||
move_next (
|
||||
) const
|
||||
{
|
||||
if (at_start_)
|
||||
{
|
||||
at_start_ = false;
|
||||
// if the queue is empty then there is nothing to do
|
||||
if (queue_size == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_element = out;
|
||||
current_element_pos = out_pos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (current_element == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
++current_element_pos;
|
||||
// if we are at the last element then the enumeration has finished
|
||||
if (current_element == in && current_element_pos == in_pos )
|
||||
{
|
||||
current_element = 0;
|
||||
return false;
|
||||
}
|
||||
else if (current_element_pos == block_size)
|
||||
{
|
||||
current_element_pos = 0;
|
||||
current_element = current_element->next;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// remover function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_2<T,block_size,mem_manager>::
|
||||
remove_any (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
dequeue(item);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// private member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
unsigned long block_size,
|
||||
typename mem_manager
|
||||
>
|
||||
void queue_kernel_2<T,block_size,mem_manager>::
|
||||
delete_nodes (
|
||||
node* start,
|
||||
node* end
|
||||
)
|
||||
{
|
||||
node* temp;
|
||||
while (start != end)
|
||||
{
|
||||
temp = start;
|
||||
start = start->next;
|
||||
pool.deallocate(temp);
|
||||
}
|
||||
pool.deallocate(start);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_QUEUE_KERNEl_2_
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_QUEUE_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_QUEUE_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../serialize.h"
|
||||
#include "../algs.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager = default_memory_manager
|
||||
>
|
||||
class queue : public enumerable<T>,
|
||||
public remover<T>
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T must be swappable by a global swap()
|
||||
T must have a default constructor
|
||||
|
||||
REQUIREMENTS ON mem_manager
|
||||
must be an implementation of memory_manager/memory_manager_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_global/memory_manager_global_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
|
||||
mem_manager::type can be set to anything.
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
swap() and current() functions do not invalidate pointers or
|
||||
references to internal data.
|
||||
All other functions have no such guarantee.
|
||||
|
||||
INITIAL VALUE
|
||||
size() == 0
|
||||
|
||||
ENUMERATION ORDER
|
||||
The enumerator will iterate over the elements in the queue in the
|
||||
same order they would be removed by repeated calls to dequeue().
|
||||
(e.g. current() would be the first element enumerated)
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This is a first in first out queue containing items of type T
|
||||
|
||||
e.g. if the queue is {b,c,d,e} and then 'a' is enqueued
|
||||
the queue becomes {a,b,c,d,e} and then calling dequeue takes e out
|
||||
making the queue {a,b,c,d}
|
||||
|
||||
Also note that unless specified otherwise, no member functions
|
||||
of this object throw exceptions.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
queue (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
!*/
|
||||
|
||||
virtual ~queue (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- all memory associated with *this has 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 enqueue (
|
||||
T& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- item is now at the left end of #*this
|
||||
- #item has an initial value for its type
|
||||
- #size() == size() + 1
|
||||
- #at_start() == true
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
if enqueue() throws then it has no effect
|
||||
!*/
|
||||
|
||||
void dequeue (
|
||||
T& item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- size() != 0
|
||||
ensures
|
||||
- #size() == size() - 1
|
||||
- the far right element of *this has been removed and swapped
|
||||
into #item
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
void cat (
|
||||
queue& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- item has been concatenated onto the left end of *this.
|
||||
i.e. item.current() is attached onto the left end of *this and
|
||||
the left most element in item will also be the left most item
|
||||
in #*this
|
||||
- #size() == size() + item.size()
|
||||
- #item has its initial value
|
||||
- #at_start() == true
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
if cat() throws then the state of #item and *this is undefined
|
||||
until clear() is successfully called on them.
|
||||
!*/
|
||||
|
||||
T& current (
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- size() != 0
|
||||
ensures
|
||||
- returns a const reference to the next element to be dequeued.
|
||||
i.e. the right most element.
|
||||
!*/
|
||||
|
||||
const T& current (
|
||||
) const;
|
||||
/*!
|
||||
requires
|
||||
- size() != 0
|
||||
ensures
|
||||
- returns a non-const reference to the next element to be dequeued.
|
||||
i.e. the right most element.
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
queue& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
queue(queue&); // copy constructor
|
||||
queue& operator=(queue&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
inline void swap (
|
||||
queue<T,mem_manager>& a,
|
||||
queue<T,mem_manager>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
queue<T,mem_manager>& item,
|
||||
std::istream& in
|
||||
);
|
||||
/*!
|
||||
provides deserialization support
|
||||
!*/
|
||||
}
|
||||
|
||||
#endif // DLIB_QUEUE_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_QUEUE_KERNEl_C_
|
||||
#define DLIB_QUEUE_KERNEl_C_
|
||||
|
||||
#include "queue_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../assert.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
|
||||
template <
|
||||
typename queue_base // is an implementation of queue_kernel_abstract.h
|
||||
>
|
||||
class queue_kernel_c : public queue_base
|
||||
{
|
||||
typedef typename queue_base::type T;
|
||||
|
||||
public:
|
||||
|
||||
void dequeue (
|
||||
T& item
|
||||
);
|
||||
|
||||
T& current (
|
||||
);
|
||||
|
||||
const T& current (
|
||||
) const;
|
||||
|
||||
const T& element (
|
||||
) const;
|
||||
|
||||
T& element (
|
||||
);
|
||||
|
||||
void remove_any (
|
||||
T& item
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
inline void swap (
|
||||
queue_kernel_c<queue_base>& a,
|
||||
queue_kernel_c<queue_base>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
void queue_kernel_c<queue_base>::
|
||||
dequeue (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->size() != 0,
|
||||
"\tvoid queue::dequeue"
|
||||
<< "\n\tsize of queue should not be zero"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
queue_base::dequeue(item);
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
const typename queue_base::type& queue_kernel_c<queue_base>::
|
||||
current (
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->size() != 0,
|
||||
"\tconst T& queue::current"
|
||||
<< "\n\tsize of queue should not be zero"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return queue_base::current();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
typename queue_base::type& queue_kernel_c<queue_base>::
|
||||
current (
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->size() != 0,
|
||||
"\tT& queue::current"
|
||||
<< "\n\tsize of queue should not be zero"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return queue_base::current();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
const typename queue_base::type& queue_kernel_c<queue_base>::
|
||||
element (
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tconst T& queue::element"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return queue_base::element();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
typename queue_base::type& queue_kernel_c<queue_base>::
|
||||
element (
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tT& queue::element"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return queue_base::element();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
void queue_kernel_c<queue_base>::
|
||||
remove_any (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( (this->size() > 0),
|
||||
"\tvoid queue::remove_any"
|
||||
<< "\n\tsize() must be greater than zero if something is going to be removed"
|
||||
<< "\n\tsize(): " << this->size()
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
queue_base::remove_any(item);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_QUEUE_KERNEl_C_
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_QUEUE_SORt_1_
|
||||
#define DLIB_QUEUE_SORt_1_
|
||||
|
||||
#include "queue_sort_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include <vector>
|
||||
#include "../sort.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
class queue_sort_1 : public queue_base
|
||||
{
|
||||
typedef typename queue_base::type T;
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
This implementation uses the QuickSort algorithm and
|
||||
when the quicksort depth goes too high it uses the dlib::qsort_array()
|
||||
function on the data.
|
||||
!*/
|
||||
|
||||
void sort (
|
||||
);
|
||||
|
||||
template <typename compare_type>
|
||||
void sort (
|
||||
const compare_type& compare
|
||||
)
|
||||
{
|
||||
if (this->size() > 1)
|
||||
{
|
||||
sort_this_queue(*this,0,compare);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <typename compare_type>
|
||||
void sort_this_queue (
|
||||
queue_base& queue,
|
||||
long depth,
|
||||
const compare_type& compare
|
||||
)
|
||||
/*!
|
||||
ensures
|
||||
each element in the queue is < the element behind it according
|
||||
to compare
|
||||
!*/
|
||||
{
|
||||
if (queue.size() <= 1)
|
||||
{
|
||||
// already sorted
|
||||
}
|
||||
else if (queue.size() <= 29)
|
||||
{
|
||||
T vect[29];
|
||||
const unsigned long size = queue.size();
|
||||
for (unsigned long i = 0; i < size; ++i)
|
||||
{
|
||||
queue.dequeue(vect[i]);
|
||||
}
|
||||
isort_array(vect,0,size-1,compare);
|
||||
for (unsigned long i = 0; i < size; ++i)
|
||||
{
|
||||
queue.enqueue(vect[i]);
|
||||
}
|
||||
}
|
||||
else if (depth > 50)
|
||||
{
|
||||
std::vector<T> vect(queue.size());
|
||||
for (unsigned long i = 0; i < vect.size(); ++i)
|
||||
{
|
||||
queue.dequeue(vect[i]);
|
||||
}
|
||||
hsort_array(vect,0,vect.size()-1,compare);
|
||||
for (unsigned long i = 0; i < vect.size(); ++i)
|
||||
{
|
||||
queue.enqueue(vect[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
queue_base left, right;
|
||||
T partition_element;
|
||||
T temp;
|
||||
// do this just to avoid a compiler warning
|
||||
assign_zero_if_built_in_scalar_type(temp);
|
||||
assign_zero_if_built_in_scalar_type(partition_element);
|
||||
|
||||
queue.dequeue(partition_element);
|
||||
|
||||
// partition queue into left and right
|
||||
while (queue.size() > 0)
|
||||
{
|
||||
queue.dequeue(temp);
|
||||
if (compare(temp , partition_element))
|
||||
{
|
||||
left.enqueue(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
right.enqueue(temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
long ratio;
|
||||
if (left.size() > right.size())
|
||||
ratio = left.size()/(right.size()+1); // add 1 so we can't divide by zero
|
||||
else
|
||||
ratio = right.size()/(left.size()+1);
|
||||
|
||||
sort_this_queue(left,ratio+depth,compare);
|
||||
sort_this_queue(right,ratio+depth,compare);
|
||||
|
||||
// combine the two queues
|
||||
left.swap(queue);
|
||||
queue.enqueue(partition_element);
|
||||
queue.cat(right);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
inline void swap (
|
||||
queue_sort_1<queue_base>& a,
|
||||
queue_sort_1<queue_base>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
void queue_sort_1<queue_base>::
|
||||
sort (
|
||||
)
|
||||
{
|
||||
if (this->size() > 1)
|
||||
{
|
||||
sort_this_queue(*this,0,std::less<typename queue_base::type>());
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_QUEUE_SORt_1_
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_QUEUE_SORt_ABSTRACT_
|
||||
#ifdef DLIB_QUEUE_SORt_ABSTRACT_
|
||||
|
||||
|
||||
#include "queue_kernel_abstract.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename queue_base
|
||||
>
|
||||
class queue_sort : public queue_base
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON QUEUE_BASE
|
||||
- is an implementation of queue/queue_kernel_abstract.h
|
||||
- queue_base::type must be a type with that is comparable via operator<
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
sort() may invalidate pointers and references to internal data.
|
||||
|
||||
WHAT THIS EXTENSION DOES FOR QUEUE
|
||||
This gives a queue the ability to sort its contents by calling sort().
|
||||
!*/
|
||||
|
||||
|
||||
public:
|
||||
|
||||
void sort (
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all elements in #*this the ith element is <= the i+1 element
|
||||
- #at_start() == true
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
data may be lost if sort() throws
|
||||
!*/
|
||||
|
||||
template <typename compare_type>
|
||||
void sort (
|
||||
const compare_type& compare
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- for all elements in #*this the ith element is <= the i+1 element
|
||||
- uses compare(a,b) as the < operator. So if compare(a,b) == true
|
||||
then a comes before b in the resulting ordering.
|
||||
- #at_start() == true
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
data may be lost if sort() throws
|
||||
!*/
|
||||
};
|
||||
|
||||
template <
|
||||
template queue_base
|
||||
>
|
||||
inline void swap (
|
||||
queue_sort<queue_base>& a,
|
||||
queue_sort<queue_base>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_QUEUE_SORt_ABSTRACT_
|
||||
|
||||
84
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/ref.h
vendored
Normal file
84
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/ref.h
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright (C) 2010 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_REFERENCE_WRAPpER_H_
|
||||
#define DLIB_REFERENCE_WRAPpER_H_
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template<
|
||||
typename T
|
||||
>
|
||||
class reference_wrapper
|
||||
{
|
||||
/*!
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
This is a simple object that just holds a reference to another object.
|
||||
It is useful because it can serve as a kind of "copyable reference".
|
||||
!*/
|
||||
|
||||
public:
|
||||
typedef T type;
|
||||
|
||||
explicit reference_wrapper(T& o) : obj(&o) {}
|
||||
|
||||
operator T&() const { return *obj; }
|
||||
T& get() const { return *obj; }
|
||||
|
||||
private:
|
||||
T* obj;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
reference_wrapper<T> ref(
|
||||
T& obj
|
||||
) { return reference_wrapper<T>(obj); }
|
||||
/*!
|
||||
ensures
|
||||
- returns a reference_wrapper that contains a reference to obj.
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
reference_wrapper<T> ref(
|
||||
reference_wrapper<T> obj
|
||||
) { return obj; }
|
||||
/*!
|
||||
ensures
|
||||
- returns the given reference_wrapper object without modification
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
reference_wrapper<const T> cref(
|
||||
const T& obj
|
||||
) { return reference_wrapper<const T>(obj); }
|
||||
/*!
|
||||
ensures
|
||||
- returns a reference_wrapper that contains a constant reference to obj.
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <typename T>
|
||||
reference_wrapper<const T> cref(
|
||||
reference_wrapper<T> obj
|
||||
) { return cref(obj.get()); }
|
||||
/*!
|
||||
ensures
|
||||
- converts the given reference_wrapper into a reference_wrapper that contains a
|
||||
constant reference.
|
||||
!*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_REFERENCE_WRAPpER_H_
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef DLIB_REVISION_H
|
||||
#define DLIB_MAJOR_VERSION 19
|
||||
#define DLIB_MINOR_VERSION 21
|
||||
#define DLIB_PATCH_VERSION 99
|
||||
#endif
|
||||
|
||||
2606
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/serialize.h
vendored
Normal file
2606
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/serialize.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
74
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/set.h
vendored
Normal file
74
Plugins/GameLiftPlugin/Source/GameLiftServer/ThirdParty/concurrentqueue/benchmarks/dlib/set.h
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SEt_
|
||||
#define DLIB_SEt_
|
||||
|
||||
#include "set/set_kernel_1.h"
|
||||
#include "set/set_kernel_c.h"
|
||||
|
||||
|
||||
|
||||
#include "binary_search_tree.h"
|
||||
|
||||
#include "set/set_compare_1.h"
|
||||
|
||||
#include "algs.h"
|
||||
#include <functional>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager = default_memory_manager,
|
||||
typename compare = std::less<T>
|
||||
>
|
||||
class set
|
||||
{
|
||||
set() {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef typename binary_search_tree<T,char,mem_manager,compare>::kernel_1a
|
||||
binary_search_tree_1;
|
||||
|
||||
typedef typename binary_search_tree<T,char,mem_manager,compare>::kernel_2a
|
||||
binary_search_tree_2;
|
||||
|
||||
public:
|
||||
|
||||
//----------- kernels ---------------
|
||||
|
||||
// kernel_1a
|
||||
typedef set_kernel_1<T,binary_search_tree_1,mem_manager>
|
||||
kernel_1a;
|
||||
typedef set_kernel_c<kernel_1a>
|
||||
kernel_1a_c;
|
||||
|
||||
// kernel_1b
|
||||
typedef set_kernel_1<T,binary_search_tree_2,mem_manager>
|
||||
kernel_1b;
|
||||
typedef set_kernel_c<kernel_1b>
|
||||
kernel_1b_c;
|
||||
|
||||
|
||||
//---------- extensions ------------
|
||||
|
||||
// compare extensions
|
||||
typedef set_compare_1<kernel_1a>
|
||||
compare_1a;
|
||||
typedef set_compare_1<kernel_1a_c>
|
||||
compare_1a_c;
|
||||
|
||||
typedef set_compare_1<kernel_1b>
|
||||
compare_1b;
|
||||
typedef set_compare_1<kernel_1b_c>
|
||||
compare_1b_c;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_SEt_
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
// Copyright (C) 2005 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SET_COMPARe_1_
|
||||
#define DLIB_SET_COMPARe_1_
|
||||
|
||||
#include "set_compare_abstract.h"
|
||||
|
||||
#include "../algs.h"
|
||||
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
class set_compare_1 : public set_base
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
bool operator< (
|
||||
const set_compare_1& rhs
|
||||
) const;
|
||||
|
||||
bool operator== (
|
||||
const set_compare_1& rhs
|
||||
) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
inline void swap (
|
||||
set_compare_1<set_base>& a,
|
||||
set_compare_1<set_base>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
bool set_compare_1<set_base>::
|
||||
operator< (
|
||||
const set_compare_1<set_base>& rhs
|
||||
) const
|
||||
{
|
||||
bool result = false;
|
||||
if (set_base::size() < rhs.size())
|
||||
result = true;
|
||||
|
||||
if (set_base::size() == rhs.size())
|
||||
{
|
||||
rhs.reset();
|
||||
set_base::reset();
|
||||
while (rhs.move_next())
|
||||
{
|
||||
set_base::move_next();
|
||||
if (set_base::element() < rhs.element())
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
else if (rhs.element() < set_base::element())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_base::reset();
|
||||
rhs.reset();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
bool set_compare_1<set_base>::
|
||||
operator== (
|
||||
const set_compare_1<set_base>& rhs
|
||||
) const
|
||||
{
|
||||
bool result = true;
|
||||
if (set_base::size() != rhs.size())
|
||||
result = false;
|
||||
|
||||
|
||||
rhs.reset();
|
||||
set_base::reset();
|
||||
while (rhs.move_next() && set_base::move_next())
|
||||
{
|
||||
if (!(rhs.element() == set_base::element()))
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
set_base::reset();
|
||||
rhs.reset();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SET_COMPARe_1_
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
// Copyright (C) 2005 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_SET_COMPARe_ABSTRACT_
|
||||
#ifdef DLIB_SET_COMPARe_ABSTRACT_
|
||||
|
||||
#include "set_kernel_abstract.h"
|
||||
|
||||
#include "../algs.h"
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
class set_compare : public set_base
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON set_base
|
||||
must be an implementation of set/set_kernel_abstract.h
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
operator== and operator< invalidate pointers or references to
|
||||
data members.
|
||||
|
||||
WHAT THIS EXTENSION DOES FOR set
|
||||
This gives a set the ability to compare itself to other
|
||||
sets using the < and == operators.
|
||||
|
||||
The < operator is conceptually weird for sets. It is useful
|
||||
though because it allows you to make sets of sets since
|
||||
sets require that their containing type implement operator<.
|
||||
|
||||
Also note that it is the case that for any two sets a and b
|
||||
if (a<b) == false and (b<a) == false then a == b.
|
||||
|
||||
Also note that unless specified otherwise, no member functions
|
||||
of this object throw exceptions.
|
||||
|
||||
|
||||
NOTATION
|
||||
For the purposes of defining what these operators do I will
|
||||
use the operator[] to reference the elements of the sets.
|
||||
operator[] is defined to access the elements of the set in
|
||||
the same order they would be enumerated by the enumerable
|
||||
interface.
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
bool operator< (
|
||||
const set_compare& rhs
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- #at_start() == true
|
||||
- if (size() < rhs.size()) then
|
||||
- returns true
|
||||
- else if (size() > rhs.size()) then
|
||||
- returns false
|
||||
- else
|
||||
- returns true if there exists an integer j such that 0 <= j < size()
|
||||
and for all integers i such that 0 <= i < j where it is true that
|
||||
(*this)[i] == rhs[i] and (*this)[j] < rhs[j]
|
||||
- returns false if there is no j that will satisfy the above conditions.
|
||||
!*/
|
||||
|
||||
bool operator== (
|
||||
const set_compare& rhs
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- #at_start() == true
|
||||
- returns true if *this and rhs contain the same elements.
|
||||
returns false otherwise.
|
||||
!*/
|
||||
};
|
||||
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
inline void swap (
|
||||
set_compare<set_base>& a,
|
||||
set_compare<set_base>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SET_COMPARe_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,372 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SET_KERNEl_1_
|
||||
#define DLIB_SET_KERNEl_1_
|
||||
|
||||
#include "set_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../serialize.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager = default_memory_manager
|
||||
>
|
||||
class set_kernel_1 : public enumerable<const T>,
|
||||
public asc_remover<T,typename bst_base::compare_type>
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON bst_base
|
||||
bst_base is instantiated with <domain=T,range=char> and
|
||||
implements binray_search_tree/binary_search_tree_kernel_abstract.h
|
||||
|
||||
INITIAL VALUE
|
||||
bst has its initial value
|
||||
|
||||
CONVENTION
|
||||
bst.size() == the number of elements in the set and
|
||||
the elements in the set are stored in bst
|
||||
!*/
|
||||
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
typedef typename bst_base::compare_type compare_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
set_kernel_1(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~set_kernel_1(
|
||||
)
|
||||
{}
|
||||
|
||||
inline void clear(
|
||||
);
|
||||
|
||||
inline void add (
|
||||
T& item
|
||||
);
|
||||
|
||||
inline bool is_member (
|
||||
const T& item
|
||||
) const;
|
||||
|
||||
inline void remove (
|
||||
const T& item,
|
||||
T& item_copy
|
||||
);
|
||||
|
||||
inline void destroy (
|
||||
const T& item
|
||||
);
|
||||
|
||||
inline void swap (
|
||||
set_kernel_1& item
|
||||
);
|
||||
|
||||
// functions from the remover interface
|
||||
inline void remove_any (
|
||||
T& item
|
||||
);
|
||||
|
||||
// functions from the enumerable interface
|
||||
inline size_t size (
|
||||
) const;
|
||||
|
||||
inline bool at_start (
|
||||
) const;
|
||||
|
||||
inline void reset (
|
||||
) const;
|
||||
|
||||
inline bool current_element_valid (
|
||||
) const;
|
||||
|
||||
inline const T& element (
|
||||
) const;
|
||||
|
||||
|
||||
inline const T& element (
|
||||
);
|
||||
|
||||
inline bool move_next (
|
||||
) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
bst_base bst;
|
||||
char junk;
|
||||
|
||||
// restricted functions
|
||||
set_kernel_1(set_kernel_1&);
|
||||
set_kernel_1& operator=(set_kernel_1&);
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
inline void swap (
|
||||
set_kernel_1<T,bst_base,mem_manager>& a,
|
||||
set_kernel_1<T,bst_base,mem_manager>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
set_kernel_1<T,bst_base,mem_manager>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.clear();
|
||||
unsigned long size;
|
||||
deserialize(size,in);
|
||||
T temp;
|
||||
for (unsigned long i = 0; i < size; ++i)
|
||||
{
|
||||
deserialize(temp,in);
|
||||
item.add(temp);
|
||||
}
|
||||
}
|
||||
catch (serialization_error& e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type set_kernel_1");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void set_kernel_1<T,bst_base,mem_manager>::
|
||||
clear (
|
||||
)
|
||||
{
|
||||
bst.clear();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void set_kernel_1<T,bst_base,mem_manager>::
|
||||
add (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
bst.add(item,junk);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
bool set_kernel_1<T,bst_base,mem_manager>::
|
||||
is_member(
|
||||
const T& item
|
||||
) const
|
||||
{
|
||||
return (bst[item] != 0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void set_kernel_1<T,bst_base,mem_manager>::
|
||||
remove_any (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
bst.remove_any(item,junk);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void set_kernel_1<T,bst_base,mem_manager>::
|
||||
remove(
|
||||
const T& item,
|
||||
T& item_copy
|
||||
)
|
||||
{
|
||||
bst.remove(item,item_copy,junk);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void set_kernel_1<T,bst_base,mem_manager>::
|
||||
destroy(
|
||||
const T& item
|
||||
)
|
||||
{
|
||||
bst.destroy(item);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
size_t set_kernel_1<T,bst_base,mem_manager>::
|
||||
size (
|
||||
) const
|
||||
{
|
||||
return bst.size();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void set_kernel_1<T,bst_base,mem_manager>::
|
||||
swap (
|
||||
set_kernel_1<T,bst_base,mem_manager>& item
|
||||
)
|
||||
{
|
||||
bst.swap(item.bst);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// enumerable function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
bool set_kernel_1<T,bst_base,mem_manager>::
|
||||
at_start (
|
||||
) const
|
||||
{
|
||||
return bst.at_start();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
void set_kernel_1<T,bst_base,mem_manager>::
|
||||
reset (
|
||||
) const
|
||||
{
|
||||
bst.reset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
bool set_kernel_1<T,bst_base,mem_manager>::
|
||||
current_element_valid (
|
||||
) const
|
||||
{
|
||||
return bst.current_element_valid();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
const T& set_kernel_1<T,bst_base,mem_manager>::
|
||||
element (
|
||||
) const
|
||||
{
|
||||
return bst.element().key();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
const T& set_kernel_1<T,bst_base,mem_manager>::
|
||||
element (
|
||||
)
|
||||
{
|
||||
return bst.element().key();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename bst_base,
|
||||
typename mem_manager
|
||||
>
|
||||
bool set_kernel_1<T,bst_base,mem_manager>::
|
||||
move_next (
|
||||
) const
|
||||
{
|
||||
return bst.move_next();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SET_KERNEl_1_
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#undef DLIB_SET_KERNEl_ABSTRACT_
|
||||
#ifdef DLIB_SET_KERNEl_ABSTRACT_
|
||||
|
||||
#include "../interfaces/enumerable.h"
|
||||
#include "../interfaces/remover.h"
|
||||
#include "../serialize.h"
|
||||
#include "../algs.h"
|
||||
#include <functional>
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager = default_memory_manager,
|
||||
typename compare = std::less<T>
|
||||
>
|
||||
class set : public enumerable<const T>,
|
||||
public asc_remover<T,compare>
|
||||
{
|
||||
|
||||
/*!
|
||||
REQUIREMENTS ON T
|
||||
T must be comparable by compare where compare is a functor compatible with std::less and
|
||||
T must be swappable by a global swap() and
|
||||
T must have a default constructor
|
||||
|
||||
REQUIREMENTS ON mem_manager
|
||||
must be an implementation of memory_manager/memory_manager_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_global/memory_manager_global_kernel_abstract.h or
|
||||
must be an implementation of memory_manager_stateless/memory_manager_stateless_kernel_abstract.h
|
||||
mem_manager::type can be set to anything.
|
||||
|
||||
POINTERS AND REFERENCES TO INTERNAL DATA
|
||||
swap() and is_member() functions do not invalidate pointers
|
||||
or references to internal data.
|
||||
All other functions have no such guarantee.
|
||||
|
||||
INITIAL VALUE
|
||||
size() == 0
|
||||
|
||||
ENUMERATION ORDER
|
||||
The enumerator will iterate over the elements in the set in
|
||||
ascending order according to the compare functor.
|
||||
(i.e. the elements are enumerated in sorted order)
|
||||
|
||||
WHAT THIS OBJECT REPRESENTS
|
||||
set contains items of type T
|
||||
|
||||
This object represents an unaddressed collection of items.
|
||||
Every element in a set is unique.
|
||||
|
||||
definition of equivalent:
|
||||
a is equivalent to b if
|
||||
a < b == false and
|
||||
b < a == false
|
||||
!*/
|
||||
|
||||
public:
|
||||
|
||||
typedef T type;
|
||||
typedef compare compare_type;
|
||||
typedef mem_manager mem_manager_type;
|
||||
|
||||
set(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- #*this is properly initialized
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
!*/
|
||||
|
||||
virtual ~set(
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- all memory associated with *this has 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 add (
|
||||
T& item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- is_member(item) == false
|
||||
ensures
|
||||
- #is_member(item) == true
|
||||
- #item has an initial value for its type
|
||||
- #size() == size() + 1
|
||||
- #at_start() == true
|
||||
throws
|
||||
- std::bad_alloc or any exception thrown by T's constructor
|
||||
if add() throws then it has no effect
|
||||
!*/
|
||||
|
||||
bool is_member (
|
||||
const T& item
|
||||
) const;
|
||||
/*!
|
||||
ensures
|
||||
- returns whether or not there is an element in *this equivalent to
|
||||
item
|
||||
!*/
|
||||
|
||||
void remove (
|
||||
const T& item,
|
||||
T& item_copy
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- is_member(item) == true
|
||||
- &item != &item_copy (i.e. item and item_copy cannot be the same
|
||||
variable)
|
||||
ensures
|
||||
- #is_member(item) == false
|
||||
- the element in *this equivalent to item has been removed and
|
||||
swapped into #item_copy
|
||||
- #size() == size() - 1
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
void destroy (
|
||||
const T& item
|
||||
);
|
||||
/*!
|
||||
requires
|
||||
- is_member(item) == true
|
||||
ensures
|
||||
- #is_member(item) == false
|
||||
- #size() == size() - 1
|
||||
- #at_start() == true
|
||||
!*/
|
||||
|
||||
void swap (
|
||||
set& item
|
||||
);
|
||||
/*!
|
||||
ensures
|
||||
- swaps *this and item
|
||||
!*/
|
||||
|
||||
private:
|
||||
|
||||
// restricted functions
|
||||
set(set&); // copy constructor
|
||||
set& operator=(set&); // assignment operator
|
||||
|
||||
};
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
inline void swap (
|
||||
set<T,mem_manager,compare>& a,
|
||||
set<T,mem_manager,compare>& b
|
||||
) { a.swap(b); }
|
||||
/*!
|
||||
provides a global swap function
|
||||
!*/
|
||||
|
||||
template <
|
||||
typename T,
|
||||
typename mem_manager,
|
||||
typename compare
|
||||
>
|
||||
void deserialize (
|
||||
set<T,mem_manager,compare>& item,
|
||||
std::istream& in
|
||||
);
|
||||
/*!
|
||||
provides deserialization support
|
||||
!*/
|
||||
}
|
||||
|
||||
#endif // DLIB_SET_KERNEl_ABSTRACT_
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SET_KERNEl_C_
|
||||
#define DLIB_SET_KERNEl_C_
|
||||
|
||||
#include "set_kernel_abstract.h"
|
||||
#include "../algs.h"
|
||||
#include "../assert.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
class set_kernel_c : public set_base
|
||||
{
|
||||
typedef typename set_base::type T;
|
||||
public:
|
||||
|
||||
void add (
|
||||
T& item
|
||||
);
|
||||
|
||||
void remove_any (
|
||||
T& item
|
||||
);
|
||||
|
||||
void remove (
|
||||
const T& item,
|
||||
T& item_copy
|
||||
);
|
||||
|
||||
void destroy (
|
||||
const T& item
|
||||
);
|
||||
|
||||
const T& element (
|
||||
);
|
||||
|
||||
const T& element (
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
inline void swap (
|
||||
set_kernel_c<set_base>& a,
|
||||
set_kernel_c<set_base>& b
|
||||
) { a.swap(b); }
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// member function definitions
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
void set_kernel_c<set_base>::
|
||||
add(
|
||||
T& item
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( !this->is_member(item),
|
||||
"\tvoid set::add"
|
||||
<< "\n\titem being added must not already be in the set"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
set_base::add(item);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
void set_kernel_c<set_base>::
|
||||
remove (
|
||||
const T& item,
|
||||
T& item_copy
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( this->is_member(item) &&
|
||||
(static_cast<const void*>(&item) != static_cast<void*>(&item_copy)),
|
||||
"\tvoid set::remove"
|
||||
<< "\n\titem should be in the set if it's going to be removed"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&item: " << &item
|
||||
<< "\n\t&item_copy: " << &item_copy
|
||||
<< "\n\tis_member(item): " << (this->is_member(item)?"true":"false")
|
||||
);
|
||||
|
||||
// call the real function
|
||||
set_base::remove(item,item_copy);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
void set_kernel_c<set_base>::
|
||||
destroy (
|
||||
const T& item
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( this->is_member(item),
|
||||
"\tvoid set::destroy"
|
||||
<< "\n\titem should be in the set if it's going to be removed"
|
||||
<< "\n\tthis: " << this
|
||||
<< "\n\t&item: " << &item
|
||||
);
|
||||
|
||||
// call the real function
|
||||
set_base::destroy(item);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
void set_kernel_c<set_base>::
|
||||
remove_any (
|
||||
T& item
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT( this->size() != 0,
|
||||
"\tvoid set::remove_any"
|
||||
<< "\n\tsize must be greater than zero if an item is to be removed"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
set_base::remove_any(item);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
const typename set_base::type& set_kernel_c<set_base>::
|
||||
element (
|
||||
) const
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tconst T& set::element() const"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return set_base::element();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename set_base
|
||||
>
|
||||
const typename set_base::type& set_kernel_c<set_base>::
|
||||
element (
|
||||
)
|
||||
{
|
||||
// make sure requires clause is not broken
|
||||
DLIB_CASSERT(this->current_element_valid() == true,
|
||||
"\tconst T& set::element"
|
||||
<< "\n\tyou can't access the current element if it doesn't exist"
|
||||
<< "\n\tthis: " << this
|
||||
);
|
||||
|
||||
// call the real function
|
||||
return set_base::element();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_SET_KERNEl_C_
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_SLIDING_BUFFEr_
|
||||
#define DLIB_SLIDING_BUFFEr_
|
||||
|
||||
|
||||
#include "sliding_buffer/sliding_buffer_kernel_1.h"
|
||||
#include "sliding_buffer/sliding_buffer_kernel_c.h"
|
||||
#include "sliding_buffer/circular_buffer.h"
|
||||
|
||||
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
template <
|
||||
typename T
|
||||
>
|
||||
class sliding_buffer
|
||||
{
|
||||
|
||||
sliding_buffer() {}
|
||||
public:
|
||||
|
||||
//----------- kernels ---------------
|
||||
|
||||
// kernel_1a
|
||||
typedef sliding_buffer_kernel_1<T>
|
||||
kernel_1a;
|
||||
typedef sliding_buffer_kernel_c<kernel_1a>
|
||||
kernel_1a_c;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DLIB_SLIDING_BUFFEr_
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user