• C++20 如何扩展format


    #include <iostream>
    #include <format>
    #include <type_traits>
    #include <string>
    
    class KeyValue
    {
    public:
        KeyValue(std::string key, int value) : m_key{ std::move(key) }, m_value{ value } { }
        auto& getKey() const { return m_key; }
        auto& getValue() const { return m_value; }
    private:
        std::string m_key;
        int m_value;
    };
    
    template <>
    class std::formatter<KeyValue>
    {
    public:
        auto parse(auto& context)
        {
            auto iter = context.begin();
            const auto end = context.end();
            if (iter == end || *iter == '}')
            {
                m_out = OutputType::KeyAndValue; // {}
                return iter;
            }
            switch (*iter)
            {
            case 'a': m_out = OutputType::Key; break; // {:a} -> key
            case 'b': m_out = OutputType::Value; break; // {:b} -> value
            case 'c': m_out = OutputType::KeyAndValue; break; // {:c} -> key and value
            default:
                throw std::format_error{ "Invalid KeyValue format specifier. " };
            }
    
            ++iter;
            if (iter != end && *iter != '}')
                throw std::format_error{ "Invalid KeyValue format specifier. " };
            return iter;
        }
        auto format(const KeyValue& kv, auto& context)
        {
            switch (m_out)
            {
                using enum OutputType;
            case Key:
                return std::format_to(context.out(), "{}", kv.getKey());
            case Value:
                return std::format_to(context.out(), "{}", kv.getValue());
            default:
                return std::format_to(context.out(), "{} - {}", kv.getKey(), kv.getValue());
            }
        }
    private:
        enum class OutputType
        {
            Key, Value, KeyAndValue
        };
        OutputType m_out{ OutputType::KeyAndValue };
    };
    
    
    struct Point { int x, y; };
    
    template <>
    class std::formatter<Point>
    {
    public:
        typename std::format_parse_context::iterator parse(std::format_parse_context& context)
        {
            auto iter = context.begin();
            for (; iter != context.end() && *iter != '}'; ++iter)
            {
                if (*iter == '#') { m_hashtag = true; }
                else throw std::format_error{ "Invalid KeyValue format specifier. " };
            }
            return iter;
        }
    
        typename std::format_context::iterator format(const Point& p, std::format_context& context)
        {
            char left = m_hashtag ? '[' : '(';
            char right = m_hashtag ? ']' : ')';
            return std::format_to(context.out(), "{}{}, {}{}", left, p.x, p.y, right);
        }
    
    private:
        bool m_hashtag = false;
    };
    
    int main()
    {
        KeyValue kv{ "Key", 0 };
        Point p{ .x = 1, .y = 1 };
        try
        {
            std::cout << std::format("{}
    ", kv);
            std::cout << std::format("{:a}
    ", kv);
            std::cout << std::format("{:b}
    ", kv);
            std::cout << std::format("{:c}
    ", kv);
            std::cout << std::format("{:ab}
    ", kv);
        }
        catch (const std::exception& e)
        {
            std::cerr << e.what() << '
    ';
        }
    
        try
        {
            std::cout << std::format("{}
    ", p);
            //std::cout << std::format("{:#}
    ", p);
            //std::cout << std::format("{:#x}
    ", p);
        }
        catch (const std::exception& e)
        {
            std::cerr << e.what() << '
    ';
        }
    
    }
  • 相关阅读:
    Atitti  css   transition Animation differ区别
    Atitit 游戏引擎物理系统(1)爆炸效果
    Atitit.rsa密钥生成器的attilax总结
    新特性AAtitti css3 新特性attilax总结titti css
    Atitit 异常的实现原理 与用户业务异常
    Atitit.uke 团队建设的组织与运营之道attilax总结
    atitit 业务 触发器原理. 与事件原理 docx
    Atitit 基于dom的游戏引擎
    Atitit 团队建设的知识管理
    Javascript判断页面刷新或关闭的方法(转)
  • 原文地址:https://www.cnblogs.com/MasterYan576356467/p/15502458.html
Copyright © 2020-2023  润新知