[libc] Create cpp::IntegerSequence analogous to std::integer_sequence

Reviewed By: sivachandra, lntue

Differential Revision: https://reviews.llvm.org/D119511
This commit is contained in:
Alex Brachet 2022-02-14 18:13:00 +00:00
parent f2a7f83595
commit 6291454658
4 changed files with 87 additions and 0 deletions

View file

@ -10,6 +10,7 @@ add_header_library(
Limits.h Limits.h
StringView.h StringView.h
TypeTraits.h TypeTraits.h
Utility.h
) )
add_header_library( add_header_library(

View file

@ -0,0 +1,39 @@
//===-- Analogous to <utility> ----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_H
#define LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_H
#include "src/__support/CPP/TypeTraits.h"
namespace __llvm_libc::cpp {
template <typename T, T... Seq> struct IntegerSequence {
static_assert(IsIntegral<T>::Value);
template <T Next> using append = IntegerSequence<T, Seq..., Next>;
};
namespace internal {
template <typename T, int N> struct MakeIntegerSequence {
using type = typename MakeIntegerSequence<T, N - 1>::type::template append<N>;
};
template <typename T> struct MakeIntegerSequence<T, -1> {
using type = IntegerSequence<T>;
};
} // namespace internal
template <typename T, int N>
using MakeIntegerSequence =
typename internal::MakeIntegerSequence<T, N - 1>::type;
} // namespace __llvm_libc::cpp
#endif // LLVM_LIBC_SRC_SUPPORT_CPP_UTILITY_H

View file

@ -49,3 +49,13 @@ add_libc_unittest(
DEPENDS DEPENDS
libc.src.__support.CPP.vector libc.src.__support.CPP.vector
) )
add_libc_unittest(
int_seq_test
SUITE
libc_cpp_utils_unittests
SRCS
integer_sequence_test.cpp
DEPENDS
libc.src.__support.CPP.standalone_cpp
)

View file

@ -0,0 +1,37 @@
//===-- Unittests for IntegerSequence -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "src/__support/CPP/Utility.h"
#include "utils/UnitTest/Test.h"
using namespace __llvm_libc::cpp;
TEST(LlvmLibcIntegerSequencetTest, Basic) {
EXPECT_TRUE((IsSameV<IntegerSequence<int>, MakeIntegerSequence<int, 0>>));
using ISeq = IntegerSequence<int, 0, 1, 2, 3>;
EXPECT_TRUE((IsSameV<ISeq, MakeIntegerSequence<int, 4>>));
using LSeq = IntegerSequence<long, 0, 1, 2, 3>;
EXPECT_TRUE((IsSameV<LSeq, MakeIntegerSequence<long, 4>>));
using ULLSeq = IntegerSequence<unsigned long long, 0ull, 1ull, 2ull, 3ull>;
EXPECT_TRUE((IsSameV<ULLSeq, MakeIntegerSequence<unsigned long long, 4>>));
}
template <typename T, T... Ts>
bool checkArray(IntegerSequence<T, Ts...> seq) {
T arr[sizeof...(Ts)]{Ts...};
for (T i = 0; i < static_cast<T>(sizeof...(Ts)); i++)
if (arr[i] != i)
return false;
return true;
}
TEST(LlvmLibcIntegerSequencetTest, Many) {
EXPECT_TRUE(checkArray(MakeIntegerSequence<int, 100>{}));
}