Skip to content

Commit

Permalink
Merge pull request #8 from PragmaTwice/fixed-string-test
Browse files Browse the repository at this point in the history
Add unit tests and type-level conversion for fixed_string
  • Loading branch information
PragmaTwice authored Jan 16, 2021
2 parents cf632f5 + aff6145 commit 1caebea
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
61 changes: 61 additions & 0 deletions include/protopuf/fixed_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ namespace pp {
return true;
}

template <typename CharT, std::size_t N, std::size_t M>
constexpr auto operator!=(const basic_fixed_string<CharT, N> &l, const basic_fixed_string<CharT, M> &r) {
return !(l == r);
}

template <typename CharT, std::size_t N, std::size_t M>
constexpr auto operator<=>(const basic_fixed_string<CharT, N> &l, const basic_fixed_string<CharT, M> &r) {
for (std::size_t i = 0; i < std::min(N, M); ++i) {
Expand All @@ -73,6 +78,62 @@ namespace pp {
constexpr value_type operator()() const noexcept { return value; }
};

template <std::size_t, auto...>
struct constant_get_impl;

template <std::size_t N, auto v1, auto... vn>
struct constant_get_impl<N, v1, vn...> {
static constexpr auto value = constant_get_impl<N - 1, vn...>::value;
};

template <auto v1, auto... vn>
struct constant_get_impl<0, v1, vn...> {
static constexpr auto value = v1;
};

template <std::size_t N, auto... v>
constexpr auto constant_get = constant_get_impl<N, v...>::value;

template <auto... v>
struct constant_tuple {
using type = constant_tuple;

static constexpr auto size = sizeof...(v);

template <std::size_t N>
static constexpr auto value = constant_get<N, v...>;

template <std::size_t N>
using value_type = decltype(value<N>);

template <std::size_t N>
constexpr decltype(auto) get() const {
return constant<constant_get<N, v...>>{};
}
};

template <typename T, T... v>
struct constant_array {
using type = constant_array;

static constexpr auto size = sizeof...(v);

template <std::size_t N>
static constexpr auto value = constant_get<N, v...>;

using value_type = T;

template <std::size_t N>
constexpr decltype(auto) get() const {
return constant<constant_get<N, v...>>{};
}
};

template <basic_fixed_string S>
constexpr auto expand_fixed_string = []<std::size_t... I>(std::index_sequence<I...>) {
return constant_array<typename decltype(S)::value_type, S.data[I]...>{};
}(std::make_index_sequence<decltype(S)::size>{});

template <basic_fixed_string S>
constexpr auto operator ""_f() {
return constant<S>{};
Expand Down
35 changes: 35 additions & 0 deletions test/fixed_string.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2020-2021 PragmaTwice
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>

#include <protopuf/fixed_string.h>

using namespace pp;
using namespace std;

GTEST_TEST(fixed_string, static) {
static_assert("x"_f() == "x"_f());
static_assert("xxx"_f() == "xxx"_f());
static_assert("x"_f() != "y"_f());
static_assert("x"_f() != "xx"_f());
static_assert("x"_f() < "y"_f());
static_assert("x"_f() < "xy"_f());
static_assert("x"_f() < "xa"_f());
static_assert("xy"_f() < "y"_f());
static_assert("xaa"_f() < "y"_f());

static_assert(is_same_v<decltype(expand_fixed_string<"hello">), const constant_array<char, 'h', 'e', 'l', 'l', 'o', 0>>);
static_assert(expand_fixed_string<"hello">.get<2>() == 'l' && expand_fixed_string<"hello">.get<3>() == 'l');
}

0 comments on commit 1caebea

Please sign in to comment.