//===-- String utils --------------------------------------------*- 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 // //===----------------------------------------------------------------------===// // // Standalone string utility functions. Utilities requiring memory allocations // should be placed in allocating_string_utils.h intead. // //===----------------------------------------------------------------------===// #ifndef LLVM_LIBC_SRC_STRING_STRING_UTILS_H #define LLVM_LIBC_SRC_STRING_STRING_UTILS_H #include "src/__support/CPP/bitset.h" #include "src/__support/macros/config.h" #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY #include "src/string/memory_utils/inline_bzero.h" #include "src/string/memory_utils/inline_memcpy.h" #include <stddef.h> // For size_t namespace LIBC_NAMESPACE_DECL { namespace internal { template <typename Word> LIBC_INLINE constexpr Word repeat_byte(Word byte) { … } // The goal of this function is to take in a block of arbitrary size and return // if it has any bytes equal to zero without branching. This is done by // transforming the block such that zero bytes become non-zero and non-zero // bytes become zero. // The first transformation relies on the properties of carrying in arithmetic // subtraction. Specifically, if 0x01 is subtracted from a byte that is 0x00, // then the result for that byte must be equal to 0xff (or 0xfe if the next byte // needs a carry as well). // The next transformation is a simple mask. All zero bytes will have the high // bit set after the subtraction, so each byte is masked with 0x80. This narrows // the set of bytes that result in a non-zero value to only zero bytes and bytes // with the high bit and any other bit set. // The final transformation masks the result of the previous transformations // with the inverse of the original byte. This means that any byte that had the // high bit set will no longer have it set, narrowing the list of bytes which // result in non-zero values to just the zero byte. template <typename Word> LIBC_INLINE constexpr bool has_zeroes(Word block) { … } template <typename Word> LIBC_INLINE size_t string_length_wide_read(const char *src) { … } LIBC_INLINE size_t string_length_byte_read(const char *src) { … } // Returns the length of a string, denoted by the first occurrence // of a null terminator. LIBC_INLINE size_t string_length(const char *src) { … } template <typename Word> LIBC_INLINE void *find_first_character_wide_read(const unsigned char *src, unsigned char ch, size_t n) { … } LIBC_INLINE void *find_first_character_byte_read(const unsigned char *src, unsigned char ch, size_t n) { … } // Returns the first occurrence of 'ch' within the first 'n' characters of // 'src'. If 'ch' is not found, returns nullptr. LIBC_INLINE void *find_first_character(const unsigned char *src, unsigned char ch, size_t max_strlen) { … } // Returns the maximum length span that contains only characters not found in // 'segment'. If no characters are found, returns the length of 'src'. LIBC_INLINE size_t complementary_span(const char *src, const char *segment) { … } // Given the similarities between strtok and strtok_r, we can implement both // using a utility function. On the first call, 'src' is scanned for the // first character not found in 'delimiter_string'. Once found, it scans until // the first character in the 'delimiter_string' or the null terminator is // found. We define this span as a token. The end of the token is appended with // a null terminator, and the token is returned. The point where the last token // is found is then stored within 'context' for subsequent calls. Subsequent // calls will use 'context' when a nullptr is passed in for 'src'. Once the null // terminating character is reached, returns a nullptr. template <bool SkipDelim = true> LIBC_INLINE char *string_token(char *__restrict src, const char *__restrict delimiter_string, char **__restrict saveptr) { … } LIBC_INLINE size_t strlcpy(char *__restrict dst, const char *__restrict src, size_t size) { … } template <bool ReturnNull = true> LIBC_INLINE constexpr static char *strchr_implementation(const char *src, int c) { … } LIBC_INLINE constexpr static char *strrchr_implementation(const char *src, int c) { … } } // namespace internal } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC_SRC_STRING_STRING_UTILS_H