summaryrefslogtreecommitdiffstats
path: root/src/ml/dlib/dlib/array
diff options
context:
space:
mode:
Diffstat (limited to 'src/ml/dlib/dlib/array')
-rw-r--r--src/ml/dlib/dlib/array/array_kernel.h810
-rw-r--r--src/ml/dlib/dlib/array/array_kernel_abstract.h360
-rw-r--r--src/ml/dlib/dlib/array/array_tools.h38
-rw-r--r--src/ml/dlib/dlib/array/array_tools_abstract.h33
4 files changed, 1241 insertions, 0 deletions
diff --git a/src/ml/dlib/dlib/array/array_kernel.h b/src/ml/dlib/dlib/array/array_kernel.h
new file mode 100644
index 000000000..48160941b
--- /dev/null
+++ b/src/ml/dlib/dlib/array/array_kernel.h
@@ -0,0 +1,810 @@
+// 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(
+ 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;
+
+ // restricted functions
+ array(array<T>&); // copy constructor
+ array<T>& operator=(array<T>&); // assignment operator
+
+ };
+
+ 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_
+
diff --git a/src/ml/dlib/dlib/array/array_kernel_abstract.h b/src/ml/dlib/dlib/array/array_kernel_abstract.h
new file mode 100644
index 000000000..5cfdd483a
--- /dev/null
+++ b/src/ml/dlib/dlib/array/array_kernel_abstract.h
@@ -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_
+
diff --git a/src/ml/dlib/dlib/array/array_tools.h b/src/ml/dlib/dlib/array/array_tools.h
new file mode 100644
index 000000000..fce634396
--- /dev/null
+++ b/src/ml/dlib/dlib/array/array_tools.h
@@ -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_
+
diff --git a/src/ml/dlib/dlib/array/array_tools_abstract.h b/src/ml/dlib/dlib/array/array_tools_abstract.h
new file mode 100644
index 000000000..e9b957518
--- /dev/null
+++ b/src/ml/dlib/dlib/array/array_tools_abstract.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_
+