1//===-- Standalone implementation of a char vector --------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIBC_SRC___SUPPORT_CHARVECTOR_H
10#define LLVM_LIBC_SRC___SUPPORT_CHARVECTOR_H
11
12#include "src/__support/common.h" // LIBC_INLINE
13
14#include <stddef.h> // size_t
15#include <stdlib.h> // malloc, realloc, free
16
17namespace LIBC_NAMESPACE {
18
19// This is very simple alternate of the std::string class. There is no
20// bounds check performed in any of the methods. The callers are expected to
21// do the checks before invoking the methods.
22//
23// This class will be extended as needed in future.
24
25class CharVector {
26 static constexpr size_t INIT_BUFF_SIZE = 64;
27 char local_buffer[INIT_BUFF_SIZE];
28 char *cur_str = local_buffer;
29 size_t cur_buff_size = INIT_BUFF_SIZE;
30 size_t index = 0;
31
32public:
33 CharVector() = default;
34 LIBC_INLINE ~CharVector() {
35 if (cur_str != local_buffer)
36 free(ptr: cur_str);
37 }
38
39 // append returns true on success and false on allocation failure.
40 LIBC_INLINE bool append(char new_char) {
41 // Subtract 1 for index starting at 0 and another for the null terminator.
42 if (index >= cur_buff_size - 2) {
43 // If the new character would cause the string to be longer than the
44 // buffer's size, attempt to allocate a new buffer.
45 cur_buff_size = cur_buff_size * 2;
46 if (cur_str == local_buffer) {
47 char *new_str;
48 new_str = reinterpret_cast<char *>(malloc(size: cur_buff_size));
49 if (new_str == nullptr) {
50 return false;
51 }
52 // TODO: replace with inline memcpy
53 for (size_t i = 0; i < index; ++i)
54 new_str[i] = cur_str[i];
55 cur_str = new_str;
56 } else {
57 cur_str = reinterpret_cast<char *>(realloc(ptr: cur_str, size: cur_buff_size));
58 if (cur_str == nullptr) {
59 return false;
60 }
61 }
62 }
63 cur_str[index] = new_char;
64 ++index;
65 return true;
66 }
67
68 LIBC_INLINE char *c_str() {
69 cur_str[index] = '\0';
70 return cur_str;
71 }
72
73 LIBC_INLINE size_t length() { return index; }
74};
75
76} // namespace LIBC_NAMESPACE
77
78#endif // LLVM_LIBC_SRC___SUPPORT_CHARVECTOR_H
79

source code of libc/src/__support/char_vector.h