Created
March 14, 2012 03:21
-
-
Save pgoodman/2033774 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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_ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment