| /** @file |
| |
| Forward definitions for BufferWriter formatting. |
| |
| @section license License |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include <cstdlib> |
| #include <utility> |
| #include <cstring> |
| #include <vector> |
| #include <map> |
| |
| #include "tscpp/util/TextView.h" |
| #include "tscore/ink_assert.h" |
| |
| namespace ts |
| { |
| /** A parsed version of a format specifier. |
| */ |
| struct BWFSpec { |
| using self_type = BWFSpec; ///< Self reference type. |
| static constexpr char DEFAULT_TYPE = 'g'; ///< Default format type. |
| |
| /// Constructor a default instance. |
| constexpr BWFSpec() {} |
| |
| /// Construct by parsing @a fmt. |
| BWFSpec(TextView fmt); |
| |
| char _fill = ' '; ///< Fill character. |
| char _sign = '-'; ///< Numeric sign style, space + - |
| enum class Align : char { |
| NONE, ///< No alignment. |
| LEFT, ///< Left alignment '<'. |
| RIGHT, ///< Right alignment '>'. |
| CENTER, ///< Center alignment '^'. |
| SIGN ///< Align plus/minus sign before numeric fill. '=' |
| } _align = Align::NONE; ///< Output field alignment. |
| char _type = DEFAULT_TYPE; ///< Type / radix indicator. |
| bool _radix_lead_p = false; ///< Print leading radix indication. |
| // @a _min is unsigned because there's no point in an invalid default, 0 works fine. |
| unsigned int _min = 0; ///< Minimum width. |
| int _prec = -1; ///< Precision |
| unsigned int _max = std::numeric_limits<unsigned int>::max(); ///< Maximum width |
| int _idx = -1; ///< Positional "name" of the specification. |
| std::string_view _name; ///< Name of the specification. |
| std::string_view _ext; ///< Extension if provided. |
| |
| static const self_type DEFAULT; |
| |
| /// Validate @a c is a specifier type indicator. |
| static bool is_type(char c); |
| /// Check if the type flag is numeric. |
| static bool is_numeric_type(char c); |
| /// Check if the type is an upper case variant. |
| static bool is_upper_case_type(char c); |
| /// Check if the type @a in @a this is numeric. |
| bool has_numeric_type() const; |
| /// Check if the type in @a this is an upper case variant. |
| bool has_upper_case_type() const; |
| /// Check if the type is a raw pointer. |
| bool has_pointer_type() const; |
| |
| protected: |
| /// Validate character is alignment character and return the appropriate enum value. |
| Align align_of(char c); |
| |
| /// Validate is sign indicator. |
| bool is_sign(char c); |
| |
| /// Handrolled initialization the character syntactic property data. |
| static const struct Property { |
| Property(); ///< Default constructor, creates initialized flag set. |
| /// Flag storage, indexed by character value. |
| uint8_t _data[0x100]; |
| /// Flag mask values. |
| static constexpr uint8_t ALIGN_MASK = 0x0F; ///< Alignment type. |
| static constexpr uint8_t TYPE_CHAR = 0x10; ///< A valid type character. |
| static constexpr uint8_t UPPER_TYPE_CHAR = 0x20; ///< Upper case flag. |
| static constexpr uint8_t NUMERIC_TYPE_CHAR = 0x40; ///< Numeric output. |
| static constexpr uint8_t SIGN_CHAR = 0x80; ///< Is sign character. |
| } _prop; |
| }; |
| |
| inline BWFSpec::Align |
| BWFSpec::align_of(char c) |
| { |
| return static_cast<Align>(_prop._data[static_cast<unsigned>(c)] & Property::ALIGN_MASK); |
| } |
| |
| inline bool |
| BWFSpec::is_sign(char c) |
| { |
| return _prop._data[static_cast<unsigned>(c)] & Property::SIGN_CHAR; |
| } |
| |
| inline bool |
| BWFSpec::is_type(char c) |
| { |
| return _prop._data[static_cast<unsigned>(c)] & Property::TYPE_CHAR; |
| } |
| |
| inline bool |
| BWFSpec::is_upper_case_type(char c) |
| { |
| return _prop._data[static_cast<unsigned>(c)] & Property::UPPER_TYPE_CHAR; |
| } |
| |
| inline bool |
| BWFSpec::has_numeric_type() const |
| { |
| return _prop._data[static_cast<unsigned>(_type)] & Property::NUMERIC_TYPE_CHAR; |
| } |
| |
| inline bool |
| BWFSpec::has_upper_case_type() const |
| { |
| return _prop._data[static_cast<unsigned>(_type)] & Property::UPPER_TYPE_CHAR; |
| } |
| |
| inline bool |
| BWFSpec::has_pointer_type() const |
| { |
| return _type == 'p' || _type == 'P'; |
| } |
| |
| class BWFormat; |
| |
| class BufferWriter; |
| |
| } // namespace ts |