Loading

std::format格式化自定义类型

示例代码

#include <string>
#include <iostream>
// 导入format
#include <format>


struct Vector4D
{
	int x, y, z, s;
};

// std::formatter格式化Vector4D
namespace std {

	template <>
	class formatter<Vector4D> {
	public:
		explicit formatter() noexcept
			: _fmt(OutputFormat::XYZS)
		{ }
		
		typename std::basic_format_parse_context<char>::iterator
			parse(std::basic_format_parse_context<char>& pc) {
			if (pc.begin() == pc.end() || *pc.begin() == '}') {
				_fmt = OutputFormat::XYZS;
				return pc.end();
			}
			switch (*pc.begin()) {
			case 'X':
				_fmt = OutputFormat::X;
				break;
			case 'Y':
				_fmt = OutputFormat::Y;
				break;
			case 'Z':
				_fmt = OutputFormat::Z;
				break;
			case 'S':
				_fmt = OutputFormat::S;
			default:
				throw std::format_error("Invalid format specification");
			}
			return pc.begin() + 1;
		}

		template <typename OutputIt>
		std::basic_format_context<OutputIt, char>::iterator
			format(const Vector4D& value, std::basic_format_context<OutputIt, char>& fc) const noexcept {
			std::string valueString;
			switch (_fmt) {
			case OutputFormat::XYZS: {
				valueString = std::format("X={}, Y={}, Z={}, S={}",
					value.x, value.y, value.z, value.s);
				break;
			}
			case OutputFormat::X:
				valueString = std::format("X={}", value.x);
				break;
			case OutputFormat::Y:
				valueString = std::format("Y={}", value.y);
				break;
			case OutputFormat::Z:
				valueString = std::format("Z={}", value.z);
				break;
			case OutputFormat::S:
				valueString = std::format("S={}", value.s);
				break;
			}

			auto output = fc.out();
			for (auto ch : valueString) {
				*output++ = ch;
			}

			return output;
		}

	private:
		enum class OutputFormat {
			X,
			Y,
			Z,
			S,
			XYZS
		};

		OutputFormat _fmt;
	};

} // namespace std



int main()
{
	Vector4D v = { 1, 2, 3, 4 };
	std::cout << std::format("{}", v) << std::endl;
	return 0;
}
posted @ 2022-08-10 18:02  WindSnowLi  阅读(230)  评论(0编辑  收藏  举报