| 276 | template<class T, class D> |
| 277 | #endif |
| 278 | class Array |
| 279 | { |
| 280 | public: |
| 281 | /** @brief Element type */ |
| 282 | typedef T Type; |
| 283 | |
| 284 | /** |
| 285 | * @brief Deleter type |
| 286 | * |
| 287 | * Defaults to pointer to a @cpp void(T*, std::size_t) @ce function, |
| 288 | * where first is array pointer and second array size. |
| 289 | */ |
| 290 | typedef D Deleter; |
| 291 | |
| 292 | /** |
| 293 | * @brief Default constructor |
| 294 | * |
| 295 | * Creates a zero-sized array. Move an @ref Array with a nonzero size |
| 296 | * onto the instance to make it useful. |
| 297 | */ |
| 298 | #ifdef DOXYGEN_GENERATING_OUTPUT |
| 299 | /*implicit*/ Array(std::nullptr_t = nullptr) noexcept; |
| 300 | #else |
| 301 | /* To avoid ambiguity either when calling Array{0} or in certain cases of passing 0 to overloads that take either an Array or std::size_t */ |
| 302 | template<class U, typename std::enable_if<std::is_same<std::nullptr_t, U>::value, int>::type = 0> /*implicit*/ Array(U) noexcept : _data{nullptr}, _size{0}, _deleter{} {} |
| 303 | |
| 304 | /*implicit*/ Array() noexcept : _data(nullptr), _size(0), _deleter{} {} |
| 305 | #endif |
| 306 | |
| 307 | /** |
| 308 | * @brief Construct a value-initialized array |
| 309 | * |
| 310 | * Creates an array of given size, the contents are value-initialized |
| 311 | * (i.e. trivial types are zero-initialized, default constructor called |
| 312 | * otherwise). This is the same as @ref Array(std::size_t). If the size |
| 313 | * is zero, no allocation is done. |
| 314 | */ |
| 315 | explicit Array(ValueInitT, std::size_t size) : _data{size ? new T[size]() : nullptr}, _size{size}, _deleter{nullptr} {} |
| 316 | |
| 317 | /** |
| 318 | * @brief Construct an array without initializing its contents |
| 319 | * |
| 320 | * Creates an array of given size, the contents are *not* initialized. |
| 321 | * If the size is zero, no allocation is done. Useful if you will be |
| 322 | * overwriting all elements later anyway or if you need to call custom |
| 323 | * constructors in a way that's not expressible via any other |
| 324 | * @ref Array constructor. |
| 325 | * |
| 326 | * For trivial types is equivalent to @cpp new T[size] @ce (as opposed |
| 327 | * to @cpp new T[size]{} @ce), with @ref deleter() being the default |
| 328 | * (@cpp nullptr @ce). For non-trivial types, the data are allocated as |
| 329 | * a @cpp char @ce array and destruction is done using a custom deleter |
| 330 | * that explicitly calls the destructor on *all elements* and then |
| 331 | * deallocates the data as a @cpp char @ce array again --- which means |
| 332 | * that for non-trivial types you're expected to construct all elements |
| 333 | * using placement new (or for example @ref std::uninitialized_copy()) |
| 334 | * in order to avoid calling destructors on uninitialized memory. |
| 335 | */ |