Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
AlignedStorage.h
00001 /* 00002 * Copyright (c) 2016, ARM Limited, All Rights Reserved 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00006 * not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #ifndef EVENTQUEUE_DETAIL_ALIGNEDSTORAGE_H_ 00018 #define EVENTQUEUE_DETAIL_ALIGNEDSTORAGE_H_ 00019 00020 #include <cstddef> 00021 00022 namespace eq { 00023 00024 class AnonymousDeclaration; 00025 00026 /** 00027 * Provide aligned raw storage for holding a type T. 00028 * This class is useful to delay the construction of objects while reserving 00029 * space in memory for them. 00030 * For instance, it can be use with static or global variable which can not 00031 * be constructed before main. It can also be used in class member which 00032 * do not have or can't be constructed at parent construction time. 00033 * 00034 * Once the storage has been reserved, it is possible explicitly construct the 00035 * object of T by using placement new syntax. 00036 * @code 00037 * AlignedStorage<Foo> foo; 00038 * new (foo.get_storage()) Foo(...); 00039 * @endcode 00040 * Then it is possible to get a reference to the object by calling the member 00041 * function get. 00042 * @code 00043 * foo.get().doSomething(); 00044 * @endcode 00045 * Once the object needs to be destroyed it is possible to call the destructor 00046 * directly 00047 * @code 00048 * foo.get().~Foo(); 00049 * @endcode 00050 * After this point, their is no instance of T in the storage and the function 00051 * get remains unusable until an object is again initialised in the storage. 00052 */ 00053 template<typename T> 00054 class AlignedStorage { 00055 public: 00056 /** 00057 * Initialisation of the storage, does **not** zeroed its memory. 00058 */ 00059 AlignedStorage() {} 00060 /** 00061 * Provide the raw pointer to the address of the storage. 00062 */ 00063 void* get_storage() { 00064 return data; 00065 } 00066 00067 /** 00068 * Provide the raw pointer to the const address of the storage. 00069 */ 00070 const void* get_storage() const { 00071 return data; 00072 } 00073 00074 /** 00075 * Return a reference to the element T in this storage. 00076 */ 00077 T& get() { 00078 return *static_cast<T*>(get_storage()); 00079 } 00080 00081 /** 00082 * Return a reference to the const element of T in this storage. 00083 */ 00084 const T& get() const { 00085 return *static_cast<const T*>(get_storage()); 00086 } 00087 00088 private: 00089 // it doesn't make sense to allow copy construction of copy assignement for 00090 // this kind of object. 00091 AlignedStorage(const AlignedStorage&); 00092 AlignedStorage& operator=(const AlignedStorage&); 00093 // storage. Can be improved by metaprogramming to be the best fit. 00094 union { 00095 char char_storage; 00096 short int short_int_storage; 00097 int int_storage; 00098 long int long_int_storage; 00099 float float_storage; 00100 double double_storage; 00101 long double long_double_storage; 00102 void* pointer_storage; 00103 AnonymousDeclaration (*function_pointer_storage)(AnonymousDeclaration); 00104 AnonymousDeclaration* AnonymousDeclaration::*data_member_storage ; 00105 AnonymousDeclaration (AnonymousDeclaration::*function_member_storage)(AnonymousDeclaration); 00106 char data[sizeof(T)]; 00107 }; 00108 }; 00109 00110 /** 00111 * Provide aligned raw storage for holding an array of type T. 00112 * This is a specialisation of AlignedStorage for arrays of T. 00113 * With this class, it is possible to reserve space for a given number of 00114 * elements of type T and delay their construction to a latter point. This 00115 * feature can be really useful when building generic container which 00116 * embed memory for their elements. Instead of default constructing them, 00117 * the construction of an element can be made when it is really needed, by 00118 * copy. It is the same for the destruction, only objects which have been 00119 * constructed needs to be destructed. 00120 * Those properties improve generic containers because only the operations 00121 * which have to be made are made. It also allow generic container to hold 00122 * types which are not DefaultConstructible. 00123 * 00124 * Once the storage has been reserved, it is possible explicitly construct an 00125 * object of T at a given index by using placement new syntax. 00126 * @code 00127 * AlignedStorage<Foo[10]> foo; 00128 * //construct object at index 0 then at index 1. 00129 * new (foo.get_storage(0)) Foo(...); 00130 * new (foo.get_storage(1)) Foo(...); 00131 * @endcode 00132 * Then it is possible to get a reference to an object at a given index by 00133 * calling the member function get. 00134 * @code 00135 * // do something with object at index 1 00136 * foo.get(1).doSomething(); 00137 * @endcode 00138 * Once the object needs to be destroyed it is possible to call the destructor 00139 * directly 00140 * @code 00141 * // destroy object at index 1. 00142 * foo.get(1).~Foo(); 00143 * @endcode 00144 * After this point, their is no instance of T at index 1 in the storage and 00145 * trying to use the object at this index will lead to undefined behavior until 00146 * an object is again initialised at this index. 00147 */ 00148 template<typename T, std::size_t ArraySize> 00149 struct AlignedStorage<T[ArraySize]> { 00150 /** 00151 * Initialisation of the storage, does **not** zeroed its memory. 00152 */ 00153 AlignedStorage() {} 00154 00155 /** 00156 * Return raw pointer to the address of element at a given index 00157 */ 00158 void* get_storage(std::size_t index) { 00159 return &get(index); 00160 } 00161 00162 /** 00163 * const version of void* get_storage(std::size_t). 00164 */ 00165 const void* get_storage(std::size_t index) const { 00166 return &get(index); 00167 } 00168 00169 /** 00170 * Return reference to the element stored atindex. 00171 */ 00172 T& get(std::size_t index) { 00173 return reinterpret_cast<T*>(data)[index]; 00174 } 00175 00176 /** 00177 * const version of T& get(std::size_t). 00178 */ 00179 const T& get(std::size_t index) const { 00180 return reinterpret_cast<const T*>(data)[index]; 00181 } 00182 00183 private: 00184 // it doesn't make sense to allow copy construction of copy assignement for 00185 // this kind of object. 00186 AlignedStorage(const AlignedStorage&); 00187 AlignedStorage& operator=(const AlignedStorage&); 00188 // storage. Can be improved by metaprogramming to be the best fit. 00189 union { 00190 char char_storage; 00191 short int short_int_storage; 00192 int int_storage; 00193 long int long_int_storage; 00194 float float_storage; 00195 double double_storage; 00196 long double long_double_storage; 00197 void* pointer_storage; 00198 AnonymousDeclaration (*function_pointer_storage)(AnonymousDeclaration); 00199 AnonymousDeclaration* AnonymousDeclaration::*data_member_storage ; 00200 AnonymousDeclaration (AnonymousDeclaration::*function_member_storage)(AnonymousDeclaration); 00201 char data[sizeof(T[ArraySize])]; 00202 }; 00203 }; 00204 00205 } // namespace eq 00206 00207 #endif /* EVENTQUEUE_DETAIL_ALIGNEDSTORAGE_H_ */
Generated on Thu Jul 14 2022 09:28:18 by
1.7.2