// 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 == trueCONVENTION- 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 interfaceinline 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 memberssize_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 brokenDLIB_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 brokenDLIB_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 brokenDLIB_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;elselast_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 differentif (max != max_array_size){if (array_elements){pool.deallocate_array(array_elements);}// try to get more memroytry { 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 zeroelse{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 brokenDLIB_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 brokenDLIB_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.hdlib::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 brokenDLIB_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 brokenDLIB_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 brokenDLIB_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 brokenDLIB_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 arrayarray 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_
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。