diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 13:19:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-03-09 13:20:02 +0000 |
commit | 58daab21cd043e1dc37024a7f99b396788372918 (patch) | |
tree | 96771e43bb69f7c1c2b0b4f7374cb74d7866d0cb /ml/dlib/dlib/matrix/matrix_data_layout.h | |
parent | Releasing debian version 1.43.2-1. (diff) | |
download | netdata-58daab21cd043e1dc37024a7f99b396788372918.tar.xz netdata-58daab21cd043e1dc37024a7f99b396788372918.zip |
Merging upstream version 1.44.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ml/dlib/dlib/matrix/matrix_data_layout.h')
-rw-r--r-- | ml/dlib/dlib/matrix/matrix_data_layout.h | 1271 |
1 files changed, 1271 insertions, 0 deletions
diff --git a/ml/dlib/dlib/matrix/matrix_data_layout.h b/ml/dlib/dlib/matrix/matrix_data_layout.h new file mode 100644 index 000000000..22891c228 --- /dev/null +++ b/ml/dlib/dlib/matrix/matrix_data_layout.h @@ -0,0 +1,1271 @@ +// Copyright (C) 2006 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_MATRIx_DATA_LAYOUT_ +#define DLIB_MATRIx_DATA_LAYOUT_ + +#include "../algs.h" +#include "matrix_fwd.h" +#include "matrix_data_layout_abstract.h" +#ifdef MATLAB_MEX_FILE +#include <mex.h> +#endif + +// GCC 4.8 gives false alarms about some matrix operations going out of bounds. Disable +// these false warnings. +#if defined(__GNUC__) && ((__GNUC__ >= 4 && __GNUC_MINOR__ >= 8) || (__GNUC__ > 4)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif + +namespace dlib +{ + +// ---------------------------------------------------------------------------------------- + + /*! + A matrix layout object is any object that contains a templated class called "layout" + with an interface identical to one below: + (Note that all the template arguments are just the template arguments from the dlib::matrix + object and the member functions are defined identically to the ones with the same + signatures inside the matrix object.) + + struct matrix_layout + { + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout + { + public: + + T& operator() ( + long r, + long c + ); + + const T& operator() ( + long r, + long c + ); + + T& operator() ( + long i + ); + + const T& operator() ( + long i + ) const; + + void swap( + layout& item + ); + + long nr ( + ) const; + + long nc ( + ) const; + + void set_size ( + long nr_, + long nc_ + ); + }; + }; + !*/ + +// ---------------------------------------------------------------------------------------- + + struct row_major_layout + { + // if a matrix is bigger than this many bytes then don't put it on the stack + const static size_t max_stack_based_size = 256; + + // this is a hack to avoid a compile time error in visual studio 8. I would just + // use sizeof(T) and be done with it but that won't compile. The idea here + // is to avoid using the stack allocation of the layout object if it + // is going to contain another matrix and also avoid asking for the sizeof() + // the contained matrix. + template <typename T> + struct get_sizeof_helper + { + const static std::size_t val = sizeof(T); + }; + + template <typename T, long NR, long NC, typename mm, typename l> + struct get_sizeof_helper<matrix<T,NR,NC,mm,l> > + { + const static std::size_t val = 1000000; + }; + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager, + int val = static_switch < + // when the sizes are all non zero and small + (num_rows*num_cols*get_sizeof_helper<T>::val <= max_stack_based_size) && (num_rows != 0 && num_cols != 0), + // when the sizes are all non zero and big + (num_rows*num_cols*get_sizeof_helper<T>::val > max_stack_based_size) && (num_rows != 0 && num_cols != 0), + num_rows == 0 && num_cols != 0, + num_rows != 0 && num_cols == 0, + num_rows == 0 && num_cols == 0 + >::value + > + class layout ; + /*! + WHAT THIS OBJECT REPRESENTS + This object represents the actual allocation of space for a matrix. + Small matrices allocate all their data on the stack and bigger ones + use a memory_manager to get their memory. + !*/ + + // ------------------------------------------------------------------------------------ + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout<T,num_rows,num_cols,mem_manager,1> : noncopyable // when the sizes are all non zero and small + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout() {} + + T& operator() ( + long r, + long c + ) { return *(data+r*num_cols + c); } + + const T& operator() ( + long r, + long c + ) const { return *(data+r*num_cols + c); } + + T& operator() ( + long i + ) { return data[i]; } + + const T& operator() ( + long i + ) const { return data[i]; } + + void swap( + layout& item + ) + { + for (long r = 0; r < num_rows; ++r) + { + for (long c = 0; c < num_cols; ++c) + { + exchange((*this)(r,c),item(r,c)); + } + } + } + + long nr ( + ) const { return num_rows; } + + long nc ( + ) const { return num_cols; } + + void set_size ( + long , + long + ) + { + } + +#ifdef MATLAB_MEX_FILE + void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); } + mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); } + void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); } + bool _private_is_owned_by_matlab() const { return false; } +#endif + + private: + T data[num_rows*num_cols]; + }; + + // ------------------------------------------------------------------------------------ + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout<T,num_rows,num_cols,mem_manager,2> : noncopyable // when the sizes are all non zero and big + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout ( + ) { data = pool.allocate_array(num_rows*num_cols); } + + ~layout () + { pool.deallocate_array(data); } + + T& operator() ( + long r, + long c + ) { return data[r*num_cols + c]; } + + const T& operator() ( + long r, + long c + ) const { return data[r*num_cols + c]; } + + T& operator() ( + long i + ) { return data[i]; } + + const T& operator() ( + long i + ) const { return data[i]; } + + void swap( + layout& item + ) + { + std::swap(item.data,data); + pool.swap(item.pool); + } + + long nr ( + ) const { return num_rows; } + + long nc ( + ) const { return num_cols; } + + void set_size ( + long , + long + ) + { + } + +#ifdef MATLAB_MEX_FILE + void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); } + mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); } + void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); } + bool _private_is_owned_by_matlab() const { return false; } +#endif + + private: + + T* data; + typename mem_manager::template rebind<T>::other pool; + }; + + // ------------------------------------------------------------------------------------ + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout<T,num_rows,num_cols,mem_manager,3> : noncopyable // when num_rows == 0 && num_cols != 0, + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout ( + ):data(0), nr_(0) { } + + ~layout () + { + if (data) + pool.deallocate_array(data); + } + + T& operator() ( + long r, + long c + ) { return data[r*num_cols + c]; } + + const T& operator() ( + long r, + long c + ) const { return data[r*num_cols + c]; } + + T& operator() ( + long i + ) { return data[i]; } + + const T& operator() ( + long i + ) const { return data[i]; } + + void swap( + layout& item + ) + { + std::swap(item.data,data); + std::swap(item.nr_,nr_); + pool.swap(item.pool); + } + + long nr ( + ) const { return nr_; } + + long nc ( + ) const { return num_cols; } + + void set_size ( + long nr, + long nc + ) + { + if (data) + { + pool.deallocate_array(data); + } + data = pool.allocate_array(nr*nc); + nr_ = nr; + } + +#ifdef MATLAB_MEX_FILE + void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); } + mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); } + void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); } + bool _private_is_owned_by_matlab() const { return false; } +#endif + + private: + + T* data; + long nr_; + typename mem_manager::template rebind<T>::other pool; + }; + + // ------------------------------------------------------------------------------------ + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout<T,num_rows,num_cols,mem_manager,4> : noncopyable // when num_rows != 0 && num_cols == 0 + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout ( + ):data(0), nc_(0) { } + + ~layout () + { + if (data) + { + pool.deallocate_array(data); + } + } + + T& operator() ( + long r, + long c + ) { return data[r*nc_ + c]; } + + const T& operator() ( + long r, + long c + ) const { return data[r*nc_ + c]; } + + T& operator() ( + long i + ) { return data[i]; } + + const T& operator() ( + long i + ) const { return data[i]; } + + void swap( + layout& item + ) + { + std::swap(item.data,data); + std::swap(item.nc_,nc_); + pool.swap(item.pool); + } + + long nr ( + ) const { return num_rows; } + + long nc ( + ) const { return nc_; } + + void set_size ( + long nr, + long nc + ) + { + if (data) + { + pool.deallocate_array(data); + } + data = pool.allocate_array(nr*nc); + nc_ = nc; + } + +#ifdef MATLAB_MEX_FILE + void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); } + mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); } + void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); } + bool _private_is_owned_by_matlab() const { return false; } +#endif + + private: + + T* data; + long nc_; + typename mem_manager::template rebind<T>::other pool; + }; + + // ------------------------------------------------------------------------------------ + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout<T,num_rows,num_cols,mem_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0 + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout ( + ):data(0), nr_(0), nc_(0) { } + + ~layout () + { + if (data) + { + pool.deallocate_array(data); + } + } + + T& operator() ( + long r, + long c + ) { return data[r*nc_ + c]; } + + const T& operator() ( + long r, + long c + ) const { return data[r*nc_ + c]; } + + T& operator() ( + long i + ) { return data[i]; } + + const T& operator() ( + long i + ) const { return data[i]; } + + void swap( + layout& item + ) + { + std::swap(item.data,data); + std::swap(item.nc_,nc_); + std::swap(item.nr_,nr_); + pool.swap(item.pool); + } + + long nr ( + ) const { return nr_; } + + long nc ( + ) const { return nc_; } + + void set_size ( + long nr, + long nc + ) + { + if (data) + { + pool.deallocate_array(data); + } + data = pool.allocate_array(nr*nc); + nr_ = nr; + nc_ = nc; + } + +#ifdef MATLAB_MEX_FILE + void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); } + mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); } + void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); } + bool _private_is_owned_by_matlab() const { return false; } +#endif + private: + T* data; + long nr_; + long nc_; + typename mem_manager::template rebind<T>::other pool; + }; + + }; + +// ---------------------------------------------------------------------------------------- + + struct column_major_layout + { + // if a matrix is bigger than this many bytes then don't put it on the stack + const static size_t max_stack_based_size = 256; + + + // this is a hack to avoid a compile time error in visual studio 8. I would just + // use sizeof(T) and be done with it but that won't compile. The idea here + // is to avoid using the stack allocation of the layout object if it + // is going to contain another matrix and also avoid asking for the sizeof() + // the contained matrix. + template <typename T> + struct get_sizeof_helper + { + const static std::size_t val = sizeof(T); + }; + + template <typename T, long NR, long NC, typename mm, typename l> + struct get_sizeof_helper<matrix<T,NR,NC,mm,l> > + { + const static std::size_t val = 1000000; + }; + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager, + int val = static_switch < + // when the sizes are all non zero and small + (num_rows*num_cols*get_sizeof_helper<T>::val <= max_stack_based_size) && (num_rows != 0 && num_cols != 0), + // when the sizes are all non zero and big + (num_rows*num_cols*get_sizeof_helper<T>::val > max_stack_based_size) && (num_rows != 0 && num_cols != 0), + num_rows == 0 && num_cols != 0, + num_rows != 0 && num_cols == 0, + num_rows == 0 && num_cols == 0 + >::value + > + class layout ; + /*! + WHAT THIS OBJECT REPRESENTS + This object represents the actual allocation of space for a matrix. + Small matrices allocate all their data on the stack and bigger ones + use a memory_manager to get their memory. + !*/ + + // ------------------------------------------------------------------------------------ + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout<T,num_rows,num_cols,mem_manager,1> : noncopyable // when the sizes are all non zero and small + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout() {} + + T& operator() ( + long r, + long c + ) { return *(data+c*num_rows + r); } + + const T& operator() ( + long r, + long c + ) const { return *(data+c*num_rows + r); } + + T& operator() ( + long i + ) { return data[i]; } + + const T& operator() ( + long i + ) const { return data[i]; } + + void swap( + layout& item + ) + { + for (long r = 0; r < num_rows; ++r) + { + for (long c = 0; c < num_cols; ++c) + { + exchange((*this)(r,c),item(r,c)); + } + } + } + + long nr ( + ) const { return num_rows; } + + long nc ( + ) const { return num_cols; } + + void set_size ( + long, + long + ) + { + } + +#ifdef MATLAB_MEX_FILE + void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); } + mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); } + void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); } + bool _private_is_owned_by_matlab() const { return false; } +#endif + + private: + T data[num_cols*num_rows]; + }; + + // ------------------------------------------------------------------------------------ + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout<T,num_rows,num_cols,mem_manager,2> : noncopyable // when the sizes are all non zero and big + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout ( + ) { data = pool.allocate_array(num_rows*num_cols); } + + ~layout () + { pool.deallocate_array(data); } + + T& operator() ( + long r, + long c + ) { return data[c*num_rows + r]; } + + const T& operator() ( + long r, + long c + ) const { return data[c*num_rows + r]; } + + T& operator() ( + long i + ) { return data[i]; } + + const T& operator() ( + long i + ) const { return data[i]; } + + void swap( + layout& item + ) + { + std::swap(item.data,data); + pool.swap(item.pool); + } + + long nr ( + ) const { return num_rows; } + + long nc ( + ) const { return num_cols; } + + void set_size ( + long , + long + ) + { + } + +#ifdef MATLAB_MEX_FILE + void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); } + mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); } + void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); } + bool _private_is_owned_by_matlab() const { return false; } +#endif + + private: + + T* data; + typename mem_manager::template rebind<T>::other pool; + }; + + // ------------------------------------------------------------------------------------ + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout<T,num_rows,num_cols,mem_manager,3> : noncopyable // when num_rows == 0 && num_cols != 0, + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout ( + ):data(0), nr_(0) { } + + ~layout () + { + if (data) + pool.deallocate_array(data); + } + + T& operator() ( + long r, + long c + ) { return data[c*nr_ + r]; } + + const T& operator() ( + long r, + long c + ) const { return data[c*nr_ + r]; } + + T& operator() ( + long i + ) { return data[i]; } + + const T& operator() ( + long i + ) const { return data[i]; } + + void swap( + layout& item + ) + { + std::swap(item.data,data); + std::swap(item.nr_,nr_); + pool.swap(item.pool); + } + + long nr ( + ) const { return nr_; } + + long nc ( + ) const { return num_cols; } + + void set_size ( + long nr, + long nc + ) + { + if (data) + { + pool.deallocate_array(data); + } + data = pool.allocate_array(nr*nc); + nr_ = nr; + } + +#ifdef MATLAB_MEX_FILE + void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); } + mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); } + void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); } + bool _private_is_owned_by_matlab() const { return false; } +#endif + + private: + + T* data; + long nr_; + typename mem_manager::template rebind<T>::other pool; + }; + + // ------------------------------------------------------------------------------------ + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout<T,num_rows,num_cols,mem_manager,4> : noncopyable // when num_rows != 0 && num_cols == 0 + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout ( + ):data(0), nc_(0) { } + + ~layout () + { + if (data) + { + pool.deallocate_array(data); + } + } + + T& operator() ( + long r, + long c + ) { return data[c*num_rows + r]; } + + const T& operator() ( + long r, + long c + ) const { return data[c*num_rows + r]; } + + T& operator() ( + long i + ) { return data[i]; } + + const T& operator() ( + long i + ) const { return data[i]; } + + void swap( + layout& item + ) + { + std::swap(item.data,data); + std::swap(item.nc_,nc_); + pool.swap(item.pool); + } + + long nr ( + ) const { return num_rows; } + + long nc ( + ) const { return nc_; } + + void set_size ( + long nr, + long nc + ) + { + if (data) + { + pool.deallocate_array(data); + } + data = pool.allocate_array(nr*nc); + nc_ = nc; + } + +#ifdef MATLAB_MEX_FILE + void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); } + mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); } + void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); } + bool _private_is_owned_by_matlab() const { return false; } +#endif + + private: + + T* data; + long nc_; + typename mem_manager::template rebind<T>::other pool; + }; + + // ------------------------------------------------------------------------------------ + + template < + typename T, + long num_rows, + long num_cols, + typename mem_manager + > + class layout<T,num_rows,num_cols,mem_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0 + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout ( + ):data(0), nr_(0), nc_(0) { } + + ~layout () + { + if (data) + { + pool.deallocate_array(data); + } + } + + T& operator() ( + long r, + long c + ) { return data[c*nr_ + r]; } + + const T& operator() ( + long r, + long c + ) const { return data[c*nr_ + r]; } + + T& operator() ( + long i + ) { return data[i]; } + + const T& operator() ( + long i + ) const { return data[i]; } + + void swap( + layout& item + ) + { + std::swap(item.data,data); + std::swap(item.nc_,nc_); + std::swap(item.nr_,nr_); + pool.swap(item.pool); + } + +#ifdef MATLAB_MEX_FILE + void _private_set_mxArray ( mxArray* ) { DLIB_CASSERT(false, "This function should never be called."); } + mxArray* _private_release_mxArray(){DLIB_CASSERT(false, "This function should never be called."); } + void _private_mark_owned_by_matlab() {DLIB_CASSERT(false, "This function should never be called."); } + bool _private_is_owned_by_matlab() const { return false; } +#endif + + long nr ( + ) const { return nr_; } + + long nc ( + ) const { return nc_; } + + void set_size ( + long nr, + long nc + ) + { + if (data) + { + pool.deallocate_array(data); + } + data = pool.allocate_array(nr*nc); + nr_ = nr; + nc_ = nc; + } + + private: + T* data; + long nr_; + long nc_; + typename mem_manager::template rebind<T>::other pool; + }; + +#ifdef MATLAB_MEX_FILE + template < + long num_rows, + long num_cols + > + class layout<double,num_rows,num_cols,default_memory_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0 + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout ( + ): data(0), nr_(0), nc_(0), owned_by_matlab(false),set_by_private_set_mxArray(false),mem(0) { } + + ~layout () + { + if (owned_by_matlab) + { + if (!set_by_private_set_mxArray && mem) + { + mxDestroyArray(mem); + mem = 0; + data = 0; + } + } + else if (data) + { + delete [] data; + data = 0; + } + } + + double& operator() ( + long r, + long c + ) { return data[c*nr_ + r]; } + + const double& operator() ( + long r, + long c + ) const { return data[c*nr_ + r]; } + + double& operator() ( + long i + ) { return data[i]; } + + const double& operator() ( + long i + ) const { return data[i]; } + + void _private_set_mxArray ( + mxArray* mem_ + ) + { + DLIB_CASSERT(mem == 0 && data == 0,"You can't call this function on an already allocated matrix."); + // We don't own the pointer, so make note of that so we won't try to free + // it. + set_by_private_set_mxArray = true; + owned_by_matlab = true; + mem = mem_; + data = mxGetPr(mem); + nr_ = mxGetM(mem); + nc_ = mxGetN(mem); + } + + mxArray* _private_release_mxArray() + { + DLIB_CASSERT(owned_by_matlab,""); + mxArray* temp = mem; + mem = 0; + set_by_private_set_mxArray = false; + data = 0; + nr_ = 0; + nc_ = 0; + return temp; + } + + void _private_mark_owned_by_matlab() + { + DLIB_CASSERT(mem == 0 && data == 0,"You can't say a matrix should be owned by matlab after it's been allocated."); + owned_by_matlab = true; + } + bool _private_is_owned_by_matlab() const + { + return owned_by_matlab; + } + + void swap( + layout& item + ) + { + std::swap(item.owned_by_matlab,owned_by_matlab); + std::swap(item.set_by_private_set_mxArray,set_by_private_set_mxArray); + std::swap(item.mem,mem); + std::swap(item.data,data); + std::swap(item.nc_,nc_); + std::swap(item.nr_,nr_); + } + + long nr ( + ) const { return nr_; } + + long nc ( + ) const { return nc_; } + + void set_size ( + long nr, + long nc + ) + { + if (owned_by_matlab) + { + if (!set_by_private_set_mxArray && mem) + { + mxDestroyArray(mem); + mem = 0; + data = 0; + } + set_by_private_set_mxArray = false; + + mem = mxCreateDoubleMatrix(nr, nc, mxREAL); + if (mem == 0) + throw std::bad_alloc(); + data = mxGetPr(mem); + } + else + { + if (data) + delete [] data; + data = new double[nr*nc]; + } + nr_ = nr; + nc_ = nc; + } + + private: + double* data; + long nr_; + long nc_; + bool owned_by_matlab; + bool set_by_private_set_mxArray; + mxArray* mem; + }; + + template < + long num_rows, + long num_cols + > + class layout<float,num_rows,num_cols,default_memory_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0 + { + public: + const static long NR = num_rows; + const static long NC = num_cols; + + layout ( + ): data(0), nr_(0), nc_(0), owned_by_matlab(false),set_by_private_set_mxArray(false),mem(0) { } + + ~layout () + { + if (owned_by_matlab) + { + if (!set_by_private_set_mxArray && mem) + { + mxDestroyArray(mem); + mem = 0; + data = 0; + } + } + else if (data) + { + delete [] data; + data = 0; + } + } + + float& operator() ( + long r, + long c + ) { return data[c*nr_ + r]; } + + const float& operator() ( + long r, + long c + ) const { return data[c*nr_ + r]; } + + float& operator() ( + long i + ) { return data[i]; } + + const float& operator() ( + long i + ) const { return data[i]; } + + void _private_set_mxArray ( + mxArray* mem_ + ) + { + DLIB_CASSERT(mem == 0 && data == 0,"You can't call this function on an already allocated matrix."); + // We don't own the pointer, so make note of that so we won't try to free + // it. + set_by_private_set_mxArray = true; + owned_by_matlab = true; + mem = mem_; + data = (float*)mxGetData(mem); + nr_ = mxGetM(mem); + nc_ = mxGetN(mem); + } + + mxArray* _private_release_mxArray() + { + DLIB_CASSERT(owned_by_matlab,""); + mxArray* temp = mem; + mem = 0; + set_by_private_set_mxArray = false; + data = 0; + nr_ = 0; + nc_ = 0; + return temp; + } + + void _private_mark_owned_by_matlab() + { + DLIB_CASSERT(mem == 0 && data == 0,"You can't say a matrix should be owned by matlab after it's been allocated."); + owned_by_matlab = true; + } + bool _private_is_owned_by_matlab() const + { + return owned_by_matlab; + } + + void swap( + layout& item + ) + { + std::swap(item.owned_by_matlab,owned_by_matlab); + std::swap(item.set_by_private_set_mxArray,set_by_private_set_mxArray); + std::swap(item.mem,mem); + std::swap(item.data,data); + std::swap(item.nc_,nc_); + std::swap(item.nr_,nr_); + } + + long nr ( + ) const { return nr_; } + + long nc ( + ) const { return nc_; } + + void set_size ( + long nr, + long nc + ) + { + if (owned_by_matlab) + { + if (!set_by_private_set_mxArray && mem) + { + mxDestroyArray(mem); + mem = 0; + data = 0; + } + set_by_private_set_mxArray = false; + + mem = mxCreateNumericMatrix(nr, nc, mxSINGLE_CLASS, mxREAL); + if (mem == 0) + throw std::bad_alloc(); + data = (float*)mxGetData(mem); + } + else + { + if (data) + delete [] data; + data = new float[nr*nc]; + } + nr_ = nr; + nc_ = nc; + } + + private: + float* data; + long nr_; + long nc_; + bool owned_by_matlab; + bool set_by_private_set_mxArray; + mxArray* mem; + }; +#endif + + }; + +// ---------------------------------------------------------------------------------------- + +} + +#if defined(__GNUC__) && ((__GNUC__ >= 4 && __GNUC_MINOR__ >= 8) || (__GNUC__ > 4)) +#pragma GCC diagnostic pop +#endif + +#endif // DLIB_MATRIx_DATA_LAYOUT_ + |