brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · 2d67477 Raw
123 lines · c
1//===-- lib/Evaluate/character.h --------------------------------*- 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 FORTRAN_EVALUATE_CHARACTER_H_10#define FORTRAN_EVALUATE_CHARACTER_H_11 12#include "flang/Evaluate/type.h"13#include <string>14 15// Provides implementations of intrinsic functions operating on character16// scalars.17 18namespace Fortran::evaluate {19 20template <int KIND> class CharacterUtils {21  using Character = Scalar<Type<TypeCategory::Character, KIND>>;22  using CharT = typename Character::value_type;23 24public:25  // CHAR also implements ACHAR under assumption that character encodings26  // contain ASCII27  static Character CHAR(std::uint64_t code) {28    return Character{{static_cast<CharT>(code)}};29  }30 31  // ICHAR also implements IACHAR under assumption that character encodings32  // contain ASCII33  static std::int64_t ICHAR(const Character &c) {34    CHECK(c.length() == 1);35    // Convert first to an unsigned integer type to avoid sign extension36    return static_cast<common::HostUnsignedIntType<(8 * KIND)>>(c[0]);37  }38 39  static Character NEW_LINE() { return Character{{NewLine()}}; }40 41  static Character ADJUSTL(const Character &str) {42    auto pos{str.find_first_not_of(Space())};43    if (pos != Character::npos && pos != 0) {44      return Character{str.substr(pos) + Character(pos, Space())};45    }46    // else empty or only spaces, or no leading spaces47    return str;48  }49 50  static Character ADJUSTR(const Character &str) {51    auto pos{str.find_last_not_of(Space())};52    if (pos != Character::npos && pos != str.length() - 1) {53      auto delta{str.length() - 1 - pos};54      return Character{Character(delta, Space()) + str.substr(0, pos + 1)};55    }56    // else empty or only spaces, or no trailing spaces57    return str;58  }59 60  static ConstantSubscript INDEX(61      const Character &str, const Character &substr, bool back = false) {62    auto pos{back ? str.rfind(substr) : str.find(substr)};63    return static_cast<ConstantSubscript>(pos == str.npos ? 0 : pos + 1);64  }65 66  static ConstantSubscript SCAN(67      const Character &str, const Character &set, bool back = false) {68    auto pos{back ? str.find_last_of(set) : str.find_first_of(set)};69    return static_cast<ConstantSubscript>(pos == str.npos ? 0 : pos + 1);70  }71 72  static ConstantSubscript VERIFY(73      const Character &str, const Character &set, bool back = false) {74    auto pos{back ? str.find_last_not_of(set) : str.find_first_not_of(set)};75    return static_cast<ConstantSubscript>(pos == str.npos ? 0 : pos + 1);76  }77 78  // Resize adds spaces on the right if the new size is bigger than the79  // original, or by trimming the rightmost characters otherwise.80  static Character Resize(const Character &str, std::size_t newLength) {81    auto oldLength{str.length()};82    if (newLength > oldLength) {83      return str + Character(newLength - oldLength, Space());84    } else {85      return str.substr(0, newLength);86    }87  }88 89  static ConstantSubscript LEN_TRIM(const Character &str) {90    auto j{str.length()};91    for (; j >= 1; --j) {92      if (str[j - 1] != ' ') {93        break;94      }95    }96    return static_cast<ConstantSubscript>(j);97  }98 99  static Character REPEAT(const Character &str, ConstantSubscript ncopies) {100    Character result;101    if (!str.empty() && ncopies > 0) {102      result.reserve(ncopies * str.size());103      while (ncopies-- > 0) {104        result += str;105      }106    }107    return result;108  }109 110  static Character TRIM(const Character &str) {111    return str.substr(0, LEN_TRIM(str));112  }113 114private:115  // Following helpers assume that character encodings contain ASCII116  static constexpr CharT Space() { return 0x20; }117  static constexpr CharT NewLine() { return 0x0a; }118};119 120} // namespace Fortran::evaluate121 122#endif // FORTRAN_EVALUATE_CHARACTER_H_123