blob: 60f147af1154f1fd74b284b637107d3659ce254f [file] [log] [blame]
Austin Schuh70cc9552019-01-21 19:46:48 -08001// Ceres Solver - A fast non-linear least squares minimizer
2// Copyright 2015 Google Inc. All rights reserved.
3// http://ceres-solver.org/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// * Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13// * Neither the name of Google Inc. nor the names of its contributors may be
14// used to endorse or promote products derived from this software without
15// specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27// POSSIBILITY OF SUCH DAMAGE.
28//
29// Author: kenton@google.com (Kenton Varda)
30//
31// ManualConstructor statically-allocates space in which to store some
32// object, but does not initialize it. You can then call the constructor
33// and destructor for the object yourself as you see fit. This is useful
34// for memory management optimizations, where you want to initialize and
35// destroy an object multiple times but only allocate it once.
36//
37// (When I say ManualConstructor statically allocates space, I mean that
38// the ManualConstructor object itself is forced to be the right size.)
39
40#ifndef CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_
41#define CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_
42
43#include <new>
44#include <utility>
45
46namespace ceres {
47namespace internal {
48
49// ------- Define CERES_ALIGNED_CHAR_ARRAY --------------------------------
50
51// Platform independent macros to get aligned memory allocations.
52// For example
53//
54// MyFoo my_foo CERES_ALIGN_ATTRIBUTE(16);
55//
56// Gives us an instance of MyFoo which is aligned at a 16 byte
57// boundary.
58#if defined(_MSC_VER)
59#define CERES_ALIGN_ATTRIBUTE(n) __declspec(align(n))
60#define CERES_ALIGN_OF(T) __alignof(T)
61#elif defined(__GNUC__)
62#define CERES_ALIGN_ATTRIBUTE(n) __attribute__((aligned(n)))
63#define CERES_ALIGN_OF(T) __alignof(T)
64#endif
65
66#ifndef CERES_ALIGNED_CHAR_ARRAY
67
68// Because MSVC and older GCCs require that the argument to their alignment
69// construct to be a literal constant integer, we use a template instantiated
70// at all the possible powers of two.
71template<int alignment, int size> struct AlignType { };
72template<int size> struct AlignType<0, size> { typedef char result[size]; };
73
74#if !defined(CERES_ALIGN_ATTRIBUTE)
75#define CERES_ALIGNED_CHAR_ARRAY you_must_define_CERES_ALIGNED_CHAR_ARRAY_for_your_compiler
76#else // !defined(CERES_ALIGN_ATTRIBUTE)
77
78#define CERES_ALIGN_TYPE_TEMPLATE(X) \
79 template<int size> struct AlignType<X, size> { \
80 typedef CERES_ALIGN_ATTRIBUTE(X) char result[size]; \
81 }
82
83CERES_ALIGN_TYPE_TEMPLATE(1);
84CERES_ALIGN_TYPE_TEMPLATE(2);
85CERES_ALIGN_TYPE_TEMPLATE(4);
86CERES_ALIGN_TYPE_TEMPLATE(8);
87CERES_ALIGN_TYPE_TEMPLATE(16);
88CERES_ALIGN_TYPE_TEMPLATE(32);
89CERES_ALIGN_TYPE_TEMPLATE(64);
90CERES_ALIGN_TYPE_TEMPLATE(128);
91CERES_ALIGN_TYPE_TEMPLATE(256);
92CERES_ALIGN_TYPE_TEMPLATE(512);
93CERES_ALIGN_TYPE_TEMPLATE(1024);
94CERES_ALIGN_TYPE_TEMPLATE(2048);
95CERES_ALIGN_TYPE_TEMPLATE(4096);
96CERES_ALIGN_TYPE_TEMPLATE(8192);
97// Any larger and MSVC++ will complain.
98
99#undef CERES_ALIGN_TYPE_TEMPLATE
100
101#define CERES_ALIGNED_CHAR_ARRAY(T, Size) \
102 typename AlignType<CERES_ALIGN_OF(T), sizeof(T) * Size>::result
103
104#endif // !defined(CERES_ALIGN_ATTRIBUTE)
105
106#endif // CERES_ALIGNED_CHAR_ARRAY
107
108template <typename Type>
109class ManualConstructor {
110 public:
111 // No constructor or destructor because one of the most useful uses of
112 // this class is as part of a union, and members of a union cannot have
113 // constructors or destructors. And, anyway, the whole point of this
114 // class is to bypass these.
115
116 inline Type* get() {
117 return reinterpret_cast<Type*>(space_);
118 }
119 inline const Type* get() const {
120 return reinterpret_cast<const Type*>(space_);
121 }
122
123 inline Type* operator->() { return get(); }
124 inline const Type* operator->() const { return get(); }
125
126 inline Type& operator*() { return *get(); }
127 inline const Type& operator*() const { return *get(); }
128
129 // This is needed to get around the strict aliasing warning GCC generates.
130 inline void* space() {
131 return reinterpret_cast<void*>(space_);
132 }
133
134 template <typename... Ts>
135 inline void Init(Ts&&... ps) {
136 new(space()) Type(std::forward<Ts>(ps)...);
137 }
138
139 inline void Destroy() {
140 get()->~Type();
141 }
142
143 private:
144 CERES_ALIGNED_CHAR_ARRAY(Type, 1) space_;
145};
146
147#undef CERES_ALIGNED_CHAR_ARRAY
148
149} // namespace internal
150} // namespace ceres
151
152#endif // CERES_PUBLIC_INTERNAL_MANUAL_CONSTRUCTOR_H_