Constexpr ``fmt::formatter::parse`` for C++20 (#3942)

This commit is contained in:
Antoine Prouvost 2025-05-16 17:44:21 +02:00 committed by GitHub
parent 39988503c8
commit aaae25ff04
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 212 additions and 207 deletions

View File

@ -15,7 +15,6 @@
#include <fmt/format.h>
#include "mamba/specs/error.hpp"
#include "mamba/util/tuple_hash.hpp"
namespace mamba::specs
{
@ -152,28 +151,41 @@ namespace mamba::specs
template <>
struct fmt::formatter<mamba::specs::BuildNumberPredicate>
{
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw format_error("invalid format");
}
return ctx.begin();
}
auto format(const ::mamba::specs::BuildNumberPredicate& pred, format_context& ctx) const
-> decltype(ctx.out());
-> format_context::iterator;
};
template <>
struct fmt::formatter<mamba::specs::BuildNumberSpec>
{
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw format_error("invalid format");
}
return ctx.begin();
}
auto format(const ::mamba::specs::BuildNumberSpec& spec, format_context& ctx) const
-> decltype(ctx.out());
-> format_context::iterator;
};
template <>
struct std::hash<mamba::specs::BuildNumberSpec>
{
auto operator()(const mamba::specs::BuildNumberSpec& spec) const -> std::size_t
{
return mamba::util::hash_vals(spec.to_string());
}
auto operator()(const mamba::specs::BuildNumberSpec& spec) const -> std::size_t;
};
#endif

View File

