Merge branch 'master' into jgrpp

# Conflicts:
#	src/cargotype.h
#	src/core/CMakeLists.txt
#	src/core/span_type.hpp
#	src/fileio.cpp
#	src/fios.cpp
#	src/misc/endian_buffer.hpp
#	src/misc_gui.cpp
#	src/saveload/saveload.h
#	src/saveload/vehicle_sl.cpp
#	src/screenshot.cpp
#	src/settings.cpp
#	src/settings_internal.h
#	src/stdafx.h
#	src/string_func.h
#	src/strings.cpp
#	src/strings_func.h
#	src/strings_internal.h
pull/642/head
Jonathan G Rennison 3 months ago
commit 822ecae85d

@ -57,6 +57,7 @@
#include "../../stdafx.h"
#include "../../core/endian_func.hpp"
#include "md5.h"
#include <bit>
#include "../../safeguards.h"
@ -130,14 +131,14 @@ static inline void Md5Set1(const uint32_t *X, uint32_t *a, const uint32_t *b, co
{
uint32_t t = (*b & *c) | (~*b & *d);
t += *a + X[k] + Ti;
*a = ROL(t, s) + *b;
*a = std::rotl(t, s) + *b;
}
static inline void Md5Set2(const uint32_t *X, uint32_t *a, const uint32_t *b, const uint32_t *c, const uint32_t *d, const uint8_t k, const uint8_t s, const uint32_t Ti)
{
uint32_t t = (*b & *d) | (*c & ~*d);
t += *a + X[k] + Ti;
*a = ROL(t, s) + *b;
*a = std::rotl(t, s) + *b;
}
@ -145,14 +146,14 @@ static inline void Md5Set3(const uint32_t *X, uint32_t *a, const uint32_t *b, co
{
uint32_t t = *b ^ *c ^ *d;
t += *a + X[k] + Ti;
*a = ROL(t, s) + *b;
*a = std::rotl(t, s) + *b;
}
static inline void Md5Set4(const uint32_t *X, uint32_t *a, const uint32_t *b, const uint32_t *c, const uint32_t *d, const uint8_t k, const uint8_t s, const uint32_t Ti)
{
uint32_t t = *c ^ (*b | ~*d);
t += *a + X[k] + Ti;
*a = ROL(t, s) + *b;
*a = std::rotl(t, s) + *b;
}
Md5::Md5()

@ -157,9 +157,9 @@ SpriteID CargoSpec::GetCargoIcon() const
return sprite;
}
std::array<uint8_t, NUM_CARGO> _sorted_cargo_types; ///< Sort order of cargoes by cargo ID.
std::vector<const CargoSpec *> _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name.
span<const CargoSpec *> _sorted_standard_cargo_specs; ///< Standard cargo specifications sorted alphabetically by name.
std::array<uint8_t, NUM_CARGO> _sorted_cargo_types; ///< Sort order of cargoes by cargo ID.
std::vector<const CargoSpec *> _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name.
std::span<const CargoSpec *> _sorted_standard_cargo_specs; ///< Standard cargo specifications sorted alphabetically by name.
/** Sort cargo specifications by their name. */
static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b)

@ -16,7 +16,6 @@
#include "strings_type.h"
#include "landscape_type.h"
#include "core/bitmath_func.hpp"
#include "core/span_type.hpp"
#include <vector>
/** Globally unique label of a cargo type. */
@ -200,7 +199,7 @@ Dimension GetLargestCargoIconSize();
void InitializeSortedCargoSpecs();
extern std::array<uint8_t, NUM_CARGO> _sorted_cargo_types;
extern std::vector<const CargoSpec *> _sorted_cargo_specs;
extern span<const CargoSpec *> _sorted_standard_cargo_specs;
extern std::span<const CargoSpec *> _sorted_standard_cargo_specs;
uint ConvertCargoQuantityToDisplayQuantity(CargoID cargo, uint quantity);
uint ConvertDisplayQuantityToCargoQuantity(CargoID cargo, uint quantity);

@ -61,14 +61,14 @@ struct CommandAuxiliarySerialised : public CommandAuxiliaryBase {
return new CommandAuxiliarySerialised(*this);
}
virtual std::optional<span<const uint8_t>> GetDeserialisationSrc() const override { return span<const uint8_t>(this->serialised_data.data(), this->serialised_data.size()); }
virtual std::optional<std::span<const uint8_t>> GetDeserialisationSrc() const override { return std::span<const uint8_t>(this->serialised_data.data(), this->serialised_data.size()); }
virtual void Serialise(CommandSerialisationBuffer &buffer) const override { buffer.Send_binary(this->serialised_data.data(), this->serialised_data.size()); }
};
template <typename T>
struct CommandAuxiliarySerialisable : public CommandAuxiliaryBase {
virtual std::optional<span<const uint8_t>> GetDeserialisationSrc() const override { return {}; }
virtual std::optional<std::span<const uint8_t>> GetDeserialisationSrc() const override { return {}; }
CommandAuxiliaryBase *Clone() const override
{
@ -86,10 +86,10 @@ public:
inline CommandCost Load(const CommandAuxiliaryBase *base)
{
if (base == nullptr) return CMD_ERROR;
std::optional<span<const uint8_t>> deserialise_from = base->GetDeserialisationSrc();
std::optional<std::span<const uint8_t>> deserialise_from = base->GetDeserialisationSrc();
if (deserialise_from.has_value()) {
this->store = T();
CommandDeserialisationBuffer buffer(deserialise_from->begin(), deserialise_from->size());
CommandDeserialisationBuffer buffer(deserialise_from->data(), deserialise_from->size());
CommandCost res = this->store->Deserialise(buffer);
if (res.Failed()) return res;
if (buffer.error || buffer.pos != buffer.size) {

@ -13,7 +13,6 @@
#include "economy_type.h"
#include "strings_type.h"
#include "tile_type.h"
#include "core/span_type.hpp"
#include <optional>
#include <string>
@ -714,7 +713,7 @@ struct CommandAuxiliaryBase {
virtual CommandAuxiliaryBase *Clone() const = 0;
virtual std::optional<span<const uint8_t>> GetDeserialisationSrc() const = 0;
virtual std::optional<std::span<const uint8_t>> GetDeserialisationSrc() const = 0;
virtual void Serialise(CommandSerialisationBuffer &buffer) const = 0;
};

@ -33,7 +33,6 @@ add_files(
serialisation.cpp
serialisation.hpp
smallstack_type.hpp
span_type.hpp
strong_typedef_type.hpp
tinystring_type.hpp
y_combinator.hpp

@ -391,38 +391,6 @@ inline bool HasAtMostOneBit(T value)
return (value & (value - 1)) == 0;
}
/**
* ROtate \a x Left by \a n
*
* @note Assumes a byte has 8 bits
* @param x The value which we want to rotate
* @param n The number how many we want to rotate
* @pre n < sizeof(T) * 8
* @return A bit rotated number
*/
template <typename T>
inline T ROL(const T x, const uint8_t n)
{
if (n == 0) return x;
return (T)(x << n | x >> (sizeof(x) * 8 - n));
}
/**
* ROtate \a x Right by \a n
*
* @note Assumes a byte has 8 bits
* @param x The value which we want to rotate
* @param n The number how many we want to rotate
* @pre n < sizeof(T) * 8
* @return A bit rotated number
*/
template <typename T>
inline T ROR(const T x, const uint8_t n)
{
if (n == 0) return x;
return (T)(x >> n | x << (sizeof(x) * 8 - n));
}
/**
* Iterable ensemble of each set bit in a value.
* @tparam Tbitpos Type of the position variable.

@ -20,6 +20,7 @@
#include "../fileio_func.h"
#include "../date_func.h"
#include "../debug.h"
#include <bit>
#endif /* RANDOM_DEBUG */
struct SimpleChecksum64 {
@ -27,7 +28,7 @@ struct SimpleChecksum64 {
void Update(uint64_t input)
{
this->state = ROL(this->state, 1) ^ input ^ 0x123456789ABCDEF7ULL;
this->state = std::rotl(this->state, 1) ^ input ^ 0x123456789ABCDEF7ULL;
}
};

@ -10,6 +10,7 @@
#include "../stdafx.h"
#include "random_func.hpp"
#include "bitmath_func.hpp"
#include <bit>
#ifdef RANDOM_DEBUG
#include "../network/network.h"
@ -33,8 +34,8 @@ uint32_t Randomizer::Next()
const uint32_t s = this->state[0];
const uint32_t t = this->state[1];
this->state[0] = s + ROR(t ^ 0x1234567F, 7) + 1;
return this->state[1] = ROR(s, 3) - 1;
this->state[0] = s + std::rotr(t ^ 0x1234567F, 7) + 1;
return this->state[1] = std::rotr(s, 3) - 1;
}
/**

@ -11,7 +11,6 @@
#define SERIALISATION_HPP
#include "bitmath_func.hpp"
#include "span_type.hpp"
#include "../string_type.h"
#include "../string_func.h"
@ -269,13 +268,13 @@ public:
* @param size The size of the data.
* @return The view of the data.
*/
span<const uint8_t> Recv_binary_view(size_t size)
std::span<const uint8_t> Recv_binary_view(size_t size)
{
if (!this->CanRecvBytes(size, true)) return {};
auto &pos = static_cast<T *>(this)->GetDeserialisationPosition();
span<const uint8_t> view { &this->GetBuffer()[pos], size };
std::span<const uint8_t> view { &this->GetBuffer()[pos], size };
pos += (decltype(pos)) size;
return view;
@ -288,7 +287,7 @@ public:
*/
std::vector<uint8_t> Recv_binary(size_t size)
{
span<const uint8_t> view = this->Recv_binary_view(size);
std::span<const uint8_t> view = this->Recv_binary_view(size);
return { view.begin(), view.end() };
}
@ -297,14 +296,14 @@ public:
* Returns a view of a length-prefixed binary buffer from the packet.
* @return The binary buffer.
*/
span<const uint8_t> Recv_buffer_view()
std::span<const uint8_t> Recv_buffer_view()
{
uint16_t length = this->Recv_uint16();
if (!this->CanRecvBytes(length, true)) return {};
auto &pos = static_cast<T *>(this)->GetDeserialisationPosition();
span<const uint8_t> buffer { &this->GetBuffer()[pos], length };
std::span<const uint8_t> buffer { &this->GetBuffer()[pos], length };
pos += length;
return buffer;
@ -316,7 +315,7 @@ public:
*/
std::vector<uint8_t> Recv_buffer()
{
span<const uint8_t> view = this->Recv_buffer_view();
std::span<const uint8_t> view = this->Recv_buffer_view();
return { view.begin(), view.end() };
}

@ -1,109 +0,0 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file span_type.hpp Minimized implementation of C++20 std::span. */
#ifndef CORE_SPAN_TYPE_HPP
#define CORE_SPAN_TYPE_HPP
/* This is a partial copy/paste from https://github.com/gsl-lite/gsl-lite/blob/master/include/gsl/gsl-lite.hpp */
/* Template to check if a template variable defines size() and data(). */
template <class, class = void>
struct has_size_and_data : std::false_type{};
template <class C>
struct has_size_and_data
<
C, std::void_t<
decltype(std::size(std::declval<C>())),
decltype(std::data(std::declval<C>()))>
> : std::true_type{};
/* Template to check if two elements are compatible. */
template <class, class, class = void>
struct is_compatible_element : std::false_type {};
template <class C, class E>
struct is_compatible_element
<
C, E, std::void_t<
decltype(std::data(std::declval<C>())),
typename std::remove_pointer<decltype(std::data( std::declval<C&>()))>::type(*)[]>
> : std::is_convertible<typename std::remove_pointer<decltype(std::data(std::declval<C&>()))>::type(*)[], E(*)[]>{};
/* Template to check if a container is compatible. gsl-lite also includes is_array and is_std_array, but as we don't use them, they are omitted. */
template <class C, class E>
struct is_compatible_container : std::bool_constant
<
has_size_and_data<C>::value
&& is_compatible_element<C, E>::value
>{};
/**
* A trimmed down version of what std::span will be in C++20.
*
* It is fully forwards compatible, so if this codebase switches to C++20,
* all "span" instances can be replaced by "std::span" without loss of
* functionality.
*
* Currently it only supports basic functionality:
* - size() and friends
* - begin() and friends
*
* It is meant to simplify function parameters, where we only want to walk
* a continuous list.
*/
template<class T>
class span {
public:
typedef T element_type;
typedef typename std::remove_cv< T >::type value_type;
typedef T &reference;
typedef T *pointer;
typedef const T &const_reference;
typedef const T *const_pointer;
typedef pointer iterator;
typedef const_pointer const_iterator;
typedef size_t size_type;
typedef std::ptrdiff_t difference_type;
constexpr span() noexcept : first(nullptr), last(nullptr) {}
constexpr span(pointer data_in, size_t size_in) : first(data_in), last(data_in + size_in) {}
template<class Container, typename std::enable_if<(is_compatible_container<Container, element_type>::value), int>::type = 0>
constexpr span(Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
template<class Container, typename std::enable_if<(std::is_const<element_type>::value && is_compatible_container<Container, element_type>::value), int>::type = 0>
constexpr span(const Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
constexpr pointer data() const noexcept { return first; }
constexpr size_t size() const noexcept { return static_cast<size_t>( last - first ); }
constexpr std::ptrdiff_t ssize() const noexcept { return static_cast<std::ptrdiff_t>( last - first ); }
constexpr bool empty() const noexcept { return this->size() == 0; }
constexpr iterator begin() const noexcept { return iterator(first); }
constexpr iterator end() const noexcept { return iterator(last); }
constexpr const_iterator cbegin() const noexcept { return const_iterator(first); }
constexpr const_iterator cend() const noexcept { return const_iterator(last); }
constexpr reference operator[](size_type idx) const { return first[idx]; }
constexpr span<element_type> subspan(size_t offset, size_t count)
{
assert(offset + count <= size());
return span(this->data() + offset, count);
}
private:
pointer first;
pointer last;
};
#endif /* CORE_SPAN_TYPE_HPP */

@ -749,7 +749,7 @@ FiosNumberedSaveName::FiosNumberedSaveName(const std::string &prefix) : prefix(p
/* Callback for FiosFileScanner. */
static fios_getlist_callback_proc *proc = [](SaveLoadOperation fop, const std::string &file, const char *ext, char *title, const char *last) {
if (StrEqualsIgnoreCase(ext, ".sav") && StrStartsWith(file, _prefix)) return FIOS_TYPE_FILE;
if (StrEqualsIgnoreCase(ext, ".sav") && file.starts_with(_prefix)) return FIOS_TYPE_FILE;
return FIOS_TYPE_INVALID;
};

@ -178,7 +178,7 @@ static void LoadSpriteTables()
const GraphicsSet *used_set = BaseGraphics::GetUsedSet();
SpriteFile &baseset_file = LoadGrfFile(used_set->files[GFT_BASE].filename, 0, PAL_DOS != used_set->palette);
if (StrStartsWith(used_set->name, "original_")) {
if (used_set->name.starts_with("original_")) {
baseset_file.flags |= SFF_OPENTTDGRF;
}

@ -1045,6 +1045,10 @@ STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marque e
STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escalar chanfros
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marque esta caixa para dimensionar os chanfros por tamanho de interface
STR_GAME_OPTIONS_GUI_FONT_SPRITE :{BLACK}Usar a fonte sprite tradicional
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Marque esta caixa se você prefere usar a fonte sprite tradicional de tamanho fixo.
STR_GAME_OPTIONS_GUI_FONT_AA :{BLACK}Fontes com bordas suaves
STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP :{BLACK}Marcar esta caixa para fontes redimensionáveis com bordas suaves.
STR_GAME_OPTIONS_GUI_SCALE_1X :1x
STR_GAME_OPTIONS_GUI_SCALE_2X :2x
@ -3424,7 +3428,7 @@ STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_ROAD_TYPE :Tipo de estrada
STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}Variável NewGRF 60+ parâmetro x (hexadecimal)
# Sprite aligner window
STR_SPRITE_ALIGNER_CAPTION :{WHITE}Alinhando "sprite" {COMMA} ({STRING})
STR_SPRITE_ALIGNER_CAPTION :{WHITE}Alinhando sprite {COMMA} ({STRING})
STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}Próximo "sprite"
STR_SPRITE_ALIGNER_NEXT_TOOLTIP :{BLACK}Prossegue ao próximo "sprite" normal, pulando quaisquer "sprites" falsos, recoloridos ou de fontes, e junta tudo do último pro primeiro
STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}Ir para o "sprite"

@ -1044,6 +1044,10 @@ STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marker d
STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Skalere facetter
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marker dette afkrydsningsfelt for at skalere facetter efter grænsefladestørrelse
STR_GAME_OPTIONS_GUI_FONT_SPRITE :{BLACK}Brug traditionel sprite-skrifttype
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Marker dette felt, hvis du foretrækker at bruge den traditionelle sprite-skrifttype med fast størrelse.
STR_GAME_OPTIONS_GUI_FONT_AA :{BLACK}Anti-alias skrifttyper
STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP :{BLACK}Marker dette felt for at skrifttyper, der kan ændres størrelse, kan udlignes.
STR_GAME_OPTIONS_GUI_SCALE_1X :1x
STR_GAME_OPTIONS_GUI_SCALE_2X :2x

@ -1045,7 +1045,7 @@ STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Scale be
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Check this box to scale bevels by interface size
STR_GAME_OPTIONS_GUI_FONT_SPRITE :{BLACK}Use traditional sprite font
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Check this box if you prefer to use the tradition fixed-size sprite font.
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Check this box if you prefer to use the traditional fixed-size sprite font.
STR_GAME_OPTIONS_GUI_FONT_AA :{BLACK}Anti-alias fonts
STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP :{BLACK}Check this box to anti-alias resizable fonts.

@ -1045,8 +1045,8 @@ STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Cochez c
STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Mettre à léchelle les bordures
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Cochez cette case pour mettre les bordures à l'échelle avec la taille de l'interface
STR_GAME_OPTIONS_GUI_FONT_SPRITE :{BLACK}Utiliser la police d'écriture de sprite
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Cochez cette case si vous préferez utiliser la police d'écriture à taille fixe de sprite.
STR_GAME_OPTIONS_GUI_FONT_SPRITE :{BLACK}Utiliser la police d'écriture par défaut
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Cochez cette case si vous préferez utiliser la police d'écriture par défaut.
STR_GAME_OPTIONS_GUI_FONT_AA :{BLACK}Polices d'écriture supportant l'anti-crénelage
STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP :{BLACK}Cochez cette case pour activer l'anti-crénelage sur les polices d'écriture à taille variable.

@ -1424,6 +1424,10 @@ STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Zaznacz
STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Skaluj fazy krawędzi
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Zaznacz to pole, aby skalować fazy krawędzi zgodnie z rozmiarem interfejsu
STR_GAME_OPTIONS_GUI_FONT_SPRITE :{BLACK}Użyj tradycyjnego fonta typu sprite
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Zaznacz to pole, jeśli wolisz używać tradycyjnego fonta typu sprite o stałym rozmiarze.
STR_GAME_OPTIONS_GUI_FONT_AA :{BLACK}Antyaliasing fontów
STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP :{BLACK}Zaznacz to pole, aby wygładzać fonty o zmiennym rozmiarze.
STR_GAME_OPTIONS_GUI_SCALE_1X :1x
STR_GAME_OPTIONS_GUI_SCALE_2X :2x
@ -3398,7 +3402,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Właści
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Lokalne władze: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Brak
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Współrzędne: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING})
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Zbudowano: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Zbudowano/odnowiono: {LTBLUE}{DATE_LONG}
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Rodzaj stacji: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Typ stacji: {LTBLUE}{STRING}
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Rodzaj lotniska: {LTBLUE}{STRING}

@ -94,36 +94,36 @@ STR_CARGO_SINGULAR_FIZZY_DRINK :汽水
# Quantity of cargo
STR_QUANTITY_NOTHING :
STR_QUANTITY_PASSENGERS :{COMMA}{NBSP}位旅客
STR_QUANTITY_COAL :{WEIGHT_LONG} 煤炭
STR_QUANTITY_COAL :{WEIGHT_LONG}煤炭
STR_QUANTITY_MAIL :{COMMA}{NBSP}包邮件
STR_QUANTITY_OIL :{VOLUME_LONG} 原油
STR_QUANTITY_OIL :{VOLUME_LONG}原油
STR_QUANTITY_LIVESTOCK :{COMMA}{NBSP}头牲畜
STR_QUANTITY_GOODS :{COMMA}{NBSP}件货物
STR_QUANTITY_GRAIN :{WEIGHT_LONG} 谷物
STR_QUANTITY_WOOD :{WEIGHT_LONG} 木材
STR_QUANTITY_IRON_ORE :{WEIGHT_LONG} 铁矿石
STR_QUANTITY_STEEL :{WEIGHT_LONG} 钢材
STR_QUANTITY_GRAIN :{WEIGHT_LONG}谷物
STR_QUANTITY_WOOD :{WEIGHT_LONG}木材
STR_QUANTITY_IRON_ORE :{WEIGHT_LONG}铁矿石
STR_QUANTITY_STEEL :{WEIGHT_LONG}钢材
STR_QUANTITY_VALUABLES :{COMMA}{NBSP}包贵重品
STR_QUANTITY_COPPER_ORE :{WEIGHT_LONG} 铜矿石
STR_QUANTITY_MAIZE :{WEIGHT_LONG} 玉米
STR_QUANTITY_FRUIT :{WEIGHT_LONG} 水果
STR_QUANTITY_MAIZE :{WEIGHT_LONG}玉米
STR_QUANTITY_FRUIT :{WEIGHT_LONG}水果
STR_QUANTITY_DIAMONDS :{COMMA}{NBSP}包钻石
STR_QUANTITY_FOOD :{WEIGHT_LONG} 食品
STR_QUANTITY_PAPER :{WEIGHT_LONG} 纸张
STR_QUANTITY_FOOD :{WEIGHT_LONG}食品
STR_QUANTITY_PAPER :{WEIGHT_LONG}纸张
STR_QUANTITY_GOLD :{COMMA}{NBSP}包黄金
STR_QUANTITY_WATER :{VOLUME_LONG} 饮用水
STR_QUANTITY_WHEAT :{WEIGHT_LONG} 小麦
STR_QUANTITY_RUBBER :{VOLUME_LONG} 橡胶
STR_QUANTITY_SUGAR :{WEIGHT_LONG} 蔗糖
STR_QUANTITY_WATER :{VOLUME_LONG}饮用水
STR_QUANTITY_WHEAT :{WEIGHT_LONG}小麦
STR_QUANTITY_RUBBER :{VOLUME_LONG}橡胶
STR_QUANTITY_SUGAR :{WEIGHT_LONG}蔗糖
STR_QUANTITY_TOYS :{COMMA}{NBSP}件玩具
STR_QUANTITY_SWEETS :{COMMA}{NBSP}包糖果
STR_QUANTITY_COLA :{VOLUME_LONG} 可乐
STR_QUANTITY_CANDYFLOSS :{WEIGHT_LONG} 棉花糖
STR_QUANTITY_COLA :{VOLUME_LONG}可乐
STR_QUANTITY_CANDYFLOSS :{WEIGHT_LONG}棉花糖
STR_QUANTITY_BUBBLES :{COMMA} 个泡泡
STR_QUANTITY_TOFFEE :{WEIGHT_LONG} 太妃糖
STR_QUANTITY_TOFFEE :{WEIGHT_LONG}太妃糖
STR_QUANTITY_BATTERIES :{COMMA} 箱电池
STR_QUANTITY_PLASTIC :{VOLUME_LONG} 塑料
STR_QUANTITY_FIZZY_DRINKS :{COMMA} 瓶汽水
STR_QUANTITY_PLASTIC :{VOLUME_LONG}塑料
STR_QUANTITY_FIZZY_DRINKS :{COMMA}瓶汽水
STR_QUANTITY_N_A :N/A
# Two letter abbreviation of cargo name
@ -1045,7 +1045,7 @@ STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}适应
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}选中此框使边框大小随界面大小而缩放
STR_GAME_OPTIONS_GUI_FONT_SPRITE :使用位图字体
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :如果您想使用固定大小的传统位图字体,请勾选此框。
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}如果您想使用固定大小的传统位图字体,请勾选此框。
STR_GAME_OPTIONS_GUI_FONT_AA :字体抗锯齿
STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP :勾选此框以对游戏字体应用抗锯齿。
@ -4658,7 +4658,7 @@ STR_DATE_YEAR_TOOLTIP :{BLACK}选择
# AI debug window
STR_AI_DEBUG :{WHITE}AI/脚本 调试
STR_AI_DEBUG :{WHITE}AI/脚本调试
STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} (v{NUM})
STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}AI名称
STR_AI_DEBUG_SETTINGS :{BLACK}AI 设置

@ -121,8 +121,8 @@ private:
uint received_demand; ///< Received demand towards this node.
PathList paths; ///< Paths through this node, sorted so that those with flow == 0 are in the back.
FlowStatMap flows; ///< Planned flows to other nodes.
span<DemandAnnotation> demands; ///< Demand annotations belonging to this node.
span<Edge> edges; ///< Edges with annotations belonging to this node.
std::span<DemandAnnotation> demands; ///< Demand annotations belonging to this node.
std::span<Edge> edges; ///< Edges with annotations belonging to this node.
void Init(uint supply);
};
@ -232,12 +232,12 @@ public:
this->node_anno.received_demand += amount;
}
span<DemandAnnotation> GetDemandAnnotations() const
std::span<DemandAnnotation> GetDemandAnnotations() const
{
return this->node_anno.demands;
}
void SetDemandAnnotations(span<DemandAnnotation> demands)
void SetDemandAnnotations(std::span<DemandAnnotation> demands)
{
this->node_anno.demands = demands;
}
@ -252,7 +252,7 @@ public:
return empty_edge;
}
span<Edge> GetEdges()
std::span<Edge> GetEdges()
{
return this->node_anno.edges;
}

@ -134,8 +134,9 @@ public:
void SetNode(NodeID, NodeID node)
{
Node node_anno = this->job[node];
this->i = node_anno.GetEdges().begin();
this->end = node_anno.GetEdges().end();
std::span<Edge> edges = node_anno.GetEdges();
this->i = edges.data();
this->end = edges.data() + edges.size();
this->node = node;
}

@ -1242,10 +1242,7 @@ struct QueryWindow : public Window {
if (!this->precomposed) this->message_str = GetString(this->message);
Dimension d = GetStringMultiLineBoundingBox(this->message_str.c_str(), *size);
d.width += WidgetDimensions::scaled.frametext.Horizontal();
d.height += WidgetDimensions::scaled.framerect.Vertical();
*size = d;
*size = GetStringMultiLineBoundingBox(this->message_str, *size);
}
void DrawWidget(const Rect &r, WidgetID widget) const override
@ -1254,8 +1251,7 @@ struct QueryWindow : public Window {
if (!this->precomposed) this->message_str = GetString(this->message);
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect),
this->message_str, TC_FROMSTRING, SA_CENTER);
DrawStringMultiLine(r, this->message_str, TC_FROMSTRING, SA_CENTER);
}
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override

@ -473,7 +473,7 @@ void NetworkAddress::Listen(int socktype, SocketList *sockets)
*/
/* static */ ServerAddress ServerAddress::Parse(const std::string &connection_string, uint16_t default_port, CompanyID *company_id)
{
if (StrStartsWith(connection_string, "+")) {
if (connection_string.starts_with("+")) {
std::string_view invite_code = ParseCompanyFromConnectionString(connection_string, company_id);
return ServerAddress(SERVER_ADDRESS_INVITE_CODE, std::string(invite_code));
}

@ -177,7 +177,7 @@ void HttpThread()
/* Prepare POST body and URI. */
if (!request->data.empty()) {
/* When the payload starts with a '{', it is a JSON payload. */
if (StrStartsWith(request->data, "{")) {
if (request->data.starts_with("{")) {
headers = curl_slist_append(headers, "Content-Type: application/json");
} else {
headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");

@ -252,7 +252,7 @@ void NetworkHTTPRequest::Connect()
WinHttpSendRequest(this->request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, reinterpret_cast<DWORD_PTR>(this));
} else {
/* When the payload starts with a '{', it is a JSON payload. */
LPCWSTR content_type = StrStartsWith(data, "{") ? L"Content-Type: application/json\r\n" : L"Content-Type: application/x-www-form-urlencoded\r\n";
LPCWSTR content_type = data.starts_with("{") ? L"Content-Type: application/json\r\n" : L"Content-Type: application/x-www-form-urlencoded\r\n";
WinHttpSendRequest(this->request, content_type, -1, const_cast<char *>(data.c_str()), static_cast<DWORD>(data.size()), static_cast<DWORD>(data.size()), reinterpret_cast<DWORD_PTR>(this));
}
}

@ -416,7 +416,7 @@ struct NetworkChatWindow : public Window {
/* Now any match we make on _chat_tab_completion_buf after this, is perfect */
}
if (tb_buf.size() < cur_name.size() && StrStartsWith(cur_name, tb_buf)) {
if (tb_buf.size() < cur_name.size() && cur_name.starts_with(tb_buf)) {
/* Save the data it was before completion */
if (!second_scan) _chat_tab_completion_buf = tb->buf;
_chat_tab_completion_active = true;

@ -514,7 +514,7 @@ void ClientNetworkCoordinatorSocketHandler::GetListing()
*/
void ClientNetworkCoordinatorSocketHandler::ConnectToServer(const std::string &invite_code, TCPServerConnecter *connecter)
{
assert(StrStartsWith(invite_code, "+"));
assert(invite_code.starts_with("+"));
if (this->connecter_pre.find(invite_code) != this->connecter_pre.end()) {
/* If someone is hammering the refresh key, one can sent out two

@ -657,7 +657,7 @@ public:
tr.top = DrawStringMultiLine(tr, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version
SetDParamStr(0, sel->connection_string);
StringID invite_or_address = StrStartsWith(sel->connection_string, "+") ? STR_NETWORK_SERVER_LIST_INVITE_CODE : STR_NETWORK_SERVER_LIST_SERVER_ADDRESS;
StringID invite_or_address = sel->connection_string.starts_with("+") ? STR_NETWORK_SERVER_LIST_INVITE_CODE : STR_NETWORK_SERVER_LIST_SERVER_ADDRESS;
tr.top = DrawStringMultiLine(tr, invite_or_address); // server address / invite code
SetDParam(0, sel->info.start_date);

@ -19,6 +19,7 @@
#include "scope.h"
#include "debug_settings.h"
#include "newgrf_engine.h"
#include <bit>
#include "safeguards.h"
@ -212,7 +213,7 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust &adjust, ScopeResolver
case DSGA_OP_STO: _temp_store.StoreValue((U)value, (S)last_value); return last_value;
case DSGA_OP_RST: return value;
case DSGA_OP_STOP: scope->StorePSA((U)value, (S)last_value); return last_value;
case DSGA_OP_ROR: return ROR<uint32_t>((U)last_value, (U)value & 0x1F); // mask 'value' to 5 bits, which should behave the same on all architectures.
case DSGA_OP_ROR: return std::rotr<uint32_t>((U)last_value, (U)value & 0x1F); // mask 'value' to 5 bits, which should behave the same on all architectures.
case DSGA_OP_SCMP: return ((S)last_value == (S)value) ? 1 : ((S)last_value < (S)value ? 0 : 2);
case DSGA_OP_UCMP: return ((U)last_value == (U)value) ? 1 : ((U)last_value < (U)value ? 0 : 2);
case DSGA_OP_SHL: return (uint32_t)(U)last_value << ((U)value & 0x1F); // Same behaviour as in ParamSet, mask 'value' to 5 bits, which should behave the same on all architectures.

@ -588,7 +588,7 @@ private:
StringID GetCompanyMessageString() const
{
/* Company news with a face have a separate headline, so the normal message is shifted by two params */
CopyInDParam(span(this->ni->params.data() + 2, this->ni->params.size() - 2));
CopyInDParam(std::span(this->ni->params.data() + 2, this->ni->params.size() - 2));
return this->ni->params[1].data;
}

@ -617,7 +617,7 @@ void MakeNewgameSettingsLive()
void OpenBrowser(const std::string &url)
{
/* Make sure we only accept urls that are sure to open a browser. */
if (StrStartsWith(url, "http://") || StrStartsWith(url, "https://")) {
if (url.starts_with("http://") || url.starts_with("https://")) {
OSOpenBrowser(url);
}
}

@ -14,7 +14,6 @@
#include "../fileio_type.h"
#include "../fios.h"
#include "../strings_type.h"
#include "../core/span_type.hpp"
#include "../core/ring_buffer.hpp"
#include <optional>
#include <string>
@ -83,10 +82,10 @@ struct ChunkHandler {
using ChunkHandlerRef = std::reference_wrapper<const ChunkHandler>;
/** A table of ChunkHandler entries. */
using ChunkHandlerTable = span<const ChunkHandlerRef>;
using ChunkHandlerTable = std::span<const ChunkHandlerRef>;
/** A table of SaveLoadCompat entries. */
using SaveLoadCompatTable = span<const struct SaveLoadCompat>;
using SaveLoadCompatTable = std::span<const struct SaveLoadCompat>;
/** Handler for saving/loading an object to/from disk. */
class SaveLoadHandler {

@ -143,7 +143,7 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm)
sq_getstring(vm, 2, &key_string);
std::string str = StrMakeValid(key_string);
if (!StrStartsWith(str, "param_") || str.size() > 8) return SQ_ERROR;
if (!str.starts_with("param_") || str.size() > 8) return SQ_ERROR;
k = stoi(str.substr(6));
} else if (sq_gettype(vm, 2) == OT_INTEGER) {

@ -19,6 +19,7 @@
#include "saveload_internal.h"
#include "oldloader.h"
#include <bit>
#include <exception>
#include "../safeguards.h"
@ -214,7 +215,7 @@ static bool VerifyOldNameChecksum(char *title, uint len)
uint16_t sum = 0;
for (uint i = 0; i < len - 2; i++) {
sum += title[i];
sum = ROL(sum, 1);
sum = std::rotl(sum, 1);
}
sum ^= 0xAAAA; // computed checksum

@ -230,7 +230,7 @@ struct NullStruct {
};
/** A table of ChunkHandler entries. */
using ChunkHandlerTable = span<const ChunkHandler>;
using ChunkHandlerTable = std::span<const ChunkHandler>;
/** Type of reference (#SLE_REF, #SLE_CONDREF). */
enum SLRefType {
@ -943,7 +943,7 @@ size_t SlCalcObjLength(const void *object, const SaveLoadTable &slt);
* @return Span of the saved data, in the autolength temp buffer
*/
template <typename F>
span<byte> SlSaveToTempBuffer(F proc)
std::span<byte> SlSaveToTempBuffer(F proc)
{
extern uint8_t SlSaveToTempBufferSetup();
extern std::pair<byte *, size_t> SlSaveToTempBufferRestore(uint8_t state);
@ -951,7 +951,7 @@ span<byte> SlSaveToTempBuffer(F proc)
uint8_t state = SlSaveToTempBufferSetup();
proc();
auto result = SlSaveToTempBufferRestore(state);
return span<byte>(result.first, result.second);
return std::span<byte>(result.first, result.second);
}
/**
@ -963,7 +963,7 @@ span<byte> SlSaveToTempBuffer(F proc)
template <typename F>
std::vector<uint8_t> SlSaveToVector(F proc)
{
span<byte> result = SlSaveToTempBuffer(proc);
std::span<byte> result = SlSaveToTempBuffer(proc);
return std::vector<uint8_t>(result.begin(), result.end());
}

@ -11,18 +11,17 @@
#define SL_SAVELOAD_COMMON_H
#include "../strings_type.h"
#include "../core/span_type.hpp"
struct SaveLoad;
/** A table of SaveLoad entries. */
using SaveLoadTable = span<const SaveLoad>;
using SaveLoadTable = std::span<const SaveLoad>;
namespace upstream_sl {
struct SaveLoad;
/** A table of SaveLoad entries. */
using SaveLoadTable = span<const SaveLoad>;
using SaveLoadTable = std::span<const SaveLoad>;
}
/** SaveLoad versions

@ -22,7 +22,6 @@
#include "bitmap_type.h"
#include "core/alloc_type.hpp"
#include "core/endian_type.hpp"
#include "core/span_type.hpp"
#include "strings_type.h"
#include <map>
#include <vector>
@ -506,9 +505,9 @@ public:
void SortStorage();
span<const FlowStat> IterateUnordered() const
std::span<const FlowStat> IterateUnordered() const
{
return span<const FlowStat>(this->flows_storage.data(), this->flows_storage.size());
return std::span<const FlowStat>(this->flows_storage.data(), this->flows_storage.size());
}
};

@ -56,6 +56,7 @@
#include <climits>
#include <cassert>
#include <memory>
#include <span>
#include <string>
#include <inttypes.h>

@ -16,6 +16,7 @@
#include "strgen.h"
#include <bit>
#include "../table/strgen_tables.h"
@ -109,7 +110,7 @@ LangString *StringData::Find(const std::string_view s)
uint StringData::VersionHashStr(uint hash, const char *s) const
{
for (; *s != '\0'; s++) {
hash = ROL(hash, 3) ^ *s;
hash = std::rotl(hash, 3) ^ *s;
hash = (hash & 1 ? hash >> 1 ^ 0xDEADBEEF : hash >> 1);
}
return hash;

@ -210,7 +210,7 @@ const char *str_fix_scc_encoded(char *str, const char *last)
* @param data Array to format
* @return Converted string.
*/
std::string FormatArrayAsHex(span<const byte> data)
std::string FormatArrayAsHex(std::span<const byte> data)
{
std::string hex_output;
hex_output.resize(data.size() * 2);
@ -431,19 +431,6 @@ const char *StrLastPathSegment(const char *path)
return best;
}
/**
* Check whether the given string starts with the given prefix.
* @param str The string to look at.
* @param prefix The prefix to look for.
* @return True iff the begin of the string is the same as the prefix.
*/
bool StrStartsWith(const std::string_view str, const std::string_view prefix)
{
size_t prefix_len = prefix.size();
if (str.size() < prefix_len) return false;
return str.compare(0, prefix_len, prefix, 0, prefix_len) == 0;
}
/**
* Check whether the given string starts with the given prefix, ignoring case.
* @param str The string to look at.
@ -456,19 +443,6 @@ bool StrStartsWithIgnoreCase(std::string_view str, const std::string_view prefix
return StrEqualsIgnoreCase(str.substr(0, prefix.size()), prefix);
}
/**
* Check whether the given string ends with the given suffix.
* @param str The string to look at.
* @param suffix The suffix to look for.
* @return True iff the end of the string is the same as the suffix.
*/
bool StrEndsWith(const std::string_view str, const std::string_view suffix)
{
size_t suffix_len = suffix.size();
if (str.size() < suffix_len) return false;
return str.compare(str.size() - suffix_len, suffix_len, suffix, 0, suffix_len) == 0;
}
/** Case insensitive implementation of the standard character type traits. */
struct CaseInsensitiveCharTraits : public std::char_traits<char> {
static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }

@ -29,7 +29,6 @@
#include <iterator>
#include "core/bitmath_func.hpp"
#include "core/span_type.hpp"
#include "string_type.h"
char *strecat(char *dst, const char *src, const char *last) NOACCESS(3);
@ -42,7 +41,7 @@ int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap)
std::string CDECL stdstr_fmt(const char *str, ...) WARN_FORMAT(1, 2);
std::string stdstr_vfmt(const char *str, va_list va) WARN_FORMAT(1, 0);
std::string FormatArrayAsHex(span<const byte> data);
std::string FormatArrayAsHex(std::span<const byte> data);
char *StrMakeValidInPlace(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) NOACCESS(2);
[[nodiscard]] std::string StrMakeValid(std::string_view str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
@ -73,9 +72,7 @@ inline const char *StrLastPathSegment(const std::string &path)
return StrLastPathSegment(path.c_str());
}
[[nodiscard]] bool StrStartsWith(const std::string_view str, const std::string_view prefix);
[[nodiscard]] bool StrStartsWithIgnoreCase(std::string_view str, const std::string_view prefix);
[[nodiscard]] bool StrEndsWith(const std::string_view str, const std::string_view suffix);
[[nodiscard]] bool StrEndsWithIgnoreCase(std::string_view str, const std::string_view suffix);
[[nodiscard]] int StrCompareIgnoreCase(const std::string_view str1, const std::string_view str2);

@ -132,7 +132,7 @@ void SetDParamMaxDigits(size_t n, uint count, FontSize size)
* Copy the parameters from the backup into the global string parameter array.
* @param backup The backup to copy from.
*/
void CopyInDParam(const span<const StringParameterBackup> backup, uint offset)
void CopyInDParam(const std::span<const StringParameterBackup> backup, uint offset)
{
for (size_t i = 0; i < backup.size(); i++) {
auto &value = backup[i];

@ -15,7 +15,6 @@
#include "string_type.h"
#include "gfx_type.h"
#include "core/bitmath_func.hpp"
#include "core/span_type.hpp"
#include "vehicle_type.h"
#include <array>
#include <optional>
@ -103,7 +102,7 @@ void SetDParamMaxDigits(size_t n, uint count, FontSize size = FS_NORMAL);
void SetDParamStr(size_t n, const char *str);
void SetDParamStr(size_t n, std::string str);
void CopyInDParam(const span<const StringParameterBackup> backup, uint offset = 0);
void CopyInDParam(const std::span<const StringParameterBackup> backup, uint offset = 0);
void CopyOutDParam(std::vector<StringParameterBackup> &backup, size_t num);
bool HaveDParamChanged(const std::vector<StringParameterBackup> &backup);

@ -11,7 +11,6 @@
#define STRINGS_INTERNAL_H
#include "string_func.h"
#include "core/span_type.hpp"
#include "core/strong_typedef_type.hpp"
#include <array>
@ -27,12 +26,12 @@ struct StringParameter {
class StringParameters {
protected:
StringParameters *parent = nullptr; ///< If not nullptr, this instance references data from this parent instance.
span<StringParameter> parameters = {}; ///< Array with the actual parameters.
std::span<StringParameter> parameters = {}; ///< Array with the actual parameters.
size_t offset = 0; ///< Current offset in the parameters span.
char32_t next_type = 0; ///< The type of the next data that is retrieved.
StringParameters(span<StringParameter> parameters = {}) :
StringParameters(std::span<StringParameter> parameters = {}) :
parameters(parameters)
{}
@ -211,7 +210,7 @@ class ArrayStringParameters : public StringParameters {
public:
ArrayStringParameters()
{
this->parameters = span(params.data(), params.size());
this->parameters = std::span(params.data(), params.size());
}
ArrayStringParameters(ArrayStringParameters&& other) noexcept
@ -224,7 +223,7 @@ public:
this->offset = other.offset;
this->next_type = other.next_type;
this->params = std::move(other.params);
this->parameters = span(params.data(), params.size());
this->parameters = std::span(params.data(), params.size());
return *this;
}

@ -225,9 +225,9 @@ void SurveyConfiguration(nlohmann::json &survey)
survey["graphics_set"] = fmt::format("{}.{}", BaseGraphics::GetUsedSet()->name, BaseGraphics::GetUsedSet()->version);
const GRFConfig *extra_cfg = BaseGraphics::GetUsedSet()->GetExtraConfig();
if (extra_cfg != nullptr && extra_cfg->num_params > 0) {
survey["graphics_set_parameters"] = span<const uint32_t>(extra_cfg->param.data(), extra_cfg->num_params);
survey["graphics_set_parameters"] = std::span<const uint32_t>(extra_cfg->param.data(), extra_cfg->num_params);
} else {
survey["graphics_set_parameters"] = span<const uint32_t>();
survey["graphics_set_parameters"] = std::span<const uint32_t>();
}
}
if (BaseMusic::GetUsedSet() != nullptr) {
@ -318,7 +318,7 @@ void SurveyGrfs(nlohmann::json &survey)
if ((c->palette & GRFP_BLT_MASK) == GRFP_BLT_32BPP) grf["blitter"] = "32bpp";
grf["is_static"] = HasBit(c->flags, GCF_STATIC);
grf["parameters"] = span<const uint32_t>(c->param.data(), c->num_params);
grf["parameters"] = std::span<const uint32_t>(c->param.data(), c->num_params);
}
}

@ -164,97 +164,6 @@ TEST_CASE("StrEqualsIgnoreCase - std::string_view")
/**** String starts with *****/
TEST_CASE("StrStartsWith - std::string")
{
/* Everything starts with an empty prefix. */
CHECK(StrStartsWith(std::string{""}, std::string{""}));
CHECK(StrStartsWith(std::string{"a"}, std::string{""}));
/* Equal strings. */
CHECK(StrStartsWith(std::string{"a"}, std::string{"a"}));
CHECK(StrStartsWith(std::string{"A"}, std::string{"A"}));
/* Starts with same. */
CHECK(StrStartsWith(std::string{"ab"}, std::string{"a"}));
CHECK(StrStartsWith(std::string{"Ab"}, std::string{"A"}));
/* Different cases. */
CHECK(!StrStartsWith(std::string{"a"}, std::string{"A"}));
CHECK(!StrStartsWith(std::string{"A"}, std::string{"a"}));
CHECK(!StrStartsWith(std::string{"ab"}, std::string{"A"}));
CHECK(!StrStartsWith(std::string{"Ab"}, std::string{"a"}));
/* Does not start the same. */
CHECK(!StrStartsWith(std::string{""}, std::string{"b"}));
CHECK(!StrStartsWith(std::string{"a"}, std::string{"b"}));
CHECK(!StrStartsWith(std::string{"b"}, std::string{"a"}));
CHECK(!StrStartsWith(std::string{"a"}, std::string{"aa"}));
}
TEST_CASE("StrStartsWith - char pointer")
{
CHECK(StrStartsWith("", ""));
CHECK(StrStartsWith("a", ""));
/* Equal strings. */
CHECK(StrStartsWith("a", "a"));
CHECK(StrStartsWith("A", "A"));
/* Starts with same. */
CHECK(StrStartsWith("ab", "a"));
CHECK(StrStartsWith("Ab", "A"));
/* Different cases. */
CHECK(!StrStartsWith("a", "A"));
CHECK(!StrStartsWith("A", "a"));
CHECK(!StrStartsWith("ab", "A"));
CHECK(!StrStartsWith("Ab", "a"));
/* Does not start the same. */
CHECK(!StrStartsWith("", "b"));
CHECK(!StrStartsWith("a", "b"));
CHECK(!StrStartsWith("b", "a"));
CHECK(!StrStartsWith("a", "aa"));
}
TEST_CASE("StrStartsWith - std::string_view")
{
/*
* With std::string_view the only way to access the data is via .data(),
* which does not guarantee the termination that would be required by
* things such as stricmp/strcasecmp. So, just passing .data() into stricmp
* or strcasecmp would fail if it does not account for the length of the
* view. Thus, contrary to the string/char* tests, this uses the same base
* string but gets different sections to trigger these corner cases.
*/
std::string_view base{"aabAb"};
/* Everything starts with an empty prefix. */
CHECK(StrStartsWith(base.substr(0, 0), base.substr(1, 0))); // Different positions
CHECK(StrStartsWith(base.substr(0, 1), base.substr(0, 0)));
/* Equals string. */
CHECK(StrStartsWith(base.substr(0, 1), base.substr(1, 1))); // Different positions
CHECK(StrStartsWith(base.substr(3, 1), base.substr(3, 1)));
/* Starts with same. */
CHECK(StrStartsWith(base.substr(1, 2), base.substr(0, 1)));
CHECK(StrStartsWith(base.substr(3, 2), base.substr(3, 1)));
/* Different cases. */
CHECK(!StrStartsWith(base.substr(0, 1), base.substr(3, 1)));
CHECK(!StrStartsWith(base.substr(3, 1), base.substr(0, 1)));
CHECK(!StrStartsWith(base.substr(1, 2), base.substr(3, 1)));
CHECK(!StrStartsWith(base.substr(3, 2), base.substr(0, 1)));
/* Does not start the same. */
CHECK(!StrStartsWith(base.substr(2, 0), base.substr(2, 1)));
CHECK(!StrStartsWith(base.substr(0, 1), base.substr(2, 1)));
CHECK(!StrStartsWith(base.substr(2, 1), base.substr(0, 1)));
CHECK(!StrStartsWith(base.substr(0, 1), base.substr(0, 2)));
}
TEST_CASE("StrStartsWithIgnoreCase - std::string")
{
/* Everything starts with an empty prefix. */
@ -342,97 +251,6 @@ TEST_CASE("StrStartsWithIgnoreCase - std::string_view")
/**** String ends with *****/
TEST_CASE("StrEndsWith - std::string")
{
/* Everything ends with an empty prefix. */
CHECK(StrEndsWith(std::string{""}, std::string{""}));
CHECK(StrEndsWith(std::string{"a"}, std::string{""}));
/* Equal strings. */
CHECK(StrEndsWith(std::string{"a"}, std::string{"a"}));
CHECK(StrEndsWith(std::string{"A"}, std::string{"A"}));
/* Ends with same. */
CHECK(StrEndsWith(std::string{"ba"}, std::string{"a"}));
CHECK(StrEndsWith(std::string{"bA"}, std::string{"A"}));
/* Different cases. */
CHECK(!StrEndsWith(std::string{"a"}, std::string{"A"}));
CHECK(!StrEndsWith(std::string{"A"}, std::string{"a"}));
CHECK(!StrEndsWith(std::string{"ba"}, std::string{"A"}));
CHECK(!StrEndsWith(std::string{"bA"}, std::string{"a"}));
/* Does not end the same. */
CHECK(!StrEndsWith(std::string{""}, std::string{"b"}));
CHECK(!StrEndsWith(std::string{"a"}, std::string{"b"}));
CHECK(!StrEndsWith(std::string{"b"}, std::string{"a"}));
CHECK(!StrEndsWith(std::string{"a"}, std::string{"aa"}));
}
TEST_CASE("StrEndsWith - char pointer")
{
CHECK(StrEndsWith("", ""));
CHECK(StrEndsWith("a", ""));
/* Equal strings. */
CHECK(StrEndsWith("a", "a"));
CHECK(StrEndsWith("A", "A"));
/* Ends with same. */
CHECK(StrEndsWith("ba", "a"));
CHECK(StrEndsWith("bA", "A"));
/* Different cases. */
CHECK(!StrEndsWith("a", "A"));
CHECK(!StrEndsWith("A", "a"));
CHECK(!StrEndsWith("ba", "A"));
CHECK(!StrEndsWith("bA", "a"));
/* Does not end the same. */
CHECK(!StrEndsWith("", "b"));
CHECK(!StrEndsWith("a", "b"));
CHECK(!StrEndsWith("b", "a"));
CHECK(!StrEndsWith("a", "aa"));
}
TEST_CASE("StrEndsWith - std::string_view")
{
/*
* With std::string_view the only way to access the data is via .data(),
* which does not guarantee the termination that would be required by
* things such as stricmp/strcasecmp. So, just passing .data() into stricmp
* or strcasecmp would fail if it does not account for the length of the
* view. Thus, contrary to the string/char* tests, this uses the same base
* string but gets different sections to trigger these corner cases.
*/
std::string_view base{"aabAba"};
/* Everything ends with an empty prefix. */
CHECK(StrEndsWith(base.substr(0, 0), base.substr(1, 0))); // Different positions
CHECK(StrEndsWith(base.substr(0, 1), base.substr(0, 0)));
/* Equals string. */
CHECK(StrEndsWith(base.substr(0, 1), base.substr(1, 1))); // Different positions
CHECK(StrEndsWith(base.substr(3, 1), base.substr(3, 1)));
/* Ends with same. */
CHECK(StrEndsWith(base.substr(4, 2), base.substr(0, 1)));
CHECK(StrEndsWith(base.substr(2, 2), base.substr(3, 1)));
/* Different cases. */
CHECK(!StrEndsWith(base.substr(0, 1), base.substr(3, 1)));
CHECK(!StrEndsWith(base.substr(3, 1), base.substr(0, 1)));
CHECK(!StrEndsWith(base.substr(4, 2), base.substr(3, 1)));
CHECK(!StrEndsWith(base.substr(2, 2), base.substr(0, 1)));
/* Does not end the same. */
CHECK(!StrEndsWith(base.substr(2, 0), base.substr(2, 1)));
CHECK(!StrEndsWith(base.substr(0, 1), base.substr(2, 1)));
CHECK(!StrEndsWith(base.substr(2, 1), base.substr(0, 1)));
CHECK(!StrEndsWith(base.substr(0, 1), base.substr(0, 2)));
}
TEST_CASE("StrEndsWithIgnoreCase - std::string")
{
/* Everything ends with an empty prefix. */

@ -179,14 +179,14 @@ enum class HyperlinkType {
static HyperlinkType ClassifyHyperlink(const std::string &destination, bool trusted)
{
if (destination.empty()) return HyperlinkType::Unknown;
if (StrStartsWith(destination, "#")) return HyperlinkType::Internal;
if (destination.starts_with("#")) return HyperlinkType::Internal;
/* Only allow external / internal links for sources we trust. */
if (!trusted) return HyperlinkType::Unknown;
if (StrStartsWith(destination, "http://")) return HyperlinkType::Web;
if (StrStartsWith(destination, "https://")) return HyperlinkType::Web;
if (StrStartsWith(destination, "./")) return HyperlinkType::File;
if (destination.starts_with("http://")) return HyperlinkType::Web;
if (destination.starts_with("https://")) return HyperlinkType::Web;
if (destination.starts_with("./")) return HyperlinkType::File;
return HyperlinkType::Unknown;
}
@ -430,7 +430,7 @@ void TextfileWindow::NavigateHistory(int delta)
void TextfileWindow::NavigateToFile(std::string newfile, size_t line)
{
/* Double-check that the file link begins with ./ as a relative path. */
if (!StrStartsWith(newfile, "./")) return;
if (!newfile.starts_with("./")) return;
/* Get the path portion of the current file path. */
std::string newpath = this->filepath;
@ -790,12 +790,12 @@ static void Xunzip(byte **bufp, size_t *sizep)
#if defined(WITH_ZLIB)
/* In-place gunzip */
if (StrEndsWith(textfile, ".gz")) Gunzip((byte**)&buf, &filesize);
if (std::string_view(textfile).ends_with(".gz")) Gunzip((byte**)&buf, &filesize);
#endif
#if defined(WITH_LIBLZMA)
/* In-place xunzip */
if (StrEndsWith(textfile, ".xz")) Xunzip((byte**)&buf, &filesize);
if (std::string_view(textfile).ends_with(".xz")) Xunzip((byte**)&buf, &filesize);
#endif
if (buf == nullptr) return;
@ -803,7 +803,7 @@ static void Xunzip(byte **bufp, size_t *sizep)
std::string_view sv_buf(buf, filesize);
/* Check for the byte-order-mark, and skip it if needed. */
if (StrStartsWith(sv_buf, "\ufeff")) sv_buf.remove_prefix(3);
if (sv_buf.starts_with("\ufeff")) sv_buf.remove_prefix(3);
/* Update the filename. */
this->filepath = textfile;

@ -48,7 +48,6 @@
#include "zoom_func.h"
#include "group_gui_list.h"
#include "newgrf_debug.h"
#include "core/span_type.hpp"
#include "3rdparty/cpp-btree/btree_map.h"
#include "safeguards.h"
@ -549,9 +548,9 @@ struct TraceRestrictDropDownListItem {
};
/**
* Return the appropriate type dropdown TraceRestrictDropDownListItem span for the given item type @p type
* Return the appropriate type dropdown TraceRestrictDropDownListItem std::span for the given item type @p type
*/
static span<const TraceRestrictDropDownListItem> GetTypeDropDownListItems(TraceRestrictGuiItemType type)
static std::span<const TraceRestrictDropDownListItem> GetTypeDropDownListItems(TraceRestrictGuiItemType type)
{
static const TraceRestrictDropDownListItem actions[] = {
{ TRIT_PF_DENY, STR_TRACE_RESTRICT_PF_DENY, TRDDLIF_NONE },
@ -602,9 +601,9 @@ static span<const TraceRestrictDropDownListItem> GetTypeDropDownListItems(TraceR
};
if (IsTraceRestrictTypeConditional(ItemTypeFromGuiType(type))) {
return span<const TraceRestrictDropDownListItem>(conditions);
return std::span<const TraceRestrictDropDownListItem>(conditions);
} else {
return span<const TraceRestrictDropDownListItem>(actions);
return std::span<const TraceRestrictDropDownListItem>(actions);
}
}

@ -119,6 +119,7 @@
#include "core/backup_type.hpp"
#include "3rdparty/robin_hood/robin_hood.h"
#include <bit>
#include <map>
#include <vector>
#include <math.h>
@ -6670,7 +6671,7 @@ static LineSnapPoint LineSnapPointAtRailTrackEndpoint(TileIndex tile, DiagDirect
SetBit(ret.dirs, DiagDirToDir(exit_dir));
SetBit(ret.dirs, ChangeDir(DiagDirToDir(exit_dir), DIRDIFF_45LEFT));
SetBit(ret.dirs, ChangeDir(DiagDirToDir(exit_dir), DIRDIFF_45RIGHT));
if (bidirectional) ret.dirs |= ROR<uint8_t>(ret.dirs, DIRDIFF_REVERSE);
if (bidirectional) ret.dirs |= std::rotr<uint8_t>(ret.dirs, DIRDIFF_REVERSE);
return ret;
}
@ -6785,7 +6786,7 @@ static void SetRailSnapTile(TileIndex tile)
for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
_tile_snap_points.push_back(LineSnapPointAtRailTrackEndpoint(tile, dir, false));
LineSnapPoint &point = _tile_snap_points.back();
point.dirs = ROR<uint8_t>(point.dirs, DIRDIFF_REVERSE);
point.dirs = std::rotr<uint8_t>(point.dirs, DIRDIFF_REVERSE);
}
}

Loading…
Cancel
Save