GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
oct-mem.h
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2009-2013 VZLU Prague
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if !defined (octave_oct_mem_h)
24 #define octave_oct_mem_h 1
25 
26 #include <cstddef>
27 #include <cstring>
28 #include <algorithm>
29 
30 #include "oct-cmplx.h"
31 #include "oct-inttypes.h"
32 
33 // NOTE: These functions are used to optimize stuff where performance is a
34 // priority. They assume that the std::complex and octave_int can be
35 // manipulated as plain memory, an assumption that is always true in practice
36 // but not theoretically guaranteed by the C++ standard. In the future, C++ may
37 // provide a better way to accomplish these tasks.
38 
39 inline size_t safe_size_comp (size_t n, size_t size)
40 {
41  if (n > static_cast<size_t> (-1) / size)
42  throw std::bad_alloc ();
43  return n * size;
44 }
45 
46 // Unaliased copy. This boils down to memcpy, even for octave_int and
47 // complex types.
48 
49 template <class T>
50 inline void copy_or_memcpy (size_t n, const T *src, T *dest)
51 { std::copy (src, src + n, dest); }
52 
53 #define DEFINE_POD_UCOPY(T) \
54 inline void copy_or_memcpy (size_t n, const T *src, T *dest) \
55 { std::memcpy (dest, src, n * sizeof (T)); }
56 
63 DEFINE_POD_UCOPY (unsigned char)
64 DEFINE_POD_UCOPY (unsigned short)
65 DEFINE_POD_UCOPY (unsigned int)
66 DEFINE_POD_UCOPY (unsigned long)
67 
70 
71 template <class T>
73 
74 // Fill by value, with a check for zero. This boils down to memset if value is
75 // a POD zero.
76 template <class T>
77 inline void fill_or_memset (size_t n, const T& value, T *dest)
78 { std::fill_n (dest, n, value); }
79 
80 template <class T>
81 inline bool helper_is_zero_mem (const T& value)
82 {
83  // get integer type of the same size.
85  return *(reinterpret_cast<const IT *>(&value)) == 0;
86 }
87 
88 template <class T>
89 inline bool helper_is_zero_mem (const std::complex<T>& value)
90 {
91  return (helper_is_zero_mem (value.real ())
92  && helper_is_zero_mem (value.imag ()));
93 }
94 
95 template <class T>
96 inline bool helper_is_zero_mem (const octave_int<T>& value)
97 { return value.value () == T (); }
98 
99 #define DEFINE_POD_FILL(T) \
100 inline void fill_or_memset (size_t n, const T& value, T *dest) \
101 { \
102  if (helper_is_zero_mem (value)) \
103  std::memset (dest, 0, n * sizeof (T)); \
104  else \
105  std::fill_n (dest, n, value); \
106 }
107 
114 DEFINE_POD_FILL (unsigned char)
115 DEFINE_POD_FILL (unsigned short)
116 DEFINE_POD_FILL (unsigned int)
117 DEFINE_POD_FILL (unsigned long)
118 
121 
122 template <class T>
124 
125 // Uninitialized allocation.
126 // Will not initialize memory for complex and octave_int.
127 // Memory allocated by octave_new should be freed by octave_delete.
128 template <class T>
129 inline T *no_ctor_new (size_t n)
130 {
131  // Some systems let us allocate > 2GB memory even though size_t, which is
132  // either buggy or completely cuckoo, so let's check here to stay safe.
133  safe_size_comp (n, sizeof (T));
134  return new T [n];
135 }
136 template <class T>
137 inline void no_ctor_delete (T *ptr)
138 { delete [] ptr; }
139 
140 #define DEFINE_POD_NEW_DELETE(T) \
141 template <> \
142 inline T *no_ctor_new<T > (size_t n) \
143 { return reinterpret_cast<T *> (new char [safe_size_comp (n, sizeof (T))]); } \
144 template <> \
145 inline void no_ctor_delete<T > (T *ptr) \
146 { delete [] reinterpret_cast<char *> (ptr); }
147 
150 
159 
160 #endif /* octave_oct_mem_h */