1 //===-- A class for number to string mappings -------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_MESSAGE_MAPPER_H
10 #define LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_MESSAGE_MAPPER_H
12 #include "src/__support/CPP/array.h"
13 #include "src/__support/CPP/optional.h"
14 #include "src/__support/CPP/string_view.h"
17 namespace LIBC_NAMESPACE
{
23 constexpr MsgMapping() : num(0), msg() { ; }
25 constexpr MsgMapping(int init_num
, const char *init_msg
)
26 : num(init_num
), msg(init_msg
) {
31 template <size_t N
> using MsgTable
= cpp::array
<MsgMapping
, N
>;
33 template <size_t N
> constexpr size_t total_str_len(const MsgTable
<N
> &table
) {
35 for (size_t i
= 0; i
< table
.size(); ++i
) {
36 // add 1 for the null terminator.
37 total
+= table
[i
].msg
.size() + 1;
42 template <size_t N
> constexpr size_t max_key_val(const MsgTable
<N
> &table
) {
44 for (size_t i
= 0; i
< table
.size(); ++i
) {
45 if (table
[i
].num
> max
) {
49 // max will never be negative since the starting value is 0. This is good,
50 // since it's used as a length.
51 return static_cast<size_t>(max
);
54 template <size_t ARR_SIZE
, size_t TOTAL_STR_LEN
> class MessageMapper
{
55 int msg_offsets
[ARR_SIZE
] = {-1};
56 char string_array
[TOTAL_STR_LEN
] = {'\0'};
59 template <size_t N
> constexpr MessageMapper(const MsgTable
<N
> &table
) {
60 cpp::string_view string_mappings
[ARR_SIZE
] = {""};
61 for (size_t i
= 0; i
< table
.size(); ++i
)
62 string_mappings
[table
[i
].num
] = table
[i
].msg
;
64 int string_array_index
= 0;
65 for (size_t cur_num
= 0; cur_num
< ARR_SIZE
; ++cur_num
) {
66 if (string_mappings
[cur_num
].size() != 0) {
67 msg_offsets
[cur_num
] = string_array_index
;
68 // No need to replace with proper strcpy, this is evaluated at compile
70 for (size_t i
= 0; i
< string_mappings
[cur_num
].size() + 1;
71 ++i
, ++string_array_index
) {
72 string_array
[string_array_index
] = string_mappings
[cur_num
][i
];
75 msg_offsets
[cur_num
] = -1;
80 cpp::optional
<cpp::string_view
> get_str(int num
) const {
81 if (num
>= 0 && static_cast<size_t>(num
) < ARR_SIZE
&&
82 msg_offsets
[num
] != -1) {
83 return {string_array
+ msg_offsets
[num
]};
85 return cpp::optional
<cpp::string_view
>();
90 template <size_t N1
, size_t N2
>
91 constexpr MsgTable
<N1
+ N2
> operator+(const MsgTable
<N1
> &t1
,
92 const MsgTable
<N2
> &t2
) {
93 MsgTable
<N1
+ N2
> res
{};
94 for (size_t i
= 0; i
< N1
; ++i
)
96 for (size_t i
= 0; i
< N2
; ++i
)
101 } // namespace LIBC_NAMESPACE
103 #endif // LLVM_LIBC_SRC___SUPPORT_STRING_UTIL_MESSAGE_MAPPER_H