@ -15,7 +15,6 @@
#include "mamba/specs/error.hpp"
#include "mamba/specs/glob_spec.hpp"
#include "mamba/specs/regex_spec.hpp"
#include "mamba/util/tuple_hash.hpp"
namespace mamba::specs
{
@ -72,19 +71,24 @@ namespace mamba::specs
template <>
struct fmt::formatter<mamba::specs::ChimeraStringSpec>
{
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto format(const ::mamba::specs::ChimeraStringSpec& spec, format_context& ctx) const
-> decltype(ctx.out());
-> format_context::iterator;
};
template <>
struct std::hash<mamba::specs::ChimeraStringSpec>
{
auto operator()(const mamba::specs::ChimeraStringSpec& spec) const -> std::size_t
{
return mamba::util::hash_vals(spec.to_string());
}
auto operator()(const mamba::specs::ChimeraStringSpec& spec) const -> std::size_t;
};
#endif

View File

@ -63,19 +63,24 @@ namespace mamba::specs
template <>
struct fmt::formatter<mamba::specs::GlobSpec>
{
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto format(const ::mamba::specs::GlobSpec& spec, format_context& ctx) const
-> decltype(ctx.out());
-> format_context::iterator;
};
template <>
struct std::hash<mamba::specs::GlobSpec>
{
auto operator()(const mamba::specs::GlobSpec& spec) const -> std::size_t
{
return std::hash<std::string>{}(spec.to_string());
}
auto operator()(const mamba::specs::GlobSpec& spec) const -> std::size_t;
};
#endif

View File

@ -229,10 +229,30 @@ namespace mamba::specs
template <>
struct fmt::formatter<::mamba::specs::MatchSpec>
{
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto format(const ::mamba::specs::MatchSpec& spec, format_context& ctx) const
-> decltype(ctx.out());
-> format_context::iterator;
};
template <>
struct std::hash<mamba::specs::MatchSpec>
{
auto operator()(const mamba::specs::MatchSpec& spec) const -> std::size_t;
};
template <>
struct std::hash<mamba::specs::MatchSpec::ExtraMembers>
{
auto operator()(const mamba::specs::MatchSpec::ExtraMembers& extra) const -> std::size_t;
};
/*********************************
@ -304,40 +324,4 @@ namespace mamba::specs
}
}
template <>
struct std::hash<mamba::specs::MatchSpec>
{
auto operator()(const mamba::specs::MatchSpec& spec) const -> std::size_t
{
return mamba::util::hash_vals(
spec.channel(),
spec.version(),
spec.name(),
spec.build_string(),
spec.name_space(),
spec.build_number(),
spec.extra_members_hash()
);
}
};
template <>
struct std::hash<mamba::specs::MatchSpec::ExtraMembers>
{
auto operator()(const mamba::specs::MatchSpec::ExtraMembers& extra) const -> std::size_t
{
return mamba::util::hash_vals(
extra.filename,
extra.subdirs,
extra.md5,
extra.sha256,
extra.license,
extra.license_family,
extra.features,
extra.track_features,
extra.optional
);
}
};
#endif

View File

@ -69,19 +69,24 @@ namespace mamba::specs
template <>
struct fmt::formatter<mamba::specs::RegexSpec>
{
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto format(const ::mamba::specs::RegexSpec& spec, format_context& ctx) const
-> decltype(ctx.out());
-> format_context::iterator;
};
template <>
struct std::hash<mamba::specs::RegexSpec>
{
auto operator()(const mamba::specs::RegexSpec& spec) const -> std::size_t
{
return std::hash<std::string>{}(spec.to_string());
}
auto operator()(const mamba::specs::RegexSpec& spec) const -> std::size_t;
};
#endif

View File

@ -214,19 +214,35 @@ namespace mamba::specs
template <>
struct fmt::formatter<mamba::specs::VersionPartAtom>
{
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto format(const ::mamba::specs::VersionPartAtom atom, format_context& ctx) const
-> decltype(ctx.out());
-> format_context::iterator;
};
template <>
struct fmt::formatter<mamba::specs::VersionPart>
{
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto format(const ::mamba::specs::VersionPart atom, format_context& ctx) const
-> decltype(ctx.out());
-> format_context::iterator;
};
template <>

View File

@ -17,7 +17,6 @@
#include "mamba/specs/error.hpp"
#include "mamba/specs/version.hpp"
#include "mamba/util/flat_bool_expr_tree.hpp"
#include "mamba/util/tuple_hash.hpp"
namespace mamba::specs
{
@ -265,10 +264,22 @@ struct fmt::formatter<mamba::specs::VersionPredicate>
*/
bool conda_build_form = false;
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
const auto end = ctx.end();
for (auto it = ctx.begin(); it != end; ++it)
{
if (*it == 'b')
{
conda_build_form = true;
return ++it;
}
}
return ctx.begin();
}
auto format(const ::mamba::specs::VersionPredicate& pred, format_context& ctx) const
-> decltype(ctx.out());
-> format_context::iterator;
};
template <>
@ -279,28 +290,34 @@ struct fmt::formatter<mamba::specs::VersionSpec>
*/
bool conda_build_form = false;
auto parse(format_parse_context& ctx) -> decltype(ctx.begin());
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator
{
const auto end = ctx.end();
for (auto it = ctx.begin(); it != end; ++it)
{
if (*it == 'b')
{
conda_build_form = true;
return ++it;
}
}
return ctx.begin();
}
auto format(const ::mamba::specs::VersionSpec& spec, format_context& ctx) const
-> decltype(ctx.out());
-> format_context::iterator;
};
template <>
struct std::hash<mamba::specs::VersionPredicate>
{
auto operator()(const mamba::specs::VersionPredicate& pred) const -> std::size_t
{
return mamba::util::hash_vals(pred.to_string());
}
auto operator()(const mamba::specs::VersionPredicate& pred) const -> std::size_t;
};
template <>
struct std::hash<mamba::specs::VersionSpec>
{
auto operator()(const mamba::specs::VersionSpec& spec) const -> std::size_t
{
return mamba::util::hash_vals(spec.to_string());
}
auto operator()(const mamba::specs::VersionSpec& spec) const -> std::size_t;
};
#endif

View File

