Mercurial > hg > octave-nkf
view liboctave/oct-mem.h @ 14026:3781981be535 ss-3-5-90
snapshot 3.5.90
* configure.ac (AC_INIT): Version is now 3.5.90.
(OCTAVE_API_VERSION_NUMBER): Now 46.
(OCTAVE_RELEASE_DATE): Now 2011-12-11.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sun, 11 Dec 2011 23:18:31 -0500 |
parents | 12df7854fa7c |
children | 72c96de7a403 |
line wrap: on
line source
/* Copyright (C) 2009-2011 VZLU Prague This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #if !defined (octave_memory_h) #define octave_memory_h 1 #include <cstddef> #include <cstring> #include <algorithm> #include "oct-cmplx.h" #include "oct-inttypes.h" // NOTE: These functions are used to optimize stuff where performance is a // priority. They assume that the std::complex and octave_int can be // manipulated as plain memory, an assumption that is always true in practice // but not theoretically guaranteed by the C++ standard. In the future, C++ may // provide a better way to accomplish these tasks. inline size_t safe_size_comp (size_t n, size_t size) { if (n > static_cast<size_t> (-1) / size) throw std::bad_alloc (); return n * size; } // Unaliased copy. This boils down to memcpy, even for octave_int and complex types. template <class T> inline void copy_or_memcpy (size_t n, const T *src, T *dest) { std::copy (src, src + n, dest); } #define DEFINE_POD_UCOPY(T) \ inline void copy_or_memcpy (size_t n, const T *src, T *dest) \ { std::memcpy (dest, src, n * sizeof (T)); } DEFINE_POD_UCOPY (double) DEFINE_POD_UCOPY (float) DEFINE_POD_UCOPY (char) DEFINE_POD_UCOPY (short) DEFINE_POD_UCOPY (int) DEFINE_POD_UCOPY (long) DEFINE_POD_UCOPY (unsigned char) DEFINE_POD_UCOPY (unsigned short) DEFINE_POD_UCOPY (unsigned int) DEFINE_POD_UCOPY (unsigned long) DEFINE_POD_UCOPY (Complex) DEFINE_POD_UCOPY (FloatComplex) template <class T> DEFINE_POD_UCOPY (octave_int<T>) // Fill by value, with a check for zero. This boils down to memset if value is // a POD zero. template <class T> inline void fill_or_memset (size_t n, const T& value, T *dest) { std::fill_n (dest, n, value); } template <class T> inline bool helper_is_zero_mem (const T& value) { typedef typename query_integer_type<sizeof (T), false>::type IT; // get integer type of the same size. return *(reinterpret_cast<const IT *>(&value)) == 0; } template <class T> inline bool helper_is_zero_mem (const std::complex<T>& value) { return (helper_is_zero_mem (value.real ()) && helper_is_zero_mem (value.imag ())); } template <class T> inline bool helper_is_zero_mem (const octave_int<T>& value) { return value.value () == T(); } #define DEFINE_POD_FILL(T) \ inline void fill_or_memset (size_t n, const T& value, T *dest) \ { \ if (helper_is_zero_mem (value)) \ std::memset (dest, 0, n * sizeof (T)); \ else \ std::fill_n (dest, n, value); \ } DEFINE_POD_FILL (double) DEFINE_POD_FILL (float) DEFINE_POD_FILL (char) DEFINE_POD_FILL (short) DEFINE_POD_FILL (int) DEFINE_POD_FILL (long) DEFINE_POD_FILL (unsigned char) DEFINE_POD_FILL (unsigned short) DEFINE_POD_FILL (unsigned int) DEFINE_POD_FILL (unsigned long) DEFINE_POD_FILL (Complex) DEFINE_POD_FILL (FloatComplex) template <class T> DEFINE_POD_FILL (octave_int<T>) // Uninitialized allocation. Will not initialize memory for complex and octave_int. // Memory allocated by octave_new should be freed by octave_delete. template <class T> inline T *no_ctor_new (size_t n) { // Some systems let us allocate > 2GB memory even though size_t, which is either // buggy or completely cuckoo, so let's check here to stay safe. safe_size_comp (n, sizeof (T)); return new T[n]; } template <class T> inline void no_ctor_delete (T *ptr) { delete [] ptr; } #define DEFINE_POD_NEW_DELETE(T) \ template <> \ inline T *no_ctor_new<T > (size_t n) \ { return reinterpret_cast<T *> (new char[safe_size_comp (n, sizeof (T))]); } \ template <> \ inline void no_ctor_delete<T > (T *ptr) \ { delete [] reinterpret_cast<char *> (ptr); } DEFINE_POD_NEW_DELETE (Complex) DEFINE_POD_NEW_DELETE (FloatComplex) DEFINE_POD_NEW_DELETE (octave_int8) DEFINE_POD_NEW_DELETE (octave_int16) DEFINE_POD_NEW_DELETE (octave_int32) DEFINE_POD_NEW_DELETE (octave_int64) DEFINE_POD_NEW_DELETE (octave_uint8) DEFINE_POD_NEW_DELETE (octave_uint16) DEFINE_POD_NEW_DELETE (octave_uint32) DEFINE_POD_NEW_DELETE (octave_uint64) #endif /* octave_memory_h */