brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 3f25ebf Raw
76 lines · c
1//===-- Shared Converter Utilities for printf -------------------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_CONVERTER_UTILS_H10#define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_CONVERTER_UTILS_H11 12#include "src/__support/CPP/limits.h"13#include "src/__support/macros/config.h"14#include "src/stdio/printf_core/core_structs.h"15 16#include <inttypes.h>17#include <stddef.h>18 19namespace LIBC_NAMESPACE_DECL {20namespace printf_core {21 22LIBC_INLINE uintmax_t apply_length_modifier(uintmax_t num,23                                            LengthSpec length_spec) {24  auto [lm, bw] = length_spec;25  switch (lm) {26  case LengthModifier::none:27    return num & cpp::numeric_limits<unsigned int>::max();28  case LengthModifier::l:29    return num & cpp::numeric_limits<unsigned long>::max();30  case LengthModifier::ll:31  case LengthModifier::L:32    return num & cpp::numeric_limits<unsigned long long>::max();33  case LengthModifier::h:34    return num & cpp::numeric_limits<unsigned short>::max();35  case LengthModifier::hh:36    return num & cpp::numeric_limits<unsigned char>::max();37  case LengthModifier::z:38    return num & cpp::numeric_limits<size_t>::max();39  case LengthModifier::t:40    // We don't have unsigned ptrdiff so uintptr_t is used, since we need an41    // unsigned type and ptrdiff is usually the same size as a pointer.42    static_assert(sizeof(ptrdiff_t) == sizeof(uintptr_t));43    return num & cpp::numeric_limits<uintptr_t>::max();44  case LengthModifier::j:45    return num; // j is intmax, so no mask is necessary.46  case LengthModifier::w:47  case LengthModifier::wf: {48    uintmax_t mask;49    if (bw == 0) {50      mask = 0;51    } else if (bw < sizeof(uintmax_t) * CHAR_BIT) {52      mask = (static_cast<uintmax_t>(1) << bw) - 1;53    } else {54      mask = UINTMAX_MAX;55    }56    return num & mask;57  }58  }59  __builtin_unreachable();60}61 62#define RET_IF_RESULT_NEGATIVE(func)                                           \63  {                                                                            \64    int result = (func);                                                       \65    if (result < 0)                                                            \66      return result;                                                           \67  }68 69// This is used to represent which direction the number should be rounded.70enum class RoundDirection { Up, Down, Even };71 72} // namespace printf_core73} // namespace LIBC_NAMESPACE_DECL74 75#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_CONVERTER_UTILS_H76