Since the copy constructor is provided, we should explicitly specify the
others to make behavior explicit (and prevent the copy constructor from
being considered over the move constructor in certain scenarios).
CVParamTransfer contains a std::shared_ptr, so a copy here performs an
unnecessary reference count increment and decrement. We can std::move
here to avoid this.
The move constructor doesn't perform any behavior that would result in
an exception being thrown. Marking it as noexcept allows the type to
play nicely with facilities that make use of std::is_move_constructible
to determine whether copies can be avoided or not in certain
circumstances (e.g. the standard library; notably, std::vector).
We can't mark the move assignment operator as noexcept currently,
however, as it calls into interfaces outside of CToken.
Four of the five variables aren't modified, so they can be specified
directly within the functions and just be reused in place of the
variable names. This allows the constants to be elided or put into
read-only memory if necessary. It also makes the mutable value explicit.
Given the appended types consist of trivial types, it's more efficient
in this context to construct the data in place over using push_back,
which will cause a redundant copy (move semantics on trivial types are a
copy).
In the game executable itself, there exists no fallthrough here (which
makes sense, given all IO errors would be reported as character set
errors, otherwise).
Includes all necessary headers and uses a forward declaration where
applicable. Ensures inclusion changes in other headers don't break the compilation
of these headers and source files.
A few instances of CMaterialFilter are constructed at file-scope using
the Make* functions and the constructor. Given these aren't constexpr,
this means these are technically runtime function calls. We can make
these constexpr to allow the initialization to be done at compile-time,
slightly improving startup time.
Makes the arrays strongly-typed and impervious to implicit
array->pointer decay.
This also uncovered an out of bounds memory read within UpdateEffects
cause by said array->pointer decay.
The strcasecmp and _stricmp functions expect the passed in strings to
be null-terminated, however we we're also exposing a std::string_view
overload for that function. std::string_view instances aren't required
to be null-terminated, so this makes the interface a little unsafe.
We can use std::lexicographical_compare() to provide the same behavior
and also properly handle the case of non-null-terminated strings.