summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/matrix/matrix_data_layout.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:19:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:20:02 +0000
commit58daab21cd043e1dc37024a7f99b396788372918 (patch)
tree96771e43bb69f7c1c2b0b4f7374cb74d7866d0cb /ml/dlib/dlib/matrix/matrix_data_layout.h
parentReleasing debian version 1.43.2-1. (diff)
downloadnetdata-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.h1271
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_
+