66#include < algorithm>
77#include < cstddef>
88#include < cstdint>
9+ #include < limits>
910#include < system_error>
1011#include < vector>
1112
2122#include " openvic-simulation/modifier/ModifierManager.hpp"
2223#include " openvic-simulation/types/Colour.hpp"
2324#include " openvic-simulation/types/OrderedContainersMath.hpp"
25+ #include " openvic-simulation/types/TypedSpan.hpp"
2426#include " openvic-simulation/types/Vector.hpp"
2527#include " openvic-simulation/utility/BMP.hpp"
2628#include " openvic-simulation/utility/FormatValidate.hpp"
@@ -48,11 +50,14 @@ ProvinceDefinition const* MapDefinition::get_province_definition_from_number(
4850RiverSegment::RiverSegment (uint8_t new_size, memory::vector<ivec2_t >&& new_points)
4951 : size { new_size }, points { std::move (new_points) } {}
5052
53+ // 1 entry reserved for null province
54+ static constexpr province_index_t MAX_PROVINCE_COUNT = std::numeric_limits<province_index_t >().max() - 1;
55+
5156bool MapDefinition::add_province_definition (std::string_view identifier, colour_t colour) {
5257 if (province_definitions.size () >= type_safe::get (max_provinces)) {
5358 spdlog::error_s (
5459 " The map's province list is full - maximum number of provinces is {} (this can be at most {})" ,
55- max_provinces, ProvinceDefinition::MAX_INDEX
60+ max_provinces, MAX_PROVINCE_COUNT
5661 );
5762 return false ;
5863 }
@@ -71,24 +76,24 @@ bool MapDefinition::add_province_definition(std::string_view identifier, colour_
7176 spdlog::error_s (" Invalid province colour for {} - null! ({})" , identifier, colour);
7277 return false ;
7378 }
74- const ProvinceDefinition::index_t province_number = get_province_number_from_colour (colour);
75- if (province_number != ProvinceDefinition::NULL_INDEX ) {
79+ const ProvinceDefinition::province_number_t province_number = get_province_number_from_colour (colour);
80+ if (province_number != ProvinceDefinition::NULL_PROVINCE_NUMBER ) {
7681 spdlog::error_s (
7782 " Duplicate province colours: {} and {}" ,
78- get_province_definition_from_number (type_safe::get ( province_number) )->to_string (), identifier
83+ get_province_definition_from_number (province_number)->to_string (), identifier
7984 );
8085 return false ;
8186 }
8287
8388 if (!province_definitions.emplace_item (
8489 identifier,
85- identifier, colour, ProvinceDefinition::index_t (get_province_definition_count ())
90+ identifier, colour, province_index_t (get_province_definition_count ())
8691 )) {
8792 return false ;
8893 }
8994
9095 ProvinceDefinition const & new_province = province_definitions.back ();
91- colour_index_map[new_province.get_colour ()] = ProvinceDefinition::index_t (new_province.get_province_number ());
96+ colour_index_map[new_province.get_colour ()] = province_index_t (new_province.get_province_number ());
9297 return true ;
9398}
9499
@@ -468,34 +473,42 @@ bool MapDefinition::add_region(std::string_view identifier, memory::vector<Provi
468473 return ret;
469474}
470475
471- ProvinceDefinition::index_t MapDefinition::get_province_number_from_colour (colour_t colour) const {
476+ ProvinceDefinition::province_number_t MapDefinition::get_province_number_from_colour (colour_t colour) const {
472477 const colour_index_map_t ::const_iterator it = colour_index_map.find (colour);
473478 if (it != colour_index_map.end ()) {
474- return it-> second ;
479+ return ProvinceDefinition::get_province_number_from_index (it. value ()) ;
475480 }
476- return ProvinceDefinition::NULL_INDEX ;
481+ return ProvinceDefinition::NULL_PROVINCE_NUMBER ;
477482}
478483
479- ProvinceDefinition::index_t MapDefinition::get_province_number_at (ivec2_t pos) const {
484+ ProvinceDefinition::province_number_t MapDefinition::get_province_number_at (ivec2_t pos) const {
480485 if (pos.nonnegative () && pos.is_within_bound (dims)) {
481486 return province_shape_image[get_pixel_index_from_pos (pos)].province_number ;
482487 }
483- return ProvinceDefinition::NULL_INDEX ;
488+ return ProvinceDefinition::NULL_PROVINCE_NUMBER ;
484489}
485490
486491ProvinceDefinition* MapDefinition::get_province_definition_at (ivec2_t pos) {
487- return get_province_definition_from_number (type_safe::get ( get_province_number_at (pos) ));
492+ return get_province_definition_from_number (get_province_number_at (pos));
488493}
489494
490495ProvinceDefinition const * MapDefinition::get_province_definition_at (ivec2_t pos) const {
491- return get_province_definition_from_number (type_safe::get ( get_province_number_at (pos) ));
496+ return get_province_definition_from_number (get_province_number_at (pos));
492497}
493498
494- bool MapDefinition::set_max_provinces (ProvinceDefinition::index_t new_max_provinces) {
495- if (new_max_provinces <= ProvinceDefinition::NULL_INDEX) {
499+ bool MapDefinition::set_max_provinces (province_index_t new_max_provinces) {
500+ if (new_max_provinces <= province_index_t (0 )) {
501+ spdlog::error_s (
502+ " Trying to set max province count to an invalid value {} (must be greater than 0)" ,
503+ new_max_provinces
504+ );
505+ return false ;
506+ }
507+ if (new_max_provinces > MAX_PROVINCE_COUNT) {
496508 spdlog::error_s (
497- " Trying to set max province count to an invalid value {} (must be greater than {})" ,
498- new_max_provinces, ProvinceDefinition::NULL_INDEX
509+ " Trying to set max province count to an invalid value {} (must <= {})" ,
510+ new_max_provinces,
511+ MAX_PROVINCE_COUNT
499512 );
500513 return false ;
501514 }
@@ -847,19 +860,22 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
847860 uint8_t const * province_data = province_bmp.get_pixel_data ().data ();
848861 uint8_t const * terrain_data = terrain_bmp.get_pixel_data ().data ();
849862
850- memory::vector<fixed_point_map_t <TerrainType const *>> terrain_type_pixels_list (province_definitions.size ());
863+ memory::FixedVector<fixed_point_map_t <TerrainType const *>> _terrain_type_pixels_list (province_definitions.size ());
864+ TypedSpan<province_index_t , fixed_point_map_t <TerrainType const *>> terrain_type_pixels_list { _terrain_type_pixels_list };
851865
852866 bool ret = true ;
853867 ordered_set<colour_t > unrecognised_province_colours;
854868
855- memory::vector<fixed_point_t > pixels_per_province (province_definitions.size ());
856- memory::vector<fvec2_t > pixel_position_sum_per_province (province_definitions.size ());
869+ memory::FixedVector<fixed_point_t > _pixels_per_province (province_definitions.size ());
870+ TypedSpan<province_index_t , fixed_point_t > pixels_per_province { _pixels_per_province };
871+ memory::FixedVector<fvec2_t > _pixel_position_sum_per_province (province_definitions.size ());
872+ TypedSpan<province_index_t , fvec2_t > pixel_position_sum_per_province { _pixel_position_sum_per_province };
857873
858874 for (ivec2_t pos {}; pos.y < get_height (); ++pos.y ) {
859875 for (pos.x = 0 ; pos.x < get_width (); ++pos.x ) {
860876 const size_t pixel_index = get_pixel_index_from_pos (pos);
861877 const colour_t province_colour = colour_at (province_data, pixel_index);
862- ProvinceDefinition::index_t province_number = ProvinceDefinition::NULL_INDEX ;
878+ ProvinceDefinition::province_number_t province_number = ProvinceDefinition::NULL_PROVINCE_NUMBER ;
863879
864880 if (pos.x > 0 ) {
865881 const size_t jdx = pixel_index - 1 ;
@@ -879,7 +895,7 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
879895
880896 province_number = get_province_number_from_colour (province_colour);
881897
882- if (province_number == ProvinceDefinition::NULL_INDEX && !unrecognised_province_colours.contains (province_colour)) {
898+ if (province_number == ProvinceDefinition::NULL_PROVINCE_NUMBER && !unrecognised_province_colours.contains (province_colour)) {
883899 unrecognised_province_colours.insert (province_colour);
884900 if (detailed_errors) {
885901 spdlog::warn_s (
@@ -892,17 +908,18 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
892908 index_found:
893909 province_shape_image[pixel_index].province_number = province_number;
894910
895- if (province_number != ProvinceDefinition::NULL_INDEX ) {
896- const ProvinceDefinition:: index_t array_index = province_number - 1 ;
897- pixels_per_province[type_safe::get (array_index) ]++;
898- pixel_position_sum_per_province[type_safe::get (array_index) ] += static_cast <fvec2_t >(pos);
911+ if (province_number != ProvinceDefinition::NULL_PROVINCE_NUMBER ) {
912+ const province_index_t province_index = ProvinceDefinition::get_index_from_province_number ( province_number) ;
913+ pixels_per_province[province_index ]++;
914+ pixel_position_sum_per_province[province_index ] += static_cast <fvec2_t >(pos);
899915 }
900916
901917 const TerrainTypeMapping::index_t terrain = terrain_data[pixel_index];
902918 TerrainTypeMapping const * mapping = terrain_type_manager.get_terrain_type_mapping_for (terrain);
903919 if (mapping != nullptr ) {
904- if (province_number != ProvinceDefinition::NULL_INDEX) {
905- terrain_type_pixels_list[type_safe::get (province_number - 1 )][&mapping->type ]++;
920+ if (province_number != ProvinceDefinition::NULL_PROVINCE_NUMBER) {
921+ const province_index_t province_index = ProvinceDefinition::get_index_from_province_number (province_number);
922+ terrain_type_pixels_list[province_index][&mapping->type ]++;
906923 }
907924 if (mapping->has_texture && terrain < terrain_type_manager.get_terrain_texture_limit ()) {
908925 province_shape_image[pixel_index].terrain = terrain + 1 ;
@@ -920,21 +937,20 @@ bool MapDefinition::load_map_images(fs::path const& province_path, fs::path cons
920937 }
921938
922939 size_t missing = 0 ;
923- for (size_t array_index = 0 ; array_index < province_definitions.size (); ++array_index) {
924- ProvinceDefinition* province = province_definitions.get_item_by_index (array_index);
925-
926- fixed_point_map_t <TerrainType const *> const & terrain_type_pixels = terrain_type_pixels_list[array_index];
940+ for (ProvinceDefinition& province : province_definitions.get_items ()) {
941+ const province_index_t province_index = province.index ;
942+ fixed_point_map_t <TerrainType const *> const & terrain_type_pixels = terrain_type_pixels_list[province_index];
927943 const fixed_point_map_const_iterator_t <TerrainType const *> largest = get_largest_item (terrain_type_pixels);
928- province-> default_terrain_type = largest != terrain_type_pixels.end () ? largest->first : nullptr ;
944+ province. default_terrain_type = largest != terrain_type_pixels.end () ? largest->first : nullptr ;
929945
930- const fixed_point_t pixel_count = pixels_per_province[array_index ];
931- province-> on_map = pixel_count > 0 ;
946+ const fixed_point_t pixel_count = pixels_per_province[province_index ];
947+ province. on_map = pixel_count > 0 ;
932948
933- if (province-> on_map ) {
934- province-> centre = pixel_position_sum_per_province[array_index ] / pixel_count;
949+ if (province. on_map ) {
950+ province. centre = pixel_position_sum_per_province[province_index ] / pixel_count;
935951 } else {
936952 if (detailed_errors) {
937- spdlog::warn_s (" Province missing from shape image: {}" , province-> to_string ());
953+ spdlog::warn_s (" Province missing from shape image: {}" , province. to_string ());
938954 }
939955 missing++;
940956 }
0 commit comments