wowlib
0.0.0
Read & write World of Warcraft client files — a C++26 core
Toggle main menu visibility
Loading...
Searching...
No Matches
convert.hpp
Go to the documentation of this file.
1
#pragma once
2
23
24
#include <array>
25
#include <cstddef>
26
27
#include <
wowlib/core/client_version.hpp
>
28
#include <
wowlib/core/error.hpp
>
29
#include <
wowlib/formats/common/version_range.hpp
>
30
31
namespace
wowlib::formats
{
33
template
<ClientVersion V>
34
struct
VersionTag
{};
35
42
template
<
template
<ClientVersion>
class
E>
43
inline
constexpr
auto
SupportedVersions
=
nullptr
;
44
50
template
<
template
<ClientVersion>
class
E>
51
inline
constexpr
auto
VersionPivots
=
nullptr
;
52
53
namespace
detail
{
54
template
<std::
size_t
N>
55
consteval
std::size_t
indexOf
(
const
std::array<ClientVersion, N>&
versions
,
ClientVersion
v) {
56
for
(std::size_t i = 0; i < N; ++i)
57
if
(
versions
[i] == v)
return
i;
58
return
N;
// not found
59
}
60
61
template
<
template
<ClientVersion>
class
E,
ClientVersion
From,
ClientVersion
To>
concept
HasConvertStep
=
requires
(
62
const
E<From>& src) {
63
{ convert_step(src,
VersionTag<To>
{}) } -> std::same_as<Result<E<To>>>;
64
};
65
69
template
<
template
<ClientVersion>
class
E>
70
consteval
ClientVersion
71
nextCanonical
(
ClientVersion
from,
ClientVersion
to) {
72
const
auto
&
versions
=
SupportedVersions<E>
;
73
const
auto
& pivots =
VersionPivots<E>
;
74
std::size_t i =
indexOf
(
versions
, from);
75
const
std::size_t j =
indexOf
(
versions
, to);
76
const
ClientVersion
fromCanonical =
canonicalVersion
(from, pivots,
versions
);
77
while
(i != j) {
78
i = i < j ? i + 1 : i - 1;
79
const
ClientVersion
c =
canonicalVersion
(
versions
[i], pivots,
versions
);
80
if
(c != fromCanonical)
return
c;
81
}
82
return
fromCanonical;
83
}
84
}
85
94
template
<
template
<ClientVersion>
class
E,
ClientVersion
From,
ClientVersion
To>
95
consteval
bool
hasConvertPath
() {
96
constexpr
auto
&
versions
=
SupportedVersions<E>
;
97
constexpr
auto
& pivots =
VersionPivots<E>
;
98
static_assert
(
detail::indexOf
(
versions
, From) <
versions
.size(),
"From is not a supported version of this format"
);
99
static_assert
(
detail::indexOf
(
versions
, To) <
versions
.size(),
"To is not a supported version of this format"
);
100
constexpr
ClientVersion
fromC =
canonicalVersion
(From, pivots,
versions
);
101
constexpr
ClientVersion
toC =
canonicalVersion
(To, pivots,
versions
);
102
if
constexpr
(fromC == toC)
return
true
;
103
else
{
104
constexpr
ClientVersion
next =
detail::nextCanonical<E>
(fromC, toC);
105
if
constexpr
(
detail::HasConvertStep<E, fromC, next>
)
return
hasConvertPath<E, next, To>
();
106
else
return
false
;
107
}
108
}
109
118
template
<ClientVersion To,
template
<ClientVersion>
class
E,
ClientVersion
From>
requires
(!std::is_same_v<
119
decltype
(
SupportedVersions<E>
),
const
std::nullptr_t>)
120
auto
convert
(
const
E<From>& src) ->
Result
<E<
canonicalVersion
(To,
VersionPivots<E>
,
SupportedVersions<E>
)>> {
121
constexpr
auto
&
versions
=
SupportedVersions<E>
;
122
constexpr
auto
& pivots =
VersionPivots<E>
;
123
static_assert
(
detail::indexOf
(
versions
, To) <
versions
.size(),
"To is not a supported version of this format"
);
124
static_assert
(From ==
canonicalVersion
(From, pivots,
versions
),
125
"convert() takes a canonical instantiation — construct entities "
"through the public aliases"
);
126
constexpr
ClientVersion
toC =
canonicalVersion
(To, pivots,
versions
);
127
128
if
constexpr
(From == toC)
return
src;
129
else
{
130
constexpr
ClientVersion
next =
detail::nextCanonical<E>
(From, toC);
131
static_assert
(
detail::HasConvertStep<E, From, next>
,
132
"no convert_step overload for this canonical version pair — declare "
133
"Result<E<next>> convert_step(const E<From>&, version_tag<next>)"
) ;
134
auto
stepped = convert_step(src,
VersionTag<next>
{});
135
if
(!stepped)
return
std::unexpected{stepped.error()};
136
return
convert<To>
(*stepped);
137
}
138
}
139
}
client_version.hpp
Client version identity, the flavor axis that separates a client's CONTENT version from the engine ge...
wowlib::formats::detail::HasConvertStep
Definition
convert.hpp:61
error.hpp
The error-handling vocabulary: ErrorCode, Error and the Result<T> alias every fallible wowlib operati...
wowlib::formats::detail
Definition
annotations.hpp:50
wowlib::formats::detail::nextCanonical
consteval ClientVersion nextCanonical(ClientVersion from, ClientVersion to)
The next CANONICAL version on E's ladder walking from from toward to — the first range boundary cross...
Definition
convert.hpp:71
wowlib::formats::detail::indexOf
consteval std::size_t indexOf(const std::array< ClientVersion, N > &versions, ClientVersion v)
Definition
convert.hpp:55
wowlib::formats
Definition
adt.hpp:68
wowlib::formats::hasConvertPath
consteval bool hasConvertPath()
Whether every convert_step along the CANONICAL ladder from from to to exists, i.e.
Definition
convert.hpp:95
wowlib::formats::VersionPivots
constexpr auto VersionPivots
The canonicalization pivots of format template E (the assembly's pivot list from its boundaries heade...
Definition
convert.hpp:51
wowlib::formats::canonicalVersion
constexpr ClientVersion canonicalVersion(ClientVersion v, std::span< const ClientVersion > pivots, std::span< const ClientVersion > grid)
The canonical version v collapses to: the FIRST grid version in v's range.
Definition
version_range.hpp:69
wowlib::formats::convert
auto convert(const E< From > &src) -> Result< E< canonicalVersion(To, VersionPivots< E >, SupportedVersions< E >)> >
Convert src to its to - version representation by composing convert_step overloads along the format's...
Definition
convert.hpp:120
wowlib::formats::SupportedVersions
constexpr auto SupportedVersions
The ordered release list of format template E.
Definition
convert.hpp:43
wowlib::versions
Definition
client_version.hpp:107
wowlib::Result
std::expected< T, Error > Result
Every fallible wowlib operation returns Result<T>; bindings translate the error branch into a target-...
Definition
error.hpp:100
wowlib::ClientVersion
Definition
client_version.hpp:33
wowlib::formats::VersionTag
Tags the target version in convert_step overload signatures.
Definition
convert.hpp:34
version_range.hpp
Version-range canonicalization: the machinery behind collapsing a versioned family's instantiations t...
src
wowlib
formats
convert.hpp
Generated by
1.17.0