#pragma once /**************************************************************************************** * * * MOUNT CONTROL COMPONENTS LIBRARY * * * * * * IMPLEMENTATION OF OPERATIONAL ERROR * * * ****************************************************************************************/ #include #include #include #include "mcc_concepts.h" namespace mcc::impl { typedef std::error_code MccError; // library-wide definition of operational error } // namespace mcc::impl template <> struct std::formatter { template constexpr ParseContext::iterator parse(ParseContext& ctx) { auto it = ctx.begin(); if (it == ctx.end()) { return it; } _currFmt.clear(); _delim = " "; for (; it != ctx.end(); ++it) { switch (*it) { case '#': // numerical error value _currFmt.push_back(*it); break; case '@': // error category name _currFmt.push_back(*it); break; case '^': // error message _currFmt.push_back(*it); break; case '_': // while (it++ != ctx.end() || it++ != '}' || it++ != '_') { // _currFmt.push_back(*(++it)); // } if (it++ != ctx.end() || it++ != '}') { _delim = *(++it); } case '}': if (_currFmt.empty()) { _currFmt = "#@^"; } return it; default: break; } } return it; } template FmtContext::iterator format(mcc::impl::MccError const& err, FmtContext& ctx) const { std::ostringstream out; size_t idx = 0; for (auto const& fmt_sym : _currFmt) { switch (fmt_sym) { case '#': out << err.value(); ++idx; break; case '@': out << err.category().name(); ++idx; break; case '^': out << err.message(); ++idx; break; default: break; } if (idx < _currFmt.size()) { out << _delim; } } return std::ranges::copy(std::move(out).str(), ctx.out()).out; } private: std::string _currFmt{}, _delim{" "}; }; static_assert(mcc::mcc_error_c, ""); // // a helper formatter impelementation // template // requires std::is_enum_v // struct std::formatter : std::formatter, char> { // auto format(T e, auto& ctx) const // { // return formatter>::format(std::underlying_type_t(e), ctx); // } // }; // enum class EE : int { A, B, C }; // static_assert(mcc::mcc_error_c, "");