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_STRINGUTIL_MESSAGE_MAPPER_H
10 #define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_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"
15 #include "src/__support/macros/config.h"
18 namespace LIBC_NAMESPACE_DECL
{
24 constexpr MsgMapping() : num(0), msg() { ; }
26 constexpr MsgMapping(int init_num
, const char *init_msg
)
27 : num(init_num
), msg(init_msg
) {
32 template <size_t N
> using MsgTable
= cpp::array
<MsgMapping
, N
>;
34 template <size_t N
> constexpr size_t total_str_len(const MsgTable
<N
> &table
) {
36 for (size_t i
= 0; i
< table
.size(); ++i
) {
37 // add 1 for the null terminator.
38 total
+= table
[i
].msg
.size() + 1;
43 template <size_t N
> constexpr size_t max_key_val(const MsgTable
<N
> &table
) {
45 for (size_t i
= 0; i
< table
.size(); ++i
) {
46 if (table
[i
].num
> max
) {
50 // max will never be negative since the starting value is 0. This is good,
51 // since it's used as a length.
52 return static_cast<size_t>(max
);
55 template <size_t ARR_SIZE
, size_t TOTAL_STR_LEN
> class MessageMapper
{
56 int msg_offsets
[ARR_SIZE
] = {-1};
57 char string_array
[TOTAL_STR_LEN
] = {'\0'};
60 template <size_t N
> constexpr MessageMapper(const MsgTable
<N
> &table
) {
61 cpp::string_view string_mappings
[ARR_SIZE
] = {""};
62 for (size_t i
= 0; i
< table
.size(); ++i
)
63 string_mappings
[table
[i
].num
] = table
[i
].msg
;
65 int string_array_index
= 0;
66 for (size_t cur_num
= 0; cur_num
< ARR_SIZE
; ++cur_num
) {
67 if (string_mappings
[cur_num
].size() != 0) {
68 msg_offsets
[cur_num
] = string_array_index
;
69 // No need to replace with proper strcpy, this is evaluated at compile
71 for (size_t i
= 0; i
< string_mappings
[cur_num
].size() + 1;
72 ++i
, ++string_array_index
) {
73 string_array
[string_array_index
] = string_mappings
[cur_num
][i
];
76 msg_offsets
[cur_num
] = -1;
81 cpp::optional
<cpp::string_view
> get_str(int num
) const {
82 if (num
>= 0 && static_cast<size_t>(num
) < ARR_SIZE
&&
83 msg_offsets
[num
] != -1) {
84 return {string_array
+ msg_offsets
[num
]};
86 return cpp::optional
<cpp::string_view
>();
91 template <size_t N1
, size_t N2
>
92 constexpr MsgTable
<N1
+ N2
> operator+(const MsgTable
<N1
> &t1
,
93 const MsgTable
<N2
> &t2
) {
94 MsgTable
<N1
+ N2
> res
{};
95 for (size_t i
= 0; i
< N1
; ++i
)
97 for (size_t i
= 0; i
< N2
; ++i
)
102 } // namespace LIBC_NAMESPACE_DECL
104 #endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_MESSAGE_MAPPER_H