@ -6,12 +6,12 @@
#include <algorithm>
#include <charconv>
#include <stdexcept>
#include <fmt/format.h>
#include "mamba/specs/build_number_spec.hpp"
#include "mamba/util/string.hpp"
#include "mamba/util/tuple_hash.hpp"
namespace mamba::specs
{
@ -97,23 +97,11 @@ namespace mamba::specs
}
}
auto
fmt::formatter<mamba::specs::BuildNumberPredicate>::parse(format_parse_context& ctx)
-> decltype(ctx.begin())
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw format_error("invalid format");
}
return ctx.begin();
}
auto
fmt::formatter<mamba::specs::BuildNumberPredicate>::format(
const ::mamba::specs::BuildNumberPredicate& pred,
format_context& ctx
) const -> decltype(ctx.out())
) const -> format_context::iterator
{
using BuildNumberPredicate = typename mamba::specs::BuildNumberPredicate;
using BuildNumber = typename BuildNumberPredicate::BuildNumber;
@ -252,18 +240,6 @@ namespace mamba::specs
}
}
auto
fmt::formatter<mamba::specs::BuildNumberSpec>::parse(format_parse_context& ctx)
-> decltype(ctx.begin())
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw format_error("invalid format");
}
return ctx.begin();
}
auto
fmt::formatter<mamba::specs::BuildNumberSpec>::format(
const ::mamba::specs::BuildNumberSpec& spec,
@ -272,3 +248,10 @@ fmt::formatter<mamba::specs::BuildNumberSpec>::format(
{
return fmt::format_to(ctx.out(), "{}", spec.m_predicate);
}
auto
std::hash<mamba::specs::BuildNumberSpec>::operator()(const mamba::specs::BuildNumberSpec& spec) const
-> std::size_t
{
return mamba::util::hash_vals(spec.to_string());
}

View File

@ -13,6 +13,7 @@
#include "mamba/specs/chimera_string_spec.hpp"
#include "mamba/specs/regex_spec.hpp"
#include "mamba/util/string.hpp"
#include "mamba/util/tuple_hash.hpp"
namespace mamba::specs
{
@ -125,18 +126,6 @@ namespace mamba::specs
}
}
auto
fmt::formatter<mamba::specs::ChimeraStringSpec>::parse(format_parse_context& ctx)
-> decltype(ctx.begin())
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto
fmt::formatter<mamba::specs::ChimeraStringSpec>::format(
const ::mamba::specs::ChimeraStringSpec& spec,
@ -145,3 +134,10 @@ fmt::formatter<mamba::specs::ChimeraStringSpec>::format(
{
return fmt::format_to(ctx.out(), "{}", spec.to_string());
}
auto
std::hash<mamba::specs::ChimeraStringSpec>::operator()(const mamba::specs::ChimeraStringSpec& spec
) const -> std::size_t
{
return mamba::util::hash_vals(spec.to_string());
}

View File

@ -44,20 +44,15 @@ namespace mamba::specs
}
}
auto
fmt::formatter<mamba::specs::GlobSpec>::parse(format_parse_context& ctx) -> decltype(ctx.begin())
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto
fmt::formatter<mamba::specs::GlobSpec>::format(const ::mamba::specs::GlobSpec& spec, format_context& ctx) const
-> decltype(ctx.out())
-> format_context::iterator
{
return fmt::format_to(ctx.out(), "{}", spec.to_string());
}
auto
std::hash<mamba::specs::GlobSpec>::operator()(const mamba::specs::GlobSpec& spec) const -> std::size_t
{
return std::hash<std::string>{}(spec.to_string());
}

View File

@ -16,6 +16,7 @@
#include "mamba/specs/package_info.hpp"
#include "mamba/util/parsers.hpp"
#include "mamba/util/string.hpp"
#include "mamba/util/tuple_hash.hpp"
namespace mamba::specs
{
@ -1111,22 +1112,11 @@ namespace mamba::specs
}
}
auto
fmt::formatter<::mamba::specs::MatchSpec>::parse(format_parse_context& ctx) -> decltype(ctx.begin())
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto
fmt::formatter<::mamba::specs::MatchSpec>::format(
const ::mamba::specs::MatchSpec& spec,
format_context& ctx
) const -> decltype(ctx.out())
) const -> format_context::iterator
{
using MatchSpec = ::mamba::specs::MatchSpec;
@ -1266,3 +1256,36 @@ fmt::formatter<::mamba::specs::MatchSpec>::format(
return out;
}
auto
std::hash<mamba::specs::MatchSpec>::operator()(const mamba::specs::MatchSpec& spec) const
-> std::size_t
{
return mamba::util::hash_vals(
spec.channel(),
spec.version(),
spec.name(),
spec.build_string(),
spec.name_space(),
spec.build_number(),
spec.extra_members_hash()
);
}
auto
std::hash<mamba::specs::MatchSpec::ExtraMembers>::operator()(
const mamba::specs::MatchSpec::ExtraMembers& extra
) const -> std::size_t
{
return mamba::util::hash_vals(
extra.filename,
extra.subdirs,
extra.md5,
extra.sha256,
extra.license,
extra.license_family,
extra.features,
extra.track_features,
extra.optional
);
}

View File

@ -127,22 +127,18 @@ namespace mamba::specs
}
}
auto
fmt::formatter<mamba::specs::RegexSpec>::parse(format_parse_context& ctx) -> decltype(ctx.begin())
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto
fmt::formatter<mamba::specs::RegexSpec>::format(
const ::mamba::specs::RegexSpec& spec,
format_context& ctx
) const -> decltype(ctx.out())
) const -> format_context::iterator
{
return fmt::format_to(ctx.out(), "{}", spec.to_string());
}
auto
std::hash<mamba::specs::RegexSpec>::operator()(const mamba::specs::RegexSpec& spec) const
-> std::size_t
{
return std::hash<std::string>{}(spec.to_string());
}

View File

@ -263,23 +263,11 @@ namespace mamba::specs
}
}
auto
fmt::formatter<mamba::specs::VersionPartAtom>::parse(format_parse_context& ctx)
-> decltype(ctx.begin())
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto
fmt::formatter<mamba::specs::VersionPartAtom>::format(
const ::mamba::specs::VersionPartAtom atom,
format_context& ctx
) const -> decltype(ctx.out())
) const -> format_context::iterator
{
return fmt::format_to(ctx.out(), "{}{}", atom.numeral(), atom.literal());
}
@ -360,22 +348,11 @@ namespace mamba::specs
}
}
auto
fmt::formatter<mamba::specs::VersionPart>::parse(format_parse_context& ctx) -> decltype(ctx.begin())
{
// make sure that range is empty
if (ctx.begin() != ctx.end() && *ctx.begin() != '}')
{
throw fmt::format_error("Invalid format");
}
return ctx.begin();
}
auto
fmt::formatter<mamba::specs::VersionPart>::format(
const ::mamba::specs::VersionPart part,
format_context& ctx
) const -> decltype(ctx.out())
) const -> format_context::iterator
{
auto out = ctx.out();
if (part.atoms.empty())

View File

@ -14,6 +14,7 @@
#include "mamba/specs/version_spec.hpp"
#include "mamba/util/string.hpp"
#include "mamba/util/tuple_hash.hpp"
#include "specs/version_spec_impl.hpp"
@ -307,23 +308,11 @@ namespace mamba::specs
}
}
auto
fmt::formatter<mamba::specs::VersionPredicate>::parse(format_parse_context& ctx)
-> decltype(ctx.begin())
{
if (auto it = std::find(ctx.begin(), ctx.end(), 'b'); it < ctx.end())
{
conda_build_form = true;
return ++it;
}
return ctx.begin();
}
auto
fmt::formatter<mamba::specs::VersionPredicate>::format(
const ::mamba::specs::VersionPredicate& pred,
format_context& ctx
) const -> decltype(ctx.out())
) const -> format_context::iterator
{
using VersionPredicate = typename mamba::specs::VersionPredicate;
using VersionSpec = typename mamba::specs::VersionSpec;
@ -779,22 +768,11 @@ namespace mamba::specs
}
}
auto
fmt::formatter<mamba::specs::VersionSpec>::parse(format_parse_context& ctx) -> decltype(ctx.begin())
{
if (auto it = std::find(ctx.begin(), ctx.end(), 'b'); it < ctx.end())
{
conda_build_form = true;
return ++it;
}
return ctx.begin();
}
auto
fmt::formatter<mamba::specs::VersionSpec>::format(
const ::mamba::specs::VersionSpec& spec,
format_context& ctx
) const -> decltype(ctx.out())
) const -> format_context::iterator
{
using VersionSpec = typename mamba::specs::VersionSpec;
@ -835,3 +813,17 @@ fmt::formatter<mamba::specs::VersionSpec>::format(
);
return out;
}
auto
std::hash<mamba::specs::VersionPredicate>::operator()(const mamba::specs::VersionPredicate& pred) const
-> std::size_t
{
return mamba::util::hash_vals(pred.to_string());
}
auto
std::hash<mamba::specs::VersionSpec>::operator()(const mamba::specs::VersionSpec& spec) const
-> std::size_t
{
return mamba::util::hash_vals(spec.to_string());
}