#include <array>
#include <cstddef>
#include <cstring>
namespace my
{
namespace detail
{
template <typename CharT>
constexpr auto
strlen_c(const CharT *const string) noexcept
{
auto count = static_cast<std::size_t>(0);
for (auto s = string; *s; ++s)
++count;
return count;
}
template <std::size_t N, std::size_t M, typename CharT>
struct truncation_helper
{
template <typename... CharTs>
static constexpr auto
help(const CharT *const string, const std::size_t length, const CharTs... chars) noexcept
{
static_assert(sizeof...(chars) == M, "wrong instantiation");
const auto c = (length > M) ? string[M] : static_cast<CharT>(0);
return truncation_helper<N, M + 1, CharT>::help(string, length, chars..., c);
}
};
template <std::size_t N, typename CharT>
struct truncation_helper<N, N, CharT>
{
template <typename... CharTs>
static constexpr auto
help(const CharT *, const std::size_t, const CharTs... chars) noexcept
{
static_assert(sizeof...(chars) == N, "wrong instantiation");
std::array<CharT, N + 1> result = { chars..., static_cast<CharT>(0) };
return result;
}
};
} // namespace detail
template <std::size_t N, typename CharT>
constexpr auto
truncate(const CharT *const string) noexcept
{
const auto length = detail::strlen_c(string);
return detail::truncation_helper<N, 0, CharT>::help(string, length);
}
} // namespace my
#ifndef SOMETEXT
# define SOMETEXT "example"
#endif
namespace /* anonymous */
{
constexpr auto limit = static_cast<std::size_t>(8);
constexpr auto text = my::truncate<limit>(SOMETEXT);
}
int
main()
{
std::printf("text = \"%s\"\n", text.data());
std::printf("len(text) = %lu <= %lu\n", std::strlen(text.data()), limit);
std::printf("text = \"%s\"\n", my::truncate<4>(SOMETEXT).data());
}
I2luY2x1ZGUgPGFycmF5PgojaW5jbHVkZSA8Y3N0ZGRlZj4KI2luY2x1ZGUgPGNzdHJpbmc+CgpuYW1lc3BhY2UgbXkKewoKICBuYW1lc3BhY2UgZGV0YWlsCiAgewoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBDaGFyVD4KICAgIGNvbnN0ZXhwciBhdXRvCiAgICBzdHJsZW5fYyhjb25zdCBDaGFyVCAqY29uc3Qgc3RyaW5nKSBub2V4Y2VwdAogICAgewogICAgICBhdXRvIGNvdW50ID0gc3RhdGljX2Nhc3Q8c3RkOjpzaXplX3Q+KDApOwogICAgICBmb3IgKGF1dG8gcyA9IHN0cmluZzsgKnM7ICsrcykKICAgICAgICArK2NvdW50OwogICAgICByZXR1cm4gY291bnQ7CiAgICB9CgogICAgdGVtcGxhdGUgPHN0ZDo6c2l6ZV90IE4sIHN0ZDo6c2l6ZV90IE0sIHR5cGVuYW1lIENoYXJUPgogICAgc3RydWN0IHRydW5jYXRpb25faGVscGVyCiAgICB7CiAgICAgIHRlbXBsYXRlIDx0eXBlbmFtZS4uLiBDaGFyVHM+CiAgICAgIHN0YXRpYyBjb25zdGV4cHIgYXV0bwogICAgICBoZWxwKGNvbnN0IENoYXJUICpjb25zdCBzdHJpbmcsIGNvbnN0IHN0ZDo6c2l6ZV90IGxlbmd0aCwgY29uc3QgQ2hhclRzLi4uIGNoYXJzKSBub2V4Y2VwdAogICAgICB7CiAgICAgICAgc3RhdGljX2Fzc2VydChzaXplb2YuLi4oY2hhcnMpID09IE0sICJ3cm9uZyBpbnN0YW50aWF0aW9uIik7CiAgICAgICAgY29uc3QgYXV0byBjID0gKGxlbmd0aCA+IE0pID8gc3RyaW5nW01dIDogc3RhdGljX2Nhc3Q8Q2hhclQ+KDApOwogICAgICAgIHJldHVybiB0cnVuY2F0aW9uX2hlbHBlcjxOLCBNICsgMSwgQ2hhclQ+OjpoZWxwKHN0cmluZywgbGVuZ3RoLCBjaGFycy4uLiwgYyk7CiAgICAgIH0KICAgIH07CgogICAgdGVtcGxhdGUgPHN0ZDo6c2l6ZV90IE4sIHR5cGVuYW1lIENoYXJUPgogICAgc3RydWN0IHRydW5jYXRpb25faGVscGVyPE4sIE4sIENoYXJUPgogICAgewogICAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQ2hhclRzPgogICAgICBzdGF0aWMgY29uc3RleHByIGF1dG8KICAgICAgaGVscChjb25zdCBDaGFyVCAqLCBjb25zdCBzdGQ6OnNpemVfdCwgY29uc3QgQ2hhclRzLi4uIGNoYXJzKSBub2V4Y2VwdAogICAgICB7CiAgICAgICAgc3RhdGljX2Fzc2VydChzaXplb2YuLi4oY2hhcnMpID09IE4sICJ3cm9uZyBpbnN0YW50aWF0aW9uIik7CiAgICAgICAgCiAgICAgICAgc3RkOjphcnJheTxDaGFyVCwgTiArIDE+IHJlc3VsdCA9IHsgY2hhcnMuLi4sIHN0YXRpY19jYXN0PENoYXJUPigwKSB9OwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KICAgIH07CgogIH0gIC8vIG5hbWVzcGFjZSBkZXRhaWwKCiAgdGVtcGxhdGUgPHN0ZDo6c2l6ZV90IE4sIHR5cGVuYW1lIENoYXJUPgogIGNvbnN0ZXhwciBhdXRvCiAgdHJ1bmNhdGUoY29uc3QgQ2hhclQgKmNvbnN0IHN0cmluZykgbm9leGNlcHQKICB7CiAgICBjb25zdCBhdXRvIGxlbmd0aCA9IGRldGFpbDo6c3RybGVuX2Moc3RyaW5nKTsKICAgIHJldHVybiBkZXRhaWw6OnRydW5jYXRpb25faGVscGVyPE4sIDAsIENoYXJUPjo6aGVscChzdHJpbmcsIGxlbmd0aCk7CiAgfQoKfSAgLy8gbmFtZXNwYWNlIG15CgojaWZuZGVmIFNPTUVURVhUCiMgIGRlZmluZSBTT01FVEVYVCAiZXhhbXBsZSIKI2VuZGlmCgpuYW1lc3BhY2UgLyogYW5vbnltb3VzICovCnsKICBjb25zdGV4cHIgYXV0byBsaW1pdCA9IHN0YXRpY19jYXN0PHN0ZDo6c2l6ZV90Pig4KTsKICBjb25zdGV4cHIgYXV0byB0ZXh0ID0gbXk6OnRydW5jYXRlPGxpbWl0PihTT01FVEVYVCk7Cn0KCmludAptYWluKCkKewogIHN0ZDo6cHJpbnRmKCJ0ZXh0ID0gXCIlc1wiXG4iLCB0ZXh0LmRhdGEoKSk7CiAgc3RkOjpwcmludGYoImxlbih0ZXh0KSA9ICVsdSA8PSAlbHVcbiIsIHN0ZDo6c3RybGVuKHRleHQuZGF0YSgpKSwgbGltaXQpOwogIHN0ZDo6cHJpbnRmKCJ0ZXh0ID0gXCIlc1wiXG4iLCBteTo6dHJ1bmNhdGU8ND4oU09NRVRFWFQpLmRhdGEoKSk7Cn0K