public
Created

  • Download Gist
placeholder.hpp
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
/*
* placeholder.hpp
*
* Created on: Feb 25, 2012
* Author: petergoodman
* Version: $Id$
*/
 
#ifndef XY_PLACEHOLDER_HPP_
#define XY_PLACEHOLDER_HPP_
 
#include <stdint.h>
 
namespace xy { namespace support {
 
namespace detail {
 
template <size_t div, size_t rem, size_t factor>
class storage;
 
/// one byte
template <>
class storage<1, 0, 1> {
uint8_t space;
};
 
/// two bytes
template <>
class storage<0, 1, 2> {
uint8_t space1;
};
 
template <>
class storage<1, 1, 2> {
uint16_t space0;
uint8_t space1;
};
 
template <>
class storage<1, 0, 2> {
uint16_t space0;
};
 
/// 4 bytes
template <size_t rem>
class storage<1, rem, 4> {
uint32_t space0;
storage<rem / 2, rem % 2, 2> space1;
};
 
template <size_t rem>
class storage<0, rem, 4> {
storage<rem / 2, rem % 2, 2> space1;
};
 
template <>
class storage<1, 0, 4> {
uint32_t space;
};
 
/// 8 bytes
template <size_t div, size_t rem>
class storage<div, rem, 8> {
uint64_t space0[div];
storage<rem / 4, rem % 4, 4> space1;
};
 
template <size_t rem>
class storage<0, rem, 8> {
storage<rem / 4, rem % 4, 4> space1;
};
 
template <size_t div>
class storage<div, 0, 8> {
uint64_t space[div];
};
}
 
/// placeholder for some data with the right amount of space and
/// alignment. this is mainly used in the garbage collector so that
/// the default allocation of a garbage collected value is just empty
/// space
template <typename T>
class placeholder {
private:
 
enum : size_t {
SIZE_ORIG = sizeof(T)
};
 
typedef detail::storage<SIZE_ORIG / 8, SIZE_ORIG % 8, 8> storage_type;
 
enum : size_t {
ALIGNMENT_ORIG = alignof(T),
ALIGNMENT_NEW = alignof(storage_type),
SIZE_NEW = sizeof(storage_type)
};
 
static_assert(SIZE_NEW == SIZE_ORIG,
"Placeholder storage type size is not the same as the input type size."
);
 
static_assert(ALIGNMENT_NEW >= ALIGNMENT_ORIG,
"Alignment of placeholder storage type is less restrictive than the "
"alignment of the input type."
);
 
storage_type storage;
 
public:
 
placeholder(void) throw() {
memset(&storage, 0, sizeof storage);
}
 
T *construct(void) throw() {
return new (unsafe_cast<T *>(&storage)) T;
}
 
template <typename... CTypes>
T *construct(CTypes&&... cvals) throw() {
return new (unsafe_cast<T *>(&storage)) T(cvals...);
}
 
void destruct(void) throw() {
unsafe_cast<T *>(&storage)->~T();
memset(&storage, 0, sizeof storage);
}
 
T *operator->(void) throw() {
return unsafe_cast<T *>(&storage);
}
};
 
}}
 
 
#endif /* XY_PLACEHOLDER_HPP_ */

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.