Skip to content

Instantly share code, notes, and snippets.

@pgoodman
Created March 14, 2012 03:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pgoodman/2033774 to your computer and use it in GitHub Desktop.
Save pgoodman/2033774 to your computer and use it in GitHub Desktop.
/*
* 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