mirror of
https://github.com/nasa/trick.git
synced 2024-12-29 17:38:54 +00:00
798 lines
22 KiB
C++
798 lines
22 KiB
C++
/**
|
|
* @if Er7UtilsUseGroups
|
|
* @addtogroup Er7Utils
|
|
* @{
|
|
* @addtogroup Interface
|
|
* @{
|
|
* @endif
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* Defines memory management macros and template functions.
|
|
*
|
|
* This file comprises multiple parts:
|
|
* - Declaration of a name demangler function, if available.
|
|
* - Low level, Trick-specific memory management template functions.
|
|
* - Implementation-specific definitions of set of memory management macros.
|
|
* While these macros are defined in implementation-specific manner,
|
|
* the arguments and products are implementation independent.
|
|
* - High-level memory management template functions that are implemented
|
|
* in terms of those four macros. These templates obviate the need
|
|
* for using those macros outside of this file.
|
|
* The ER7 utilities code should use the high level interfaces rather
|
|
* than the memory management macros.
|
|
*/
|
|
|
|
/*
|
|
Purpose: ()
|
|
*/
|
|
|
|
|
|
#ifndef ER7_UTILS_ALLOC_HH
|
|
#define ER7_UTILS_ALLOC_HH
|
|
|
|
// SWIG gets utterly confused by this.
|
|
#ifndef SWIG
|
|
|
|
// Interface includes
|
|
#include "config.hh"
|
|
|
|
// System includes
|
|
#include <cstddef>
|
|
#include <cstring>
|
|
#include <string>
|
|
#include <new>
|
|
|
|
#ifdef ER7_UTILS_HAVE_ABI
|
|
#include <typeinfo>
|
|
#endif
|
|
|
|
|
|
// Declare er7_utils::alloc.
|
|
namespace er7_utils {
|
|
|
|
/**
|
|
* Contains free functions that pertain to initialization (setting to NULL),
|
|
* allocating memory, and releasing allocated memory.
|
|
*/
|
|
namespace alloc {
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
// The macros below need a demangle function, if available.
|
|
|
|
|
|
#ifdef ER7_UTILS_HAVE_ABI
|
|
namespace er7_utils {
|
|
namespace alloc {
|
|
|
|
/**
|
|
* Demangle a type ID.
|
|
* @param info The type ID whose name is to be demangled.
|
|
* @return Demangled type name.
|
|
*/
|
|
const std::string demangle (const std::type_info & info);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
// Part one, allocation/deallocation macros.
|
|
|
|
/*
|
|
* Trick-based implementations of the four macros.
|
|
*/
|
|
#ifdef TRICK_VER
|
|
|
|
#include <new>
|
|
#include <string>
|
|
#include "sim_services/MemoryManager/include/memorymanager_c_intf.h"
|
|
#include "type_traits.hh"
|
|
|
|
|
|
namespace er7_utils {
|
|
|
|
/**
|
|
* Contains helper functions for the Trick-specific implementations
|
|
* of the ER7 utilities allocation macros.
|
|
*/
|
|
namespace trick_interface {
|
|
|
|
#ifdef ER7_UTILS_HAVE_ABI
|
|
/**
|
|
* Get the name of a type as a string.
|
|
* @tparam T Type whose name is to be retrieved.
|
|
* @return Demangled type name.
|
|
*/
|
|
template<typename T>
|
|
inline const std::string type_name (std::string) {
|
|
return alloc::demangle (typeid(T));
|
|
}
|
|
#else
|
|
/**
|
|
* Try to get the name of a type as a string.
|
|
* @tparam T Type whose name is to be retrieved.
|
|
* @return Type name.
|
|
*/
|
|
template<typename T>
|
|
inline const std::string type_name (std::string name_of_type) {
|
|
if (name_of_type.find("::") == 0) {
|
|
name_of_type.erase (0, 2);
|
|
}
|
|
else if ((name_of_type.find("Trick::") != 0) &&
|
|
(name_of_type.find("er7_utils::") != 0)) {
|
|
name_of_type.insert (0, "er7_utils::");
|
|
}
|
|
return name_of_type;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* Allocate an array of objects of the specified type.
|
|
* The returned array contains default-constructed objects.
|
|
* @tparam T Type of objects to be allocated.
|
|
* @param name_of_type Demangled name of the type.
|
|
* @param count Number of elements to be allocated.
|
|
* @return Array of allocated objects.
|
|
*/
|
|
template <typename T>
|
|
inline T * trick_alloc (
|
|
std::string name_of_type,
|
|
unsigned int count)
|
|
{
|
|
name_of_type = type_name<T> (name_of_type);
|
|
T * ptr = reinterpret_cast<T*> (
|
|
TMM_declare_var_1d (name_of_type.c_str(), count));
|
|
if (!ptr) {
|
|
throw std::bad_alloc();
|
|
}
|
|
return ptr;
|
|
}
|
|
|
|
/**
|
|
* Allocate an object of the specified type.
|
|
* The returned object is not constructed.
|
|
* @tparam T Type of the object to be allocated.
|
|
* @param name_of_type Demangled name of the type.
|
|
* @return Array of allocated objects.
|
|
*/
|
|
template <typename T>
|
|
inline T * alloc_object (std::string name_of_type) {
|
|
T * ptr = trick_alloc<T> (name_of_type, 1);
|
|
ptr->~T();
|
|
return ptr;
|
|
}
|
|
|
|
/**
|
|
* Destruct and deallocate a previously allocated object.
|
|
* @tparam T Type of the object to be deallocated.
|
|
* @param obj Object to be destructed, as a reference to a pointer.
|
|
*/
|
|
template <typename T>
|
|
inline void delete_object (T*& obj) {
|
|
if (obj) {
|
|
if (get_alloc_info_of(obj) != 0x0)
|
|
{
|
|
TMM_delete_var_a (type_traits::get_allocated_pointer (obj));
|
|
}
|
|
obj = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
// Part two, allocation/deallocation macros.
|
|
|
|
/*
|
|
* Trick-based implementations of the four allocation/deallocation macros.
|
|
* These use the er7_utils::trick_interface template functions defined above.
|
|
*/
|
|
#ifdef TRICK_VER
|
|
|
|
/**
|
|
* Allocate an array of some primitive type.
|
|
* @param size Size of the array to be allocated.
|
|
* @param type Type of the array.
|
|
*/
|
|
#define ER7_UTILS_ALLOC_PRIM_ARRAY(size,type) \
|
|
er7_utils::trick_interface::trick_alloc<type> (#type, size)
|
|
|
|
/**
|
|
* Allocate an object of some class type.
|
|
* @param type Type of the object.
|
|
* @param cotr Constructor arguments, in parentheses.
|
|
*/
|
|
#define ER7_UTILS_ALLOC_CLASS_OBJECT(type,cotr) \
|
|
new (er7_utils::trick_interface::alloc_object<type> (#type)) type cotr
|
|
|
|
/**
|
|
* Delete a previously allocated array.
|
|
* @param arr Array to be deleted.
|
|
*/
|
|
#define ER7_UTILS_DELETE_ARRAY(arr) \
|
|
er7_utils::trick_interface::delete_object (arr)
|
|
|
|
/**
|
|
* Delete a previously allocated instance of a class.
|
|
* @param obj Object to be deleted.
|
|
*/
|
|
#define ER7_UTILS_DELETE_OBJECT(obj) \
|
|
er7_utils::trick_interface::delete_object (obj)
|
|
|
|
|
|
/*
|
|
* JEOD-based implementations of the four macros.
|
|
* Note that the JEOD implementations come into play only in the case
|
|
* of a non-Trick implementation.
|
|
*/
|
|
#elif (defined JEOD)
|
|
|
|
#include "utils/memory/include/jeod_alloc.hh"
|
|
|
|
#define ER7_UTILS_ALLOC_PRIM_ARRAY(size,type) \
|
|
JEOD_ALLOC_PRIM_ARRAY (size, type)
|
|
|
|
#define ER7_UTILS_ALLOC_CLASS_OBJECT(type,cotr) \
|
|
JEOD_ALLOC_PRIM_ARRAY (type, cotr)
|
|
|
|
#define ER7_UTILS_DELETE_ARRAY(arr) \
|
|
JEOD_DELETE_ARRAY(arr)
|
|
|
|
#define ER7_UTILS_DELETE_OBJECT(obj) \
|
|
JEOD_DELETE_OBJECT(obj)
|
|
|
|
|
|
/*
|
|
* Generic implementations of the four macros.
|
|
* Note that the generic implementations come into play only in the case
|
|
* of a non-Trick, non-JEOD implementation.
|
|
*/
|
|
#else
|
|
namespace er7_utils {
|
|
namespace default_interface {
|
|
|
|
template <typename T>
|
|
inline T* allocate_array (std::size_t size) {
|
|
T* arr = new T[size];
|
|
std::memset (arr, 0, size*sizeof(T));
|
|
return arr;
|
|
}
|
|
|
|
template <typename T>
|
|
inline void delete_array (T*& obj) {
|
|
if (obj) {
|
|
delete[] obj;
|
|
obj = 0;
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
inline void delete_object (T*& obj) {
|
|
if (obj) {
|
|
delete obj;
|
|
obj = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#define ER7_UTILS_ALLOC_PRIM_ARRAY(size,type) \
|
|
er7_utils::default_interface::allocate_array<type> (size)
|
|
|
|
#define ER7_UTILS_ALLOC_CLASS_OBJECT(type,cotr) \
|
|
new type cotr
|
|
|
|
#define ER7_UTILS_DELETE_ARRAY(arr) \
|
|
er7_utils::default_interface::delete_array (arr)
|
|
|
|
#define ER7_UTILS_DELETE_OBJECT(obj) \
|
|
er7_utils::default_interface::delete_object (obj)
|
|
|
|
#endif
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
// Part three, allocation/deallocation template functions.
|
|
|
|
|
|
namespace er7_utils {
|
|
|
|
/**
|
|
* Contains free functions that pertain to initialization (setting to NULL),
|
|
* allocating memory, and releasing allocated memory.
|
|
*/
|
|
namespace alloc {
|
|
|
|
/**
|
|
* Allocate an object of some type using the default constructor.
|
|
* @tparam T Array type.
|
|
* @return Allocated object.
|
|
*/
|
|
template<typename T>
|
|
inline T * allocate_object ()
|
|
{
|
|
return ER7_UTILS_ALLOC_CLASS_OBJECT (T, ());
|
|
}
|
|
|
|
/**
|
|
* Allocate an object of some type using the copy constructor.
|
|
* @tparam T Array type.
|
|
* @param src Argument.
|
|
* @return Allocated object.
|
|
*/
|
|
template<typename T>
|
|
inline T * replicate_object (const T & src)
|
|
{
|
|
return ER7_UTILS_ALLOC_CLASS_OBJECT (T, (src));
|
|
}
|
|
|
|
/**
|
|
* Allocate an object of some type using a one argument constructor.
|
|
* @tparam T Array type.
|
|
* @tparam A1 Argument type.
|
|
* @param arg1 Argument.
|
|
* @return Allocated object.
|
|
*/
|
|
template<typename T, typename A1>
|
|
inline T * allocate_object (
|
|
A1 arg1)
|
|
{
|
|
return ER7_UTILS_ALLOC_CLASS_OBJECT (T, (arg1));
|
|
}
|
|
|
|
/**
|
|
* Allocate an object of some type using a two argument constructor.
|
|
* @tparam T Array type.
|
|
* @tparam A1 Argument 1 type.
|
|
* @tparam A2 Argument 2 type.
|
|
* @param arg1 Argument 1.
|
|
* @param arg2 Argument 2.
|
|
* @return Allocated object.
|
|
*/
|
|
template<typename T, typename A1, typename A2>
|
|
inline T * allocate_object (
|
|
A1 arg1,
|
|
A2 arg2)
|
|
{
|
|
return ER7_UTILS_ALLOC_CLASS_OBJECT (T, (arg1, arg2));
|
|
}
|
|
|
|
/**
|
|
* Allocate an object of some type using a three argument constructor.
|
|
* @tparam T Array type.
|
|
* @tparam A1 Argument 1 type.
|
|
* @tparam A2 Argument 2 type.
|
|
* @tparam A3 Argument 3 type.
|
|
* @param arg1 Argument 1.
|
|
* @param arg2 Argument 2.
|
|
* @param arg3 Argument 3.
|
|
* @return Allocated object.
|
|
*/
|
|
template<typename T, typename A1, typename A2, typename A3>
|
|
inline T * allocate_object (
|
|
A1 arg1,
|
|
A2 arg2,
|
|
A3 arg3)
|
|
{
|
|
return ER7_UTILS_ALLOC_CLASS_OBJECT (T, (arg1, arg2, arg3));
|
|
}
|
|
|
|
/**
|
|
* Allocate an object of some type using a four argument constructor.
|
|
* @tparam T Array type.
|
|
* @tparam A1 Argument 1 type.
|
|
* @tparam A2 Argument 2 type.
|
|
* @tparam A3 Argument 3 type.
|
|
* @tparam A4 Argument 4 type.
|
|
* @param arg1 Argument 1.
|
|
* @param arg2 Argument 2.
|
|
* @param arg3 Argument 3.
|
|
* @param arg4 Argument 4.
|
|
* @return Allocated object.
|
|
*/
|
|
template<typename T, typename A1, typename A2, typename A3, typename A4>
|
|
inline T * allocate_object (
|
|
A1 arg1,
|
|
A2 arg2,
|
|
A3 arg3,
|
|
A4 arg4)
|
|
{
|
|
return ER7_UTILS_ALLOC_CLASS_OBJECT (T, (arg1, arg2, arg3, arg4));
|
|
}
|
|
|
|
/**
|
|
* Allocate an object of some type using a five argument constructor.
|
|
* @tparam T Array type.
|
|
* @tparam A1 Argument 1 type.
|
|
* @tparam A2 Argument 2 type.
|
|
* @tparam A3 Argument 3 type.
|
|
* @tparam A4 Argument 4 type.
|
|
* @tparam A5 Argument 5 type.
|
|
* @param arg1 Argument 1.
|
|
* @param arg2 Argument 2.
|
|
* @param arg3 Argument 3.
|
|
* @param arg4 Argument 4.
|
|
* @param arg5 Argument 5.
|
|
* @return Allocated object.
|
|
*/
|
|
template<typename T,
|
|
typename A1,
|
|
typename A2,
|
|
typename A3,
|
|
typename A4,
|
|
typename A5>
|
|
inline T * allocate_object (
|
|
A1 arg1,
|
|
A2 arg2,
|
|
A3 arg3,
|
|
A4 arg4,
|
|
A5 arg5)
|
|
{
|
|
return ER7_UTILS_ALLOC_CLASS_OBJECT (
|
|
T, (arg1, arg2, arg3, arg4, arg5));
|
|
}
|
|
|
|
/**
|
|
* Allocate an object of some type using a six argument constructor.
|
|
* @tparam T Array type.
|
|
* @tparam A1 Argument 1 type.
|
|
* @tparam A2 Argument 2 type.
|
|
* @tparam A3 Argument 3 type.
|
|
* @tparam A4 Argument 4 type.
|
|
* @tparam A5 Argument 5 type.
|
|
* @tparam A6 Argument 6 type.
|
|
* @param arg1 Argument 1.
|
|
* @param arg2 Argument 2.
|
|
* @param arg3 Argument 3.
|
|
* @param arg4 Argument 4.
|
|
* @param arg5 Argument 5.
|
|
* @param arg6 Argument 6.
|
|
* @return Allocated object.
|
|
*/
|
|
template<typename T,
|
|
typename A1,
|
|
typename A2,
|
|
typename A3,
|
|
typename A4,
|
|
typename A5,
|
|
typename A6>
|
|
inline T * allocate_object (
|
|
A1 arg1,
|
|
A2 arg2,
|
|
A3 arg3,
|
|
A4 arg4,
|
|
A5 arg5,
|
|
A6 arg6)
|
|
{
|
|
return ER7_UTILS_ALLOC_CLASS_OBJECT (
|
|
T, (arg1, arg2, arg3, arg4, arg5, arg6));
|
|
}
|
|
|
|
|
|
/**
|
|
* Delete (and destruct) an instance of some class.
|
|
* @tparam T Object class.
|
|
* @param obj The object to be deleted.
|
|
*/
|
|
template<typename T>
|
|
inline void delete_object (
|
|
T *& obj)
|
|
{
|
|
ER7_UTILS_DELETE_OBJECT (obj);
|
|
}
|
|
|
|
|
|
/**
|
|
* Allocate an array of some primitive type.
|
|
* Note that because none of the arguments involve the type T,
|
|
* invocations of the function template must always specify T.
|
|
* @tparam T Array type.
|
|
* @param size Number of elements to allocate, assumed to be positive.
|
|
* @return Allocated array.
|
|
*/
|
|
template<typename T>
|
|
inline T * allocate_array (unsigned int size)
|
|
{
|
|
return ER7_UTILS_ALLOC_PRIM_ARRAY (size, T);
|
|
}
|
|
|
|
/**
|
|
* Non-template specialization of allocate_array for double.
|
|
* Note that since this is not a function template, calling
|
|
* allocate_array without a template argument will always resolve
|
|
* to this function.
|
|
* @param size Number of elements to allocate, assumed to be positive.
|
|
* @return Allocated array.
|
|
*/
|
|
inline double * allocate_array (unsigned int size)
|
|
{
|
|
return ER7_UTILS_ALLOC_PRIM_ARRAY (size, double);
|
|
}
|
|
|
|
|
|
/**
|
|
* Replicate an array of some primitive type
|
|
* @tparam T Array type.
|
|
* @param size Number of elements to allocate, assumed to be positive.
|
|
* @param src Array to be replicated.
|
|
* @return Allocated array.
|
|
*/
|
|
template<typename T>
|
|
inline T * replicate_array (unsigned int size, const T* src)
|
|
{
|
|
T* result = ER7_UTILS_ALLOC_PRIM_ARRAY (size, T);
|
|
for (unsigned int ii = 0; ii < size; ++ii) {
|
|
result[ii] = src[ii];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* Deallocate an array of some primitive type
|
|
* @tparam T Array type.
|
|
* @param arr Array to be deallocated.
|
|
*/
|
|
template<typename T>
|
|
inline void deallocate_array (T *& arr)
|
|
{
|
|
ER7_UTILS_DELETE_ARRAY (arr);
|
|
}
|
|
|
|
|
|
/**
|
|
* Zero out an array of items
|
|
* @param[in] size Array size
|
|
* @param[out] arr Array to zero
|
|
*/
|
|
template<typename T>
|
|
inline void initialize_array (
|
|
unsigned int size,
|
|
T * arr)
|
|
{
|
|
std::memset (arr, 0, size*sizeof(T));
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Initialize (zero-out) a 2D array.
|
|
* @tparam T Array type
|
|
* @tparam M Array outer dimension
|
|
* @param[out] arr Array to be initialized
|
|
*/
|
|
template<typename T, unsigned int M>
|
|
inline void initialize_2D_array (
|
|
T * arr[M])
|
|
{
|
|
initialize_array<T*> (M, arr);
|
|
}
|
|
|
|
/**
|
|
* Specialization of initialize_2D_array for double.
|
|
* @tparam M Array outer dimension
|
|
* @param[out] arr Array to be initialized
|
|
*/
|
|
template<unsigned int M>
|
|
inline void initialize_2D_array (
|
|
double * arr[M])
|
|
{
|
|
initialize_array<double*> (M, arr);
|
|
}
|
|
|
|
|
|
/**
|
|
* Allocate contents of a 2D array, where the array is declared as
|
|
* @code T * array[M] @endcode
|
|
* @tparam T Array type
|
|
* @tparam M Array outer dimension
|
|
* @param[in] size Array inner dimension
|
|
* @param[out] arr Array to be allocated
|
|
*/
|
|
template<typename T, unsigned int M>
|
|
inline void allocate_2D_array (
|
|
unsigned int size,
|
|
T * arr[M])
|
|
{
|
|
arr[0] = allocate_array<T> (size*M);
|
|
for (unsigned int ii = 1; ii < M; ++ii) {
|
|
arr[ii] = arr[ii-1] + size;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Specialization of allocate_2D_array for double.
|
|
* @tparam M Array outer dimension
|
|
* @param[in] size Array inner dimension
|
|
* @param[out] arr Array to be allocated
|
|
*/
|
|
template<unsigned int M>
|
|
inline void allocate_2D_array (
|
|
unsigned int size,
|
|
double * arr[M])
|
|
{
|
|
arr[0] = allocate_array<double> (size*M);
|
|
for (unsigned int ii = 1; ii < M; ++ii) {
|
|
arr[ii] = arr[ii-1] + size;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Allocate contents of a 2D array, where the array is declared as
|
|
* @code T ** array @endcode
|
|
* @tparam T Array type
|
|
* @param outer Array outer dimension
|
|
* @param inner Array inner dimension
|
|
* @return Allocated 2D array.
|
|
*/
|
|
template<typename T>
|
|
inline T** allocate_2D_array (
|
|
unsigned int outer,
|
|
unsigned int inner)
|
|
{
|
|
T** arr = allocate_array<T*> (outer);
|
|
arr[0] = allocate_array<T> (inner*outer);
|
|
for (unsigned int ii = 1; ii < outer; ++ii) {
|
|
arr[ii] = arr[ii-1] + inner;
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
|
|
/**
|
|
* Replicate contents of a 2D array, where the array is declared as
|
|
* @code T * array[M] @endcode
|
|
* @tparam T Array type
|
|
* @tparam M Array outer dimension
|
|
* @param[in] size Array inner dimension
|
|
* @param[in] src Source 2D array
|
|
* @param[out] tgt Array to be allocated and populated
|
|
*/
|
|
template<typename T, unsigned int M>
|
|
inline void replicate_2D_array (
|
|
unsigned int size,
|
|
T * const src[M],
|
|
T * tgt[M])
|
|
{
|
|
for (unsigned int ii = 0; ii < M; ++ii) {
|
|
if (ii == 0) {
|
|
tgt[ii] = allocate_array<T> (size*M);
|
|
}
|
|
else {
|
|
tgt[ii] = tgt[ii-1] + size;
|
|
}
|
|
for (unsigned int jj = 0; jj < size; ++jj) {
|
|
tgt[ii][jj] = src[ii][jj];
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Specialization of replicate_2D_array for double.
|
|
* @tparam M Array outer dimension
|
|
* @param[in] size Array inner dimension
|
|
* @param[in] src Source 2D array
|
|
* @param[out] tgt Array to be allocated and populated
|
|
*/
|
|
template<unsigned int M>
|
|
inline void replicate_2D_array (
|
|
unsigned int size,
|
|
double * const src[M],
|
|
double * tgt[M])
|
|
{
|
|
for (unsigned int ii = 0; ii < M; ++ii) {
|
|
if (ii == 0) {
|
|
tgt[ii] = allocate_array<double> (size*M);
|
|
}
|
|
else {
|
|
tgt[ii] = tgt[ii-1] + size;
|
|
}
|
|
for (unsigned int jj = 0; jj < size; ++jj) {
|
|
tgt[ii][jj] = src[ii][jj];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Replicate contents of a 2D array, where the array is declared as
|
|
* @code T ** array @endcode
|
|
* @tparam T Array type
|
|
* @param outer Array outer dimension
|
|
* @param inner Array inner dimension
|
|
* @param source Array to be replicated
|
|
* @return Allocated and replicated 2D array.
|
|
*/
|
|
template<typename T>
|
|
inline T** replicate_2D_array (
|
|
unsigned int outer,
|
|
unsigned int inner,
|
|
T** source)
|
|
{
|
|
T** tgt = allocate_array<T*> (outer);
|
|
for (unsigned int ii = 0; ii < outer; ++ii) {
|
|
if (ii == 0) {
|
|
tgt[ii] = allocate_array<T> (inner*outer);
|
|
}
|
|
else {
|
|
tgt[ii] = tgt[ii-1] + inner;
|
|
}
|
|
for (unsigned int jj = 0; jj < inner; ++jj) {
|
|
tgt[ii][jj] = source[ii][jj];
|
|
}
|
|
}
|
|
return tgt;
|
|
}
|
|
|
|
|
|
/**
|
|
* Deallocate a 2D array.
|
|
* @tparam T Array type
|
|
* @tparam M Array outer dimension
|
|
* @param[in,out] arr Array to be deallocated
|
|
*/
|
|
template<typename T, unsigned int M>
|
|
inline void deallocate_2D_array (
|
|
T * arr[M])
|
|
{
|
|
deallocate_array<T> (arr[0]);
|
|
}
|
|
|
|
/**
|
|
* Specialization of deallocate_2D_array for double.
|
|
* @tparam M Array outer dimension
|
|
* @param[in,out] arr Array to be deallocated
|
|
*/
|
|
template<unsigned int M>
|
|
inline void deallocate_2D_array (
|
|
double * arr[M])
|
|
{
|
|
deallocate_array<double> (arr[0]);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Deallocate a 2D array.
|
|
* @tparam T Array type
|
|
* @param[in,out] arr Array to be deallocated
|
|
*/
|
|
template<typename T>
|
|
inline void deallocate_2D_array (
|
|
unsigned int,
|
|
T **& arr)
|
|
{
|
|
if (arr != NULL) {
|
|
deallocate_array<T> (arr[0]);
|
|
deallocate_array<T*> (arr);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/**
|
|
* @if Er7UtilsUseGroups
|
|
* @}
|
|
* @}
|
|
* @endif
|
|
*/
|