Skip to content

Instantly share code, notes, and snippets.

@JustasMasiulis
Created June 21, 2018 08:48
Show Gist options
  • Save JustasMasiulis/dd1747b34ddf908c79b8c6cf830dbd25 to your computer and use it in GitHub Desktop.
Save JustasMasiulis/dd1747b34ddf908c79b8c6cf830dbd25 to your computer and use it in GitHub Desktop.
#ifndef JM_STACK_STRING_HPP
#define JM_STACK_STRING_HPP
#include <cstdint>
#include <cstddef>
#include <type_traits>
#define STACK_STRING(name, str) \
alignas(8) std::decay_t<decltype(*str)> \
name[sizeof(str) / sizeof(std::decay_t<decltype(*str)>)]; \
\
{ \
constexpr ::jm::detail::string_storage<std::decay_t<decltype(*str)>, \
sizeof(str)> \
_storageSTACK_STRING(str); \
_storageSTACK_STRING.copy(name); \
}
namespace jm { namespace detail {
template<std::size_t N>
struct _buffer_size {
constexpr static std::size_t value = N / 8 + static_cast<bool>(N % 8);
};
template<class CharT, std::size_t N>
struct string_storage {
std::uint64_t storage[_buffer_size<N>::value];
inline constexpr string_storage(const CharT (&str)[N / sizeof(CharT)])
: storage{ 0 }
{
// puts the string into 64 bit integer blocks in a constexpr way
for(std::size_t i = 0; i < N / sizeof(CharT); ++i)
storage[i / (8 / sizeof(CharT))] |=
(std::uint64_t(str[i])
<< ((i % (8 / sizeof(CharT))) * 8 * sizeof(CharT)));
}
template<std::size_t I = 0>
inline void copy(CharT* str, std::integral_constant<std::size_t, I> = {}) const
{
reinterpret_cast<volatile std::uint64_t*>(str)[I] = storage[I];
return copy(str, std::integral_constant<std::size_t, I + 1>{});
}
inline constexpr void
copy(CharT*, std::integral_constant<std::size_t, _buffer_size<N>::value>) const
{}
};
}} // namespace jm::detail
#endif // include guard
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment