Lightmetrica  0.0.1.50dbee3 (yosakoi)
 All Classes Functions Variables Typedefs Enumerations Enumerator
align.h
1 /*
2  Lightmetrica : A research-oriented renderer
3 
4  Copyright (c) 2014 Hisanari Otsu
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #pragma once
21 #ifndef LIB_LIGHTMETRICA_ALIGN_H
22 #define LIB_LIGHTMETRICA_ALIGN_H
23 
24 #include "common.h"
25 
26 LM_NAMESPACE_BEGIN
27 
34 LM_PUBLIC_API void* aligned_malloc(size_t size, size_t align);
35 
40 LM_PUBLIC_API void aligned_free(void* p);
41 
47 LM_FORCE_INLINE bool is_aligned(const void* p, size_t align)
48 {
49  return (uintptr_t)p % align == 0;
50 }
51 
56 template <size_t Align>
57 class Aligned
58 {
59 public:
60 
61  virtual ~Aligned() {}
62 
63 public:
64 
65  void* operator new(std::size_t size) throw (std::bad_alloc)
66  {
67  void* p = aligned_malloc( size, Align);
68  if (!p) throw std:: bad_alloc();
69  return p;
70  }
71 
72  void operator delete( void* p)
73  {
74  aligned_free( p);
75  }
76 
77 };
78 
84 class LM_PUBLIC_API SIMDAlignedType
85 {
86 public:
87 
88  virtual ~SIMDAlignedType() {}
89 
90 public:
91 
92  void* operator new(std::size_t size) throw (std::bad_alloc);
93  void operator delete(void* p);
94 
95 };
96 
102 template <typename T, std::size_t Alignment>
104 {
105 public:
106 
107  // The following will be the same for virtually all allocators.
108  typedef T * pointer;
109  typedef const T * const_pointer;
110  typedef T& reference;
111  typedef const T& const_reference;
112  typedef T value_type;
113  typedef std::size_t size_type;
114  typedef ptrdiff_t difference_type;
115 
116  T * address(T& r) const { return &r; }
117  const T * address(const T& s) const { return &s; }
118 
119  std::size_t max_size() const
120  {
121  // The following has been carefully written to be independent of
122  // the definition of size_t and to avoid signed/unsigned warnings.
123  return (static_cast<std::size_t>(0) - static_cast<std::size_t>(1)) / sizeof(T);
124  }
125 
126  // The following must be the same for all allocators.
127  template <typename U>
128  struct rebind
129  {
131  };
132 
133  bool operator!=(const aligned_allocator& other) const
134  {
135  return !(*this == other);
136  }
137 
138  void construct(T * const p, const T& t) const
139  {
140  void * const pv = static_cast<void *>(p);
141  new (pv) T(t);
142  }
143 
144  void destroy(T * const p) const
145  {
146  p->~T();
147  }
148 
149  // Returns true if and only if storage allocated from *this
150  // can be deallocated from other, and vice versa.
151  // Always returns true for stateless allocators.
152  bool operator==(const aligned_allocator& other) const
153  {
154  return true;
155  }
156 
157  // Default constructor, copy constructor, rebinding constructor, and destructor.
158  // Empty for stateless allocators.
159  aligned_allocator() {}
161  template <typename U> aligned_allocator(const aligned_allocator<U, Alignment>&) {}
162  ~aligned_allocator() {}
163 
164 
165  // The following will be different for each allocator.
166  T * allocate(const std::size_t n) const
167  {
168  // The return value of allocate(0) is unspecified.
169  // Mallocator returns NULL in order to avoid depending
170  // on malloc(0)'s implementation-defined behavior
171  // (the implementation can define malloc(0) to return NULL,
172  // in which case the bad_alloc check below would fire).
173  // All allocators can return NULL in this case.
174  if (n == 0) {
175  return NULL;
176  }
177 
178  // All allocators should contain an integer overflow check.
179  // The Standardization Committee recommends that std::length_error
180  // be thrown in the case of integer overflow.
181  if (n > max_size())
182  {
183  throw std::length_error("aligned_allocator<T>::allocate() - Integer overflow.");
184  }
185 
186  // Mallocator wraps malloc().
187  void * const pv = aligned_malloc(n * sizeof(T), Alignment);
188 
189  // Allocators should throw std::bad_alloc in the case of memory allocation failure.
190  if (pv == NULL)
191  {
192  throw std::bad_alloc();
193  }
194 
195  return static_cast<T *>(pv);
196  }
197 
198  void deallocate(T * const p, const std::size_t /*n*/) const
199  {
200  aligned_free(p);
201  }
202 
203 
204  // The following will be the same for all allocators that ignore hints.
205  template <typename U>
206  T * allocate(const std::size_t n, const U * /* const hint */) const
207  {
208  return allocate(n);
209  }
210 
211  // Allocators are not required to be assignable, so
212  // all allocators should have a private unimplemented
213  // assignment operator. Note that this will trigger the
214  // off-by-default (enabled under /Wall) warning C4626
215  // "assignment operator could not be generated because a
216  // base class assignment operator is inaccessible" within
217  // the STL headers, but that warning is useless.
218 private:
219 
220  aligned_allocator& operator=(const aligned_allocator&);
221 
222 };
223 
228 template <std::size_t Align>
230 {
231 
232  typedef std::size_t size_type;
233  typedef std::ptrdiff_t difference_type;
234  static char* malloc(const size_type bytes) { return static_cast<char*>(aligned_malloc(bytes, Align)); }
235  static void free(const char* block) { aligned_free((void*)block); }
236 
237 };
238 
239 LM_NAMESPACE_END
240 
241 #endif // LIB_LIGHTMETRICA_ALIGN_H
Definition: align.h:84
Definition: align.h:229
Definition: align.h:128
Definition: align.h:57
Definition: align.h:103