diff --git a/.clang-format b/.clang-format index ad4509ef2..09e930722 100644 --- a/.clang-format +++ b/.clang-format @@ -30,7 +30,7 @@ BraceWrapping: AfterFunction: true # see AllowShortFunctionsOnASingleLine AfterNamespace: false AfterStruct: true - AfterExternBlock: true + AfterExternBlock: false BeforeCatch: false BeforeElse: true BeforeLambdaBody: false diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 252ef2567..1a00430ae 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -9,7 +9,17 @@ on: - "**" jobs: + checkSource: + name: Check Source Code + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - uses: pre-commit/action@v3.0.0 + windows: + needs: checkSource name: Windows memory mapped uses: ./.github/workflows/windows.yml with: @@ -20,8 +30,9 @@ jobs: BUILD_SHARED: true secrets: NUGET_REGISTRY_PAT: ${{ secrets.VCPKG_CACHE_PAT }} - + windows-mmf-off: + needs: checkSource name: Windows file based uses: ./.github/workflows/windows.yml with: @@ -46,6 +57,7 @@ jobs: NUGET_REGISTRY_PAT: ${{ secrets.VCPKG_CACHE_PAT }} ubuntu: + needs: checkSource name: Linux memory mapped uses: ./.github/workflows/ubuntu.yml with: @@ -58,6 +70,7 @@ jobs: NUGET_REGISTRY_PAT: ${{ secrets.VCPKG_CACHE_PAT }} ubuntu-mmf-off: + needs: checkSource name: Linux file based uses: ./.github/workflows/ubuntu.yml with: @@ -82,6 +95,7 @@ jobs: NUGET_REGISTRY_PAT: ${{ secrets.VCPKG_CACHE_PAT }} macos: + needs: checkSource name: MacOS memory mapped uses: ./.github/workflows/macos.yml with: @@ -94,6 +108,7 @@ jobs: NUGET_REGISTRY_PAT: ${{ secrets.VCPKG_CACHE_PAT }} macos-mmf-off: + needs: checkSource name: MacOS file based uses: ./.github/workflows/macos.yml with: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..0df4f091e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,16 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.3.0 + hooks: + - id: trailing-whitespace + files: ^.*\.cmake|CMakeLists\.txt$ + - id: end-of-file-fixer + files: ^.*\.cmake|CMakeLists\.txt$ + + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v14.0.6 + hooks: + - id: clang-format + types_or: [c++, c] diff --git a/CMakeLists.txt b/CMakeLists.txt index ae664dd95..a09e6f1f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,11 +5,11 @@ cmake_minimum_required(VERSION 3.15) include(cmake/GetVersion.cmake) get_mapnik_version() -project(mapnik +project(mapnik VERSION ${MAPNIK_MAJOR_VERSION}.${MAPNIK_MINOR_VERSION}.${MAPNIK_PATCH_VERSION} - HOMEPAGE_URL "https://mapnik.org/" - DESCRIPTION "Mapnik is an open source toolkit for developing mapping applications" - LANGUAGES CXX + HOMEPAGE_URL "https://mapnik.org/" + DESCRIPTION "Mapnik is an open source toolkit for developing mapping applications" + LANGUAGES CXX ) message(STATUS "mapnik version: ${PROJECT_VERSION}") @@ -167,7 +167,7 @@ if(harfbuzz_FOUND) message(STATUS "Found harfbuzz native cmake") list(APPEND MAPNIK_OPTIONAL_LIBS harfbuzz::harfbuzz) else() - # Use pkg-config when harfbuzz is not found. + # Use pkg-config when harfbuzz is not found. # It might be possible that in future version harfbuzz could only be found via pkg-config. # harfbuzz related discussion: https://github.com/harfbuzz/harfbuzz/issues/2653 message(STATUS "harfbuzz not found via cmake. Searching via pkg-config...") @@ -182,13 +182,13 @@ if(USE_EXTERNAL_MAPBOX_GEOMETRY) find_path(MAPBOX_GEOMETRY_INCLUDE_DIRS "mapbox/geometry.hpp" REQUIRED) endif() else() - set(MAPBOX_GEOMETRY_INCLUDE_DIRS + set(MAPBOX_GEOMETRY_INCLUDE_DIRS $ $ ) endif() if(NOT MAPBOX_GEOMETRY_INCLUDE_DIRS) - message(FATAL_ERROR "Set -DMAPBOX_GEOMETRY_INCLUDE_DIRS to the mapbox/geometry.hpp include dir") + message(FATAL_ERROR "Set -DMAPBOX_GEOMETRY_INCLUDE_DIRS to the mapbox/geometry.hpp include dir") endif() if(USE_EXTERNAL_MAPBOX_POLYLABEL) @@ -197,13 +197,13 @@ if(USE_EXTERNAL_MAPBOX_POLYLABEL) find_path(MAPBOX_POLYLABEL_INCLUDE_DIRS "mapbox/polylabel.hpp") endif() else() - set(MAPBOX_POLYLABEL_INCLUDE_DIRS + set(MAPBOX_POLYLABEL_INCLUDE_DIRS $ $ ) endif() if(NOT MAPBOX_POLYLABEL_INCLUDE_DIRS) - message(FATAL_ERROR "Set MAPBOX_POLYLABEL_INCLUDE_DIRS to the mapbox/geometry include dir") + message(FATAL_ERROR "Set MAPBOX_POLYLABEL_INCLUDE_DIRS to the mapbox/geometry include dir") endif() if(USE_EXTERNAL_MAPBOX_PROTOZERO) @@ -212,13 +212,13 @@ if(USE_EXTERNAL_MAPBOX_PROTOZERO) find_path(MAPBOX_PROTOZERO_INCLUDE_DIRS "protozero/pbf_message.hpp") endif() else() - set(MAPBOX_PROTOZERO_INCLUDE_DIRS + set(MAPBOX_PROTOZERO_INCLUDE_DIRS $ $ ) endif() if(NOT MAPBOX_PROTOZERO_INCLUDE_DIRS) - message(FATAL_ERROR "Set MAPBOX_PROTOZERO_INCLUDE_DIRS to the mapbox/protozero include dir") + message(FATAL_ERROR "Set MAPBOX_PROTOZERO_INCLUDE_DIRS to the mapbox/protozero include dir") endif() if(USE_EXTERNAL_MAPBOX_VARIANT) @@ -227,13 +227,13 @@ if(USE_EXTERNAL_MAPBOX_VARIANT) find_path(MAPBOX_VARIANT_INCLUDE_DIRS "mapbox/variant.hpp") endif() else() - set(MAPBOX_VARIANT_INCLUDE_DIRS + set(MAPBOX_VARIANT_INCLUDE_DIRS $ $ ) endif() if(NOT MAPBOX_VARIANT_INCLUDE_DIRS) - message(FATAL_ERROR "Set MAPBOX_VARIANT_INCLUDE_DIRS to the mapbox/variant include dir") + message(FATAL_ERROR "Set MAPBOX_VARIANT_INCLUDE_DIRS to the mapbox/variant include dir") endif() # (used by MapnikInstall.cmake. properties are needed since "set(...)" will be out of scope @@ -245,7 +245,7 @@ if(USE_GLIBC_WORKAROUND) list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_ENABLE_GLIBC_WORKAROUND) endif() -if(USE_BIGINT) +if(USE_BIGINT) list(APPEND MAPNIK_COMPILE_DEFS BIGINT) endif() @@ -341,7 +341,7 @@ if(USE_SVG_RENDERER) list(APPEND MAPNIK_COMPILE_DEFS SVG_RENDERER) endif() -if(NOT WIN32) +if(NOT WIN32) message(STATUS "Compiling with -DMAPNIK_HAS_DLCFN") list(APPEND MAPNIK_COMPILE_DEFS MAPNIK_HAS_DLCFN) list(APPEND MAPNIK_OPTIONAL_LIBS ${CMAKE_DL_LIBS}) @@ -365,8 +365,8 @@ add_compile_options( add_library(core INTERFACE) add_library(mapnik::core ALIAS core) -target_include_directories(core INTERFACE - $ +target_include_directories(core INTERFACE + $ $ $ $ @@ -375,7 +375,7 @@ target_include_directories(core INTERFACE $ ${MAPNIK_OPTIONAL_LIBS_INCLUDE} ) -target_link_libraries(core INTERFACE +target_link_libraries(core INTERFACE Threads::Threads ICU::uc ICU::data diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 9aefc6b29..0d8e96059 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,6 +1,6 @@ project(mapnik-benchmark) -set(BENCHMARK_SRCS +set(BENCHMARK_SRCS src/normalize_angle.cpp src/test_array_allocation.cpp src/test_expression_parse.cpp @@ -32,7 +32,7 @@ function(mapnik_create_benchmark) add_executable(${TARGET_NAME} ${ARGV0}) target_include_directories(${TARGET_NAME} PRIVATE include) target_link_libraries(${TARGET_NAME} PRIVATE mapnik::agg mapnik::mapnik) - set_target_properties(${TARGET_NAME} PROPERTIES + set_target_properties(${TARGET_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib" @@ -46,7 +46,7 @@ foreach(benchmark ${BENCHMARK_SRCS}) endforeach() file(COPY data DESTINATION "${MAPNIK_OUTPUT_DIR}/benchmark") -file(COPY run_benchmarks - DESTINATION "${MAPNIK_OUTPUT_DIR}" +file(COPY run_benchmarks + DESTINATION "${MAPNIK_OUTPUT_DIR}" FILE_PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE GROUP_WRITE GROUP_READ GROUP_EXECUTE WORLD_READ ) diff --git a/cmake/MapnikExportPkgConfig.cmake b/cmake/MapnikExportPkgConfig.cmake index b4b9cd5ef..f92e1e203 100644 --- a/cmake/MapnikExportPkgConfig.cmake +++ b/cmake/MapnikExportPkgConfig.cmake @@ -9,7 +9,7 @@ Name: @_lib_name@ Description: @_description@ Version: @MAPNIK_VERSION@ Libs: -L"${libdir}" -l$$_POSTFIX> -Cflags: -I"${includedir}" ]] +Cflags: -I"${includedir}" ]] _contents @ONLY) file(GENERATE @@ -26,11 +26,11 @@ endfunction() function(create_pkg_config_file_mapnik _lib_name _description) get_target_property(m_compile_defs core INTERFACE_COMPILE_DEFINITIONS) string(JOIN " -D" m_str_compile_defs ${m_compile_defs}) - if(m_str_compile_defs) + if(m_str_compile_defs) set(m_str_compile_defs "-D${m_str_compile_defs}") endif() - set(m_requires + set(m_requires libmapnikwkt libmapnikjson icu-uc @@ -71,7 +71,7 @@ Description: @_description@ Version: @MAPNIK_VERSION@ Requires: @m_requires@ Libs: -L"${libdir}" -l$$_POSTFIX> -Cflags: -I"${includedir}" @m_str_compile_defs@]] +Cflags: -I"${includedir}" @m_str_compile_defs@]] _contents @ONLY) file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_lib_name}-$.pc diff --git a/cmake/MapnikInstall.cmake b/cmake/MapnikInstall.cmake index b12ccab4c..43e01b8dd 100644 --- a/cmake/MapnikInstall.cmake +++ b/cmake/MapnikInstall.cmake @@ -90,7 +90,7 @@ function(mapnik_install_targets) message(STATUS \"internal_executables: ${_internal_executables}\") message(STATUS \"internal_libraries: ${_internal_libraries}\") message(STATUS \"ADDITIONAL_LIBARIES_PATHS: ${ADDITIONAL_LIBARIES_PATHS}\") - + include(BundleUtilities) fixup_bundle(\"${_internal_executables}\" \"${_internal_libraries}\" \"${ADDITIONAL_LIBARIES_PATHS}\") " COMPONENT MapnikRuntime) diff --git a/cmake/clang-format.cmake b/cmake/clang-format.cmake index 7681ffbf2..33af54f8e 100644 --- a/cmake/clang-format.cmake +++ b/cmake/clang-format.cmake @@ -1,5 +1,5 @@ function(format_dir dir) - file(GLOB_RECURSE sources + file(GLOB_RECURSE sources "${dir}/*.cpp" "${dir}/*.hpp" ) diff --git a/cmake/mapnikConfig.cmake.in b/cmake/mapnikConfig.cmake.in index e0aee8778..e5553f964 100644 --- a/cmake/mapnikConfig.cmake.in +++ b/cmake/mapnikConfig.cmake.in @@ -32,14 +32,14 @@ function(mapnik_find_plugin_dir PLUGIN_DIR) string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type_l) set(_plugin_dir "${MAPNIK_PLUGINS_DIR_${_build_type_l}}") # only release has more then one configuration - if(NOT _plugin_dir) + if(NOT _plugin_dir) set(_all_rel_cfgs RELEASE RELWITHDEBINFO MINSIZEREL) list(FIND _all_rel_cfgs ${_build_type_l} _is_rel_cfg) # check if the current configuration is a known release configuration if(${_is_rel_cfg} GREATER_EQUAL 0) foreach(_rel_cfg IN LISTS _all_rel_cfgs) set(_plugin_dir "${MAPNIK_PLUGINS_DIR_${_rel_cfg}}") - if(_plugin_dir) + if(_plugin_dir) break() endif() endforeach() @@ -49,4 +49,4 @@ function(mapnik_find_plugin_dir PLUGIN_DIR) message(WARNING "Could not find a plugin install dir for configuration ${_build_type_l}") endif() set(${PLUGIN_DIR} ${_plugin_dir} PARENT_SCOPE) -endfunction() +endfunction() diff --git a/demo/c++/CMakeLists.txt b/demo/c++/CMakeLists.txt index fdf365528..567610f7e 100644 --- a/demo/c++/CMakeLists.txt +++ b/demo/c++/CMakeLists.txt @@ -1,5 +1,5 @@ add_executable(mapnik-demo rundemo.cpp) -set_target_properties(mapnik-demo PROPERTIES +set_target_properties(mapnik-demo PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib" diff --git a/demo/viewer/CMakeLists.txt b/demo/viewer/CMakeLists.txt index b1e2355ae..2844b332f 100644 --- a/demo/viewer/CMakeLists.txt +++ b/demo/viewer/CMakeLists.txt @@ -14,7 +14,7 @@ set(PROJECT_SOURCES styles_model.cpp forms/about.ui forms/info.ui - forms/layer_info.ui + forms/layer_info.ui mapnik_viewer.qrc ) @@ -37,7 +37,7 @@ endif() set_target_properties(mapnik-viewer PROPERTIES AUTOUIC_SEARCH_PATHS forms - AUTORCC ON + AUTORCC ON AUTOUIC ON AUTOMOC ON LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" @@ -46,16 +46,17 @@ set_target_properties(mapnik-viewer PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>$<$:DLL>" ) -target_link_libraries(mapnik-viewer PRIVATE +target_link_libraries(mapnik-viewer PRIVATE Qt${QT_VERSION_MAJOR}::Widgets mapnik::agg mapnik::mapnik ) -file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/viewer.ini +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/viewer.ini "[mapnik] plugins_dir=${PLUGINS_INSTALL_DIR} -fonts/1/dir=${FONTS_INSTALL_DIR}" +fonts/1/dir=${FONTS_INSTALL_DIR} +fonts/size=1" ) if(QT_VERSION_MAJOR EQUAL 6) diff --git a/deps/agg/.clang-format b/deps/agg/.clang-format new file mode 100644 index 000000000..e3845288a --- /dev/null +++ b/deps/agg/.clang-format @@ -0,0 +1 @@ +DisableFormat: true diff --git a/deps/agg/CMakeLists.txt b/deps/agg/CMakeLists.txt index a91a55bde..a08410b91 100644 --- a/deps/agg/CMakeLists.txt +++ b/deps/agg/CMakeLists.txt @@ -3,8 +3,8 @@ project(agg) add_library(agg INTERFACE) add_library(mapnik::agg ALIAS agg) -target_include_directories(agg INTERFACE - $ +target_include_directories(agg INTERFACE + $ $ ) target_link_libraries(agg INTERFACE mapnik::core) diff --git a/deps/agg/include/agg_basics.h b/deps/agg/include/agg_basics.h index a617cf253..8a37c8c4e 100644 --- a/deps/agg/include/agg_basics.h +++ b/deps/agg/include/agg_basics.h @@ -365,7 +365,7 @@ namespace agg inline bool is_close(unsigned c) { return (c & ~(path_flags_cw | path_flags_ccw)) == - (path_cmd_end_poly | path_flags_close); + (path_cmd_end_poly | static_cast(path_flags_close)); } //------------------------------------------------------------is_next_poly diff --git a/deps/agg/include/agg_color_gray.h b/deps/agg/include/agg_color_gray.h index bf300b8f1..fbe4b560b 100644 --- a/deps/agg/include/agg_color_gray.h +++ b/deps/agg/include/agg_color_gray.h @@ -436,7 +436,8 @@ struct gray16 static value_type luminance(const rgba& c) { // Calculate grayscale value as per ITU-R BT.709. - return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask)); + return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) + * static_cast(base_mask))); } static value_type luminance(const rgba16& c) @@ -537,13 +538,13 @@ struct gray16 //-------------------------------------------------------------------- static AGG_INLINE double to_double(value_type a) { - return double(a) / base_mask; + return static_cast(a) / static_cast(base_mask); } //-------------------------------------------------------------------- static AGG_INLINE value_type from_double(double a) { - return value_type(uround(a * base_mask)); + return value_type(uround(a * static_cast(base_mask))); } //-------------------------------------------------------------------- @@ -698,7 +699,7 @@ struct gray16 self_type gradient(self_type c, double k) const { self_type ret; - calc_type ik = uround(k * base_scale); + calc_type ik = uround(k * static_cast(base_scale)); ret.v = lerp(v, c.v, ik); ret.a = lerp(a, c.a, ik); return ret; @@ -949,7 +950,7 @@ struct gray32 //-------------------------------------------------------------------- static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { - return value_type(a * b / cover_mask); + return value_type(a * b / static_cast(cover_mask)); } //-------------------------------------------------------------------- diff --git a/deps/agg/include/agg_color_rgba.h b/deps/agg/include/agg_color_rgba.h index b4e3f76d8..c9bb88e60 100644 --- a/deps/agg/include/agg_color_rgba.h +++ b/deps/agg/include/agg_color_rgba.h @@ -281,10 +281,10 @@ struct rgba8T static void convert(rgba8T& dst, const rgba& src) { - dst.r = value_type(uround(src.r * base_mask)); - dst.g = value_type(uround(src.g * base_mask)); - dst.b = value_type(uround(src.b * base_mask)); - dst.a = value_type(uround(src.a * base_mask)); + dst.r = value_type(uround(src.r * static_cast(base_mask))); + dst.g = value_type(uround(src.g * static_cast(base_mask))); + dst.b = value_type(uround(src.b * static_cast(base_mask))); + dst.a = value_type(uround(src.a * static_cast(base_mask))); } static void convert(rgba8T& dst, const rgba& src) @@ -761,13 +761,13 @@ struct rgba16 //-------------------------------------------------------------------- static AGG_INLINE double to_double(value_type a) { - return double(a) / base_mask; + return static_cast(a) / static_cast(base_mask); } //-------------------------------------------------------------------- static AGG_INLINE value_type from_double(double a) { - return value_type(uround(a * base_mask)); + return value_type(uround(a * static_cast(base_mask))); } //-------------------------------------------------------------------- @@ -955,7 +955,7 @@ struct rgba16 AGG_INLINE self_type gradient(const self_type& c, double k) const { self_type ret; - calc_type ik = uround(k * base_mask); + calc_type ik = uround(k * static_cast(base_mask)); ret.r = lerp(r, c.r, ik); ret.g = lerp(g, c.g, ik); ret.b = lerp(b, c.b, ik); @@ -1194,7 +1194,7 @@ struct rgba32 //-------------------------------------------------------------------- static AGG_INLINE value_type mult_cover(value_type a, cover_type b) { - return value_type(a * b / cover_mask); + return value_type(a * b / static_cast(cover_mask)); } //-------------------------------------------------------------------- diff --git a/deps/agg/include/agg_conv_adaptor_vpgen.h b/deps/agg/include/agg_conv_adaptor_vpgen.h index ae8d59320..b5c246a5b 100644 --- a/deps/agg/include/agg_conv_adaptor_vpgen.h +++ b/deps/agg/include/agg_conv_adaptor_vpgen.h @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // @@ -37,7 +37,7 @@ namespace agg private: conv_adaptor_vpgen(const conv_adaptor_vpgen&); - const conv_adaptor_vpgen& + const conv_adaptor_vpgen& operator = (const conv_adaptor_vpgen&); VertexSource* m_source; @@ -52,8 +52,8 @@ namespace agg //------------------------------------------------------------------------ template - void conv_adaptor_vpgen::rewind(unsigned path_id) - { + void conv_adaptor_vpgen::rewind(unsigned path_id) + { m_source->rewind(path_id); m_vpgen.reset(); m_start_x = 0; @@ -84,7 +84,7 @@ namespace agg if(m_vertices < 0) { - if(m_vertices < -1) + if(m_vertices < -1) { m_vertices = 0; return path_cmd_stop; @@ -98,12 +98,13 @@ namespace agg cmd = m_source->vertex(&tx, &ty); if(is_vertex(cmd)) { - if(is_move_to(cmd)) + if(is_move_to(cmd)) { if(m_vpgen.auto_close() && m_vertices > 2) { m_vpgen.line_to(m_start_x, m_start_y); - m_poly_flags = path_cmd_end_poly | path_flags_close; + m_poly_flags = path_cmd_end_poly + | static_cast(path_flags_close); m_start_x = tx; m_start_y = ty; m_vertices = -1; @@ -114,7 +115,7 @@ namespace agg m_start_y = ty; m_vertices = 1; } - else + else { m_vpgen.line_to(tx, ty); ++m_vertices; @@ -141,7 +142,8 @@ namespace agg if(m_vpgen.auto_close() && m_vertices > 2) { m_vpgen.line_to(m_start_x, m_start_y); - m_poly_flags = path_cmd_end_poly | path_flags_close; + m_poly_flags = path_cmd_end_poly + | static_cast(path_flags_close); m_vertices = -2; continue; } @@ -157,4 +159,3 @@ namespace agg #endif - diff --git a/deps/agg/include/agg_image_filters.h b/deps/agg/include/agg_image_filters.h index 2b84ddeb9..e5013f0e8 100644 --- a/deps/agg/include/agg_image_filters.h +++ b/deps/agg/include/agg_image_filters.h @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // @@ -22,24 +22,25 @@ #include "agg_array.h" #include "agg_math.h" +#include namespace agg { - // See Implementation agg_image_filters.cpp + // See Implementation agg_image_filters.cpp enum image_filter_scale_e { image_filter_shift = 14, //----image_filter_shift - image_filter_scale = 1 << image_filter_shift, //----image_filter_scale - image_filter_mask = image_filter_scale - 1 //----image_filter_mask + image_filter_scale = 1 << image_filter_shift, //----image_filter_scale + image_filter_mask = image_filter_scale - 1 //----image_filter_mask }; enum image_subpixel_scale_e { image_subpixel_shift = 8, //----image_subpixel_shift - image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale - image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask + image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale + image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask }; @@ -58,12 +59,13 @@ namespace agg { double x = double(i) / double(image_subpixel_scale); double y = filter.calc_weight(x); - m_weight_array[pivot + i] = - m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale); + m_weight_array[pivot + i] = + m_weight_array[pivot - i] = + static_cast(iround(y * static_cast(image_filter_scale))); } unsigned end = (diameter() << image_subpixel_shift) - 1; m_weight_array[0] = m_weight_array[end]; - if(normalization) + if(normalization) { normalize(); } @@ -71,7 +73,7 @@ namespace agg image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {} - template image_filter_lut(const FilterF& filter, + template image_filter_lut(const FilterF& filter, bool normalization=true) { calculate(filter, normalization); @@ -80,7 +82,7 @@ namespace agg double radius() const { return m_radius; } unsigned diameter() const { return m_diameter; } int start() const { return m_start; } - const int16* weight_array() const { return &m_weight_array[0]; } + std::int16_t const* weight_array() const { return &m_weight_array[0]; } void normalize(); private: @@ -91,7 +93,7 @@ namespace agg double m_radius; unsigned m_diameter; int m_start; - pod_array m_weight_array; + pod_array m_weight_array; }; @@ -150,7 +152,7 @@ namespace agg return (2.0 * x - 3.0) * x * x + 1.0; } }; - + //------------------------------------------------image_filter_quadric struct image_filter_quadric { @@ -177,7 +179,7 @@ namespace agg static double calc_weight(double x) { return - (1.0/6.0) * + (1.0/6.0) * (pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1)); } }; @@ -211,7 +213,7 @@ namespace agg sum = 1.; y = x * x / 4.; t = y; - + for(i = 2; t > epsilon; i++) { sum += t; @@ -298,7 +300,7 @@ namespace agg struct image_filter_gaussian { static double radius() { return 2.0; } - static double calc_weight(double x) + static double calc_weight(double x) { return exp(-2.0 * x * x) * sqrt(2.0 / pi); } @@ -308,7 +310,7 @@ namespace agg //------------------------------------------------image_filter_bessel struct image_filter_bessel { - static double radius() { return 3.2383; } + static double radius() { return 3.2383; } static double calc_weight(double x) { return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x); diff --git a/deps/agg/include/agg_line_aa_basics.h b/deps/agg/include/agg_line_aa_basics.h index d22711d8c..66dc8fe06 100644 --- a/deps/agg/include/agg_line_aa_basics.h +++ b/deps/agg/include/agg_line_aa_basics.h @@ -44,13 +44,13 @@ namespace agg //------------------------------------------------------------------line_mr AGG_INLINE int line_mr(int x) { - return x >> (line_subpixel_shift - line_mr_subpixel_shift); + return x >> (line_subpixel_shift - static_cast(line_mr_subpixel_shift)); } //-------------------------------------------------------------------line_hr AGG_INLINE int line_hr(int x) { - return x << (line_subpixel_shift - line_mr_subpixel_shift); + return x << (line_subpixel_shift - static_cast(line_mr_subpixel_shift)); } //---------------------------------------------------------------line_dbl_hr @@ -64,7 +64,7 @@ namespace agg { AGG_INLINE static int conv(double x) { - return iround(x * line_subpixel_scale); + return iround(x * static_cast(line_subpixel_scale)); } }; @@ -73,7 +73,7 @@ namespace agg { AGG_INLINE static int conv(double x) { - return saturation::iround(x * line_subpixel_scale); + return saturation::iround(x * static_cast(line_subpixel_scale)); } }; diff --git a/deps/agg/include/agg_path_storage.h b/deps/agg/include/agg_path_storage.h index 3be5aa86c..338fbd513 100644 --- a/deps/agg/include/agg_path_storage.h +++ b/deps/agg/include/agg_path_storage.h @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // @@ -92,7 +92,7 @@ namespace agg { pod_allocator::deallocate( *coord_blk, - block_size * 2 + + block_size * 2 + block_size / (sizeof(T) / sizeof(unsigned char))); --coord_blk; } @@ -137,7 +137,7 @@ namespace agg //------------------------------------------------------------------------ template - const vertex_block_storage& + const vertex_block_storage& vertex_block_storage::operator = (const vertex_block_storage& v) { remove_all(); @@ -160,7 +160,7 @@ namespace agg //------------------------------------------------------------------------ template - inline void vertex_block_storage::add_vertex(double x, double y, + inline void vertex_block_storage::add_vertex(double x, double y, unsigned cmd) { T* coord_ptr = 0; @@ -172,7 +172,7 @@ namespace agg //------------------------------------------------------------------------ template - inline void vertex_block_storage::modify_vertex(unsigned idx, + inline void vertex_block_storage::modify_vertex(unsigned idx, double x, double y) { T* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1); @@ -182,8 +182,8 @@ namespace agg //------------------------------------------------------------------------ template - inline void vertex_block_storage::modify_vertex(unsigned idx, - double x, double y, + inline void vertex_block_storage::modify_vertex(unsigned idx, + double x, double y, unsigned cmd) { unsigned block = idx >> block_shift; @@ -196,7 +196,7 @@ namespace agg //------------------------------------------------------------------------ template - inline void vertex_block_storage::modify_command(unsigned idx, + inline void vertex_block_storage::modify_command(unsigned idx, unsigned cmd) { m_cmd_blocks[idx >> block_shift][idx & block_mask] = (int8u)cmd; @@ -277,7 +277,7 @@ namespace agg //------------------------------------------------------------------------ template - inline unsigned vertex_block_storage::vertex(unsigned idx, + inline unsigned vertex_block_storage::vertex(unsigned idx, double* x, double* y) const { unsigned nb = idx >> block_shift; @@ -298,22 +298,22 @@ namespace agg template void vertex_block_storage::allocate_block(unsigned nb) { - if(nb >= m_max_blocks) + if(nb >= m_max_blocks) { - T** new_coords = + T** new_coords = pod_allocator::allocate((m_max_blocks + block_pool) * 2); - unsigned char** new_cmds = + unsigned char** new_cmds = (unsigned char**)(new_coords + m_max_blocks + block_pool); if(m_coord_blocks) { - memcpy(new_coords, - m_coord_blocks, + memcpy(new_coords, + m_coord_blocks, m_max_blocks * sizeof(T*)); - memcpy(new_cmds, - m_cmd_blocks, + memcpy(new_cmds, + m_cmd_blocks, m_max_blocks * sizeof(unsigned char*)); pod_allocator::deallocate(m_coord_blocks, m_max_blocks * 2); @@ -322,11 +322,11 @@ namespace agg m_cmd_blocks = new_cmds; m_max_blocks += block_pool; } - m_coord_blocks[nb] = - pod_allocator::allocate(block_size * 2 + + m_coord_blocks[nb] = + pod_allocator::allocate(block_size * 2 + block_size / (sizeof(T) / sizeof(unsigned char))); - m_cmd_blocks[nb] = + m_cmd_blocks[nb] = (unsigned char*)(m_coord_blocks[nb] + block_size * 2); m_total_blocks++; @@ -354,8 +354,8 @@ namespace agg public: typedef T value_type; - poly_plain_adaptor() : - m_data(0), + poly_plain_adaptor() : + m_data(0), m_ptr(0), m_end(0), m_closed(false), @@ -363,7 +363,7 @@ namespace agg {} poly_plain_adaptor(const T* data, unsigned num_points, bool closed) : - m_data(data), + m_data(data), m_ptr(data), m_end(data + num_points * 2), m_closed(closed), @@ -398,7 +398,8 @@ namespace agg if(m_closed && !m_stop) { m_stop = true; - return path_cmd_end_poly | path_flags_close; + return path_cmd_end_poly + | static_cast(path_flags_close); } return path_cmd_stop; } @@ -421,15 +422,15 @@ namespace agg public: typedef typename Container::value_type vertex_type; - poly_container_adaptor() : - m_container(0), + poly_container_adaptor() : + m_container(0), m_index(0), m_closed(false), m_stop(false) {} poly_container_adaptor(const Container& data, bool closed) : - m_container(&data), + m_container(&data), m_index(0), m_closed(closed), m_stop(false) @@ -463,7 +464,8 @@ namespace agg if(m_closed && !m_stop) { m_stop = true; - return path_cmd_end_poly | path_flags_close; + return path_cmd_end_poly + | static_cast(path_flags_close); } return path_cmd_stop; } @@ -483,15 +485,15 @@ namespace agg public: typedef typename Container::value_type vertex_type; - poly_container_reverse_adaptor() : - m_container(0), + poly_container_reverse_adaptor() : + m_container(0), m_index(-1), m_closed(false), m_stop(false) {} poly_container_reverse_adaptor(const Container& data, bool closed) : - m_container(&data), + m_container(&data), m_index(-1), m_closed(closed), m_stop(false) @@ -525,7 +527,8 @@ namespace agg if(m_closed && !m_stop) { m_stop = true; - return path_cmd_end_poly | path_flags_close; + return path_cmd_end_poly + | static_cast(path_flags_close); } return path_cmd_stop; } @@ -556,7 +559,7 @@ namespace agg m_coord[2] = x2; m_coord[3] = y2; } - + void init(double x1, double y1, double x2, double y2) { m_coord[0] = x1; @@ -594,10 +597,10 @@ namespace agg //---------------------------------------------------------------path_base - // A container to store vertices with their flags. - // A path consists of a number of contours separated with "move_to" + // A container to store vertices with their flags. + // A path consists of a number of contours separated with "move_to" // commands. The path storage can keep and maintain more than one - // path. + // path. // To navigate to the beginning of a particular path, use rewind(path_id); // Where path_id is what start_new_path() returns. So, when you call // start_new_path() you need to store its return value somewhere else @@ -644,28 +647,28 @@ namespace agg bool sweep_flag, double dx, double dy); - void curve3(double x_ctrl, double y_ctrl, + void curve3(double x_ctrl, double y_ctrl, double x_to, double y_to); - void curve3_rel(double dx_ctrl, double dy_ctrl, + void curve3_rel(double dx_ctrl, double dy_ctrl, double dx_to, double dy_to); void curve3(double x_to, double y_to); void curve3_rel(double dx_to, double dy_to); - void curve4(double x_ctrl1, double y_ctrl1, - double x_ctrl2, double y_ctrl2, + void curve4(double x_ctrl1, double y_ctrl1, + double x_ctrl2, double y_ctrl2, double x_to, double y_to); - void curve4_rel(double dx_ctrl1, double dy_ctrl1, - double dx_ctrl2, double dy_ctrl2, + void curve4_rel(double dx_ctrl1, double dy_ctrl1, + double dx_ctrl2, double dy_ctrl2, double dx_to, double dy_to); - void curve4(double x_ctrl2, double y_ctrl2, + void curve4(double x_ctrl2, double y_ctrl2, double x_to, double y_to); - void curve4_rel(double x_ctrl2, double y_ctrl2, + void curve4_rel(double x_ctrl2, double y_ctrl2, double x_to, double y_to); @@ -674,8 +677,8 @@ namespace agg // Accessors //-------------------------------------------------------------------- - const container_type& vertices() const { return m_vertices; } - container_type& vertices() { return m_vertices; } + const container_type& vertices() const { return m_vertices; } + container_type& vertices() { return m_vertices; } unsigned total_vertices() const; @@ -699,9 +702,9 @@ namespace agg void rewind(unsigned path_id); unsigned vertex(double* x, double* y); - // Arrange the orientation of a polygon, all polygons in a path, - // or in all paths. After calling arrange_orientations() or - // arrange_orientations_all_paths(), all the polygons will have + // Arrange the orientation of a polygon, all polygons in a path, + // or in all paths. After calling arrange_orientations() or + // arrange_orientations_all_paths(), all the polygons will have // the same orientation, i.e. path_flags_cw or path_flags_ccw //-------------------------------------------------------------------- unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation); @@ -709,7 +712,7 @@ namespace agg void arrange_orientations_all_paths(path_flags_e orientation); void invert_polygon(unsigned start); - // Flip all vertices horizontally or vertically, + // Flip all vertices horizontally or vertically, // between x1 and x2, or between y1 and y2 respectively //-------------------------------------------------------------------- void flip_x(double x1, double x2); @@ -717,7 +720,7 @@ namespace agg // Concatenate path. The path is added as is. //-------------------------------------------------------------------- - template + template void concat_path(VertexSource& vs, unsigned path_id = 0) { double x=0; @@ -731,9 +734,9 @@ namespace agg } //-------------------------------------------------------------------- - // Join path. The path is joined with the existing one, that is, + // Join path. The path is joined with the existing one, that is, // it behaves as if the pen of a plotter was always down (drawing) - template + template void join_path(VertexSource& vs, unsigned path_id = 0) { double x=0.0, y=0.0; @@ -769,16 +772,16 @@ namespace agg } while(!is_stop(cmd = vs.vertex(&x, &y))) { - m_vertices.add_vertex(x, y, is_move_to(cmd) ? - unsigned(path_cmd_line_to) : + m_vertices.add_vertex(x, y, is_move_to(cmd) ? + unsigned(path_cmd_line_to) : cmd); } } } - // Concatenate polygon/polyline. + // Concatenate polygon/polyline. //-------------------------------------------------------------------- - template void concat_poly(const T* data, + template void concat_poly(const T* data, unsigned num_points, bool closed) { @@ -788,7 +791,7 @@ namespace agg // Join polygon/polyline continuously. //-------------------------------------------------------------------- - template void join_poly(const T* data, + template void join_poly(const T* data, unsigned num_points, bool closed) { @@ -846,7 +849,7 @@ namespace agg }; //------------------------------------------------------------------------ - template + template unsigned path_base::start_new_path() { if(!is_stop(m_vertices.last_command())) @@ -858,7 +861,7 @@ namespace agg //------------------------------------------------------------------------ - template + template inline void path_base::rel_to_abs(double* x, double* y) const { if(m_vertices.total_vertices()) @@ -870,7 +873,7 @@ namespace agg *x += x2; *y += y2; } - else if (!is_stop(m_vertices.last_command()) && + else if (!is_stop(m_vertices.last_command()) && is_vertex(m_vertices.prev_vertex(&x2, &y2))) { *x += x2; @@ -880,14 +883,14 @@ namespace agg } //------------------------------------------------------------------------ - template + template inline void path_base::move_to(double x, double y) { m_vertices.add_vertex(x, y, path_cmd_move_to); } //------------------------------------------------------------------------ - template + template inline void path_base::move_rel(double dx, double dy) { rel_to_abs(&dx, &dy); @@ -895,14 +898,14 @@ namespace agg } //------------------------------------------------------------------------ - template + template inline void path_base::line_to(double x, double y) { m_vertices.add_vertex(x, y, path_cmd_line_to); } //------------------------------------------------------------------------ - template + template inline void path_base::line_rel(double dx, double dy) { rel_to_abs(&dx, &dy); @@ -910,14 +913,14 @@ namespace agg } //------------------------------------------------------------------------ - template + template inline void path_base::hline_to(double x) { m_vertices.add_vertex(x, last_y(), path_cmd_line_to); } //------------------------------------------------------------------------ - template + template inline void path_base::hline_rel(double dx) { double dy = 0; @@ -926,14 +929,14 @@ namespace agg } //------------------------------------------------------------------------ - template + template inline void path_base::vline_to(double y) { m_vertices.add_vertex(last_x(), y, path_cmd_line_to); } //------------------------------------------------------------------------ - template + template inline void path_base::vline_rel(double dy) { double dx = 0; @@ -942,7 +945,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::arc_to(double rx, double ry, double angle, bool large_arc_flag, @@ -961,7 +964,7 @@ namespace agg // Ensure radii are valid //------------------------- - if(rx < epsilon || ry < epsilon) + if(rx < epsilon || ry < epsilon) { line_to(x, y); return; @@ -990,7 +993,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::arc_rel(double rx, double ry, double angle, bool large_arc_flag, @@ -1002,8 +1005,8 @@ namespace agg } //------------------------------------------------------------------------ - template - void path_base::curve3(double x_ctrl, double y_ctrl, + template + void path_base::curve3(double x_ctrl, double y_ctrl, double x_to, double y_to) { m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3); @@ -1011,8 +1014,8 @@ namespace agg } //------------------------------------------------------------------------ - template - void path_base::curve3_rel(double dx_ctrl, double dy_ctrl, + template + void path_base::curve3_rel(double dx_ctrl, double dy_ctrl, double dx_to, double dy_to) { rel_to_abs(&dx_ctrl, &dy_ctrl); @@ -1022,7 +1025,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::curve3(double x_to, double y_to) { double x0; @@ -1030,7 +1033,7 @@ namespace agg if(is_vertex(m_vertices.last_vertex(&x0, &y0))) { double x_ctrl; - double y_ctrl; + double y_ctrl; unsigned cmd = m_vertices.prev_vertex(&x_ctrl, &y_ctrl); if(is_curve(cmd)) { @@ -1047,7 +1050,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::curve3_rel(double dx_to, double dy_to) { rel_to_abs(&dx_to, &dy_to); @@ -1055,9 +1058,9 @@ namespace agg } //------------------------------------------------------------------------ - template - void path_base::curve4(double x_ctrl1, double y_ctrl1, - double x_ctrl2, double y_ctrl2, + template + void path_base::curve4(double x_ctrl1, double y_ctrl1, + double x_ctrl2, double y_ctrl2, double x_to, double y_to) { m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4); @@ -1066,9 +1069,9 @@ namespace agg } //------------------------------------------------------------------------ - template - void path_base::curve4_rel(double dx_ctrl1, double dy_ctrl1, - double dx_ctrl2, double dy_ctrl2, + template + void path_base::curve4_rel(double dx_ctrl1, double dy_ctrl1, + double dx_ctrl2, double dy_ctrl2, double dx_to, double dy_to) { rel_to_abs(&dx_ctrl1, &dy_ctrl1); @@ -1080,8 +1083,8 @@ namespace agg } //------------------------------------------------------------------------ - template - void path_base::curve4(double x_ctrl2, double y_ctrl2, + template + void path_base::curve4(double x_ctrl2, double y_ctrl2, double x_to, double y_to) { double x0; @@ -1089,7 +1092,7 @@ namespace agg if(is_vertex(last_vertex(&x0, &y0))) { double x_ctrl1; - double y_ctrl1; + double y_ctrl1; unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1); if(is_curve(cmd)) { @@ -1106,8 +1109,8 @@ namespace agg } //------------------------------------------------------------------------ - template - void path_base::curve4_rel(double dx_ctrl2, double dy_ctrl2, + template + void path_base::curve4_rel(double dx_ctrl2, double dy_ctrl2, double dx_to, double dy_to) { rel_to_abs(&dx_ctrl2, &dy_ctrl2); @@ -1116,7 +1119,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template inline void path_base::end_poly(unsigned flags) { if(is_vertex(m_vertices.last_command())) @@ -1126,91 +1129,91 @@ namespace agg } //------------------------------------------------------------------------ - template + template inline void path_base::close_polygon(unsigned flags) { end_poly(path_flags_close | flags); } //------------------------------------------------------------------------ - template + template inline unsigned path_base::total_vertices() const { return m_vertices.total_vertices(); } //------------------------------------------------------------------------ - template + template inline unsigned path_base::last_vertex(double* x, double* y) const { return m_vertices.last_vertex(x, y); } //------------------------------------------------------------------------ - template + template inline unsigned path_base::prev_vertex(double* x, double* y) const { return m_vertices.prev_vertex(x, y); } //------------------------------------------------------------------------ - template + template inline double path_base::last_x() const { return m_vertices.last_x(); } //------------------------------------------------------------------------ - template + template inline double path_base::last_y() const { return m_vertices.last_y(); } //------------------------------------------------------------------------ - template + template inline unsigned path_base::vertex(unsigned idx, double* x, double* y) const { return m_vertices.vertex(idx, x, y); } - + //------------------------------------------------------------------------ - template + template inline unsigned path_base::command(unsigned idx) const { return m_vertices.command(idx); } //------------------------------------------------------------------------ - template + template void path_base::modify_vertex(unsigned idx, double x, double y) { m_vertices.modify_vertex(idx, x, y); } //------------------------------------------------------------------------ - template + template void path_base::modify_vertex(unsigned idx, double x, double y, unsigned cmd) { m_vertices.modify_vertex(idx, x, y, cmd); } //------------------------------------------------------------------------ - template + template void path_base::modify_command(unsigned idx, unsigned cmd) { m_vertices.modify_command(idx, cmd); } //------------------------------------------------------------------------ - template + template inline void path_base::rewind(unsigned path_id) { m_iterator = path_id; } //------------------------------------------------------------------------ - template + template inline unsigned path_base::vertex(double* x, double* y) { if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop; @@ -1218,7 +1221,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template unsigned path_base::perceive_polygon_orientation(unsigned start, unsigned end) { @@ -1238,12 +1241,12 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::invert_polygon(unsigned start, unsigned end) { unsigned i; unsigned tmp_cmd = m_vertices.command(start); - + --end; // Make "end" inclusive // Shift all commands to one position @@ -1263,45 +1266,45 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::invert_polygon(unsigned start) { // Skip all non-vertices at the beginning - while(start < m_vertices.total_vertices() && + while(start < m_vertices.total_vertices() && !is_vertex(m_vertices.command(start))) ++start; // Skip all insignificant move_to - while(start+1 < m_vertices.total_vertices() && + while(start+1 < m_vertices.total_vertices() && is_move_to(m_vertices.command(start)) && is_move_to(m_vertices.command(start+1))) ++start; // Find the last vertex unsigned end = start + 1; - while(end < m_vertices.total_vertices() && + while(end < m_vertices.total_vertices() && !is_next_poly(m_vertices.command(end))) ++end; invert_polygon(start, end); } //------------------------------------------------------------------------ - template - unsigned path_base::arrange_polygon_orientation(unsigned start, + template + unsigned path_base::arrange_polygon_orientation(unsigned start, path_flags_e orientation) { if(orientation == path_flags_none) return start; - + // Skip all non-vertices at the beginning - while(start < m_vertices.total_vertices() && + while(start < m_vertices.total_vertices() && !is_vertex(m_vertices.command(start))) ++start; // Skip all insignificant move_to - while(start+1 < m_vertices.total_vertices() && + while(start+1 < m_vertices.total_vertices() && is_move_to(m_vertices.command(start)) && is_move_to(m_vertices.command(start+1))) ++start; // Find the last vertex unsigned end = start + 1; - while(end < m_vertices.total_vertices() && + while(end < m_vertices.total_vertices() && !is_next_poly(m_vertices.command(end))) ++end; if(end - start > 2) @@ -1311,7 +1314,7 @@ namespace agg // Invert polygon, set orientation flag, and skip all end_poly invert_polygon(start, end); unsigned cmd; - while(end < m_vertices.total_vertices() && + while(end < m_vertices.total_vertices() && is_end_poly(cmd = m_vertices.command(end))) { m_vertices.modify_command(end++, set_orientation(cmd, orientation)); @@ -1322,8 +1325,8 @@ namespace agg } //------------------------------------------------------------------------ - template - unsigned path_base::arrange_orientations(unsigned start, + template + unsigned path_base::arrange_orientations(unsigned start, path_flags_e orientation) { if(orientation != path_flags_none) @@ -1342,7 +1345,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::arrange_orientations_all_paths(path_flags_e orientation) { if(orientation != path_flags_none) @@ -1356,7 +1359,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::flip_x(double x1, double x2) { unsigned i; @@ -1372,7 +1375,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::flip_y(double y1, double y2) { unsigned i; @@ -1388,7 +1391,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::translate(double dx, double dy, unsigned path_id) { unsigned num_ver = m_vertices.total_vertices(); @@ -1407,7 +1410,7 @@ namespace agg } //------------------------------------------------------------------------ - template + template void path_base::translate_all_paths(double dx, double dy) { unsigned idx; @@ -1440,8 +1443,8 @@ namespace agg void add_vertex(double x, double y, unsigned cmd) { - m_vertices.push_back(vertex_type(value_type(x), - value_type(y), + m_vertices.push_back(vertex_type(value_type(x), + value_type(y), int8u(cmd))); } @@ -1474,8 +1477,8 @@ namespace agg unsigned last_command() const { - return m_vertices.size() ? - m_vertices[m_vertices.size() - 1].cmd : + return m_vertices.size() ? + m_vertices[m_vertices.size() - 1].cmd : path_cmd_stop; } @@ -1545,11 +1548,11 @@ namespace agg // Example of declarations path_storage with std::vector as a container //--------------------------------------------------------------------------- -//#include -//namespace agg -//{ -// typedef path_base > > path_storage; -//} +//#include +//namespace agg +//{ +// typedef path_base > > path_storage; +//} #endif diff --git a/deps/agg/include/agg_pixfmt_base.h b/deps/agg/include/agg_pixfmt_base.h index 57ae19cfe..b3e98ad1a 100644 --- a/deps/agg/include/agg_pixfmt_base.h +++ b/deps/agg/include/agg_pixfmt_base.h @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // @@ -35,7 +35,7 @@ namespace agg }; //--------------------------------------------------------------blender_base - template + template struct blender_base { typedef ColorT color_type; @@ -47,14 +47,14 @@ namespace agg if (cover > cover_none) { rgba c( - color_type::to_double(r), - color_type::to_double(g), - color_type::to_double(b), + color_type::to_double(r), + color_type::to_double(g), + color_type::to_double(b), color_type::to_double(a)); if (cover < cover_full) { - double x = double(cover) / cover_full; + double x = static_cast(cover) / static_cast(cover_full); c.r *= x; c.g *= x; c.b *= x; @@ -69,10 +69,10 @@ namespace agg static rgba get(const value_type* p, cover_type cover = cover_full) { return get( - p[order_type::R], - p[order_type::G], - p[order_type::B], - p[order_type::A], + p[order_type::R], + p[order_type::G], + p[order_type::B], + p[order_type::A], cover); } diff --git a/deps/agg/include/agg_rasterizer_sl_clip.h b/deps/agg/include/agg_rasterizer_sl_clip.h index a3c5867fb..64a0a468b 100644 --- a/deps/agg/include/agg_rasterizer_sl_clip.h +++ b/deps/agg/include/agg_rasterizer_sl_clip.h @@ -2,8 +2,8 @@ // Anti-Grain Geometry - Version 2.4 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) // -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. // This software is provided "as is" without express or implied // warranty, and with no claim as to its suitability for any purpose. // @@ -24,7 +24,7 @@ namespace agg { poly_max_coord = (1 << 30) - 1 //----poly_max_coord }; - + //------------------------------------------------------------ras_conv_int struct ras_conv_int { @@ -35,7 +35,7 @@ namespace agg } static int xi(int v) { return v; } static int yi(int v) { return v; } - static int upscale(double v) { return iround(v * poly_subpixel_scale); } + static int upscale(double v) { return iround(v * static_cast(poly_subpixel_scale)); } static int downscale(int v) { return v; } }; @@ -49,9 +49,9 @@ namespace agg } static int xi(int v) { return v; } static int yi(int v) { return v; } - static int upscale(double v) - { - return saturation::iround(v * poly_subpixel_scale); + static int upscale(double v) + { + return saturation::iround(v * static_cast(poly_subpixel_scale)); } static int downscale(int v) { return v; } }; @@ -66,7 +66,7 @@ namespace agg } static int xi(int v) { return v * 3; } static int yi(int v) { return v; } - static int upscale(double v) { return iround(v * poly_subpixel_scale); } + static int upscale(double v) { return iround(v * static_cast(poly_subpixel_scale)); } static int downscale(int v) { return v; } }; @@ -78,10 +78,10 @@ namespace agg { return a * b / c; } - static int xi(double v) { return iround(v * poly_subpixel_scale); } - static int yi(double v) { return iround(v * poly_subpixel_scale); } + static int xi(double v) { return iround(v * static_cast(poly_subpixel_scale)); } + static int yi(double v) { return iround(v * static_cast(poly_subpixel_scale)); } static double upscale(double v) { return v; } - static double downscale(int v) { return v / double(poly_subpixel_scale); } + static double downscale(int v) { return v / static_cast(poly_subpixel_scale); } }; //--------------------------------------------------------ras_conv_dbl_3x @@ -92,10 +92,10 @@ namespace agg { return a * b / c; } - static int xi(double v) { return iround(v * poly_subpixel_scale * 3); } - static int yi(double v) { return iround(v * poly_subpixel_scale); } + static int xi(double v) { return iround(v * static_cast(poly_subpixel_scale) * 3); } + static int yi(double v) { return iround(v * static_cast(poly_subpixel_scale)); } static double upscale(double v) { return v; } - static double downscale(int v) { return v / double(poly_subpixel_scale); } + static double downscale(int v) { return v / static_cast(poly_subpixel_scale); } }; @@ -111,12 +111,12 @@ namespace agg typedef rect_base rect_type; //-------------------------------------------------------------------- - rasterizer_sl_clip() : + rasterizer_sl_clip() : m_clip_box(0,0,0,0), m_x1(0), m_y1(0), m_f1(0), - m_clipping(false) + m_clipping(false) {} //-------------------------------------------------------------------- @@ -145,8 +145,8 @@ namespace agg //------------------------------------------------------------------------ template AGG_INLINE void line_clip_y(Rasterizer& ras, - coord_type x1, coord_type y1, - coord_type x2, coord_type y2, + coord_type x1, coord_type y1, + coord_type x2, coord_type y2, unsigned f1, unsigned f2) const { f1 &= 10; @@ -154,7 +154,7 @@ namespace agg if((f1 | f2) == 0) { // Fully visible - ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2)); + ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2)); } else { @@ -192,8 +192,8 @@ namespace agg tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1); ty2 = m_clip_box.y2; } - ras.line(Conv::xi(tx1), Conv::yi(ty1), - Conv::xi(tx2), Conv::yi(ty2)); + ras.line(Conv::xi(tx1), Conv::yi(ty1), + Conv::xi(tx2), Conv::yi(ty2)); } } @@ -288,8 +288,8 @@ namespace agg } else { - ras.line(Conv::xi(m_x1), Conv::yi(m_y1), - Conv::xi(x2), Conv::yi(y2)); + ras.line(Conv::xi(m_x1), Conv::yi(m_y1), + Conv::xi(x2), Conv::yi(y2)); } m_x1 = x2; m_y1 = y2; @@ -321,10 +321,10 @@ namespace agg void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; } template - void line_to(Rasterizer& ras, coord_type x2, coord_type y2) - { - ras.line(m_x1, m_y1, x2, y2); - m_x1 = x2; + void line_to(Rasterizer& ras, coord_type x2, coord_type y2) + { + ras.line(m_x1, m_y1, x2, y2); + m_x1 = x2; m_y1 = y2; } diff --git a/deps/agg/include/agg_renderer_outline_aa.h b/deps/agg/include/agg_renderer_outline_aa.h index b2d3dd42b..6af6d5720 100644 --- a/deps/agg/include/agg_renderer_outline_aa.h +++ b/deps/agg/include/agg_renderer_outline_aa.h @@ -1305,7 +1305,7 @@ namespace agg for(i = 0; i < aa_scale; i++) { m_gamma[i] = value_type( - uround(gamma_function(double(i) / aa_mask) * aa_mask)); + uround(gamma_function(static_cast(i) / static_cast(aa_mask)) * aa_mask)); } } diff --git a/deps/agg/src/agg_arrowhead.cpp b/deps/agg/src/agg_arrowhead.cpp index bbcfbba71..44c284cf2 100644 --- a/deps/agg/src/agg_arrowhead.cpp +++ b/deps/agg/src/agg_arrowhead.cpp @@ -66,7 +66,9 @@ void arrowhead::rewind(unsigned path_id) m_cmd[3] = path_cmd_line_to; m_cmd[4] = path_cmd_line_to; m_cmd[5] = path_cmd_line_to; - m_cmd[7] = path_cmd_end_poly | path_flags_close | path_flags_ccw; + m_cmd[7] = path_cmd_end_poly + | static_cast(path_flags_close) + | static_cast(path_flags_ccw); m_cmd[6] = path_cmd_stop; return; } @@ -87,7 +89,9 @@ void arrowhead::rewind(unsigned path_id) m_cmd[1] = path_cmd_line_to; m_cmd[2] = path_cmd_line_to; m_cmd[3] = path_cmd_line_to; - m_cmd[4] = path_cmd_end_poly | path_flags_close | path_flags_ccw; + m_cmd[4] = path_cmd_end_poly + | static_cast(path_flags_close) + | static_cast(path_flags_ccw); m_cmd[5] = path_cmd_stop; return; } diff --git a/deps/agg/src/agg_line_profile_aa.cpp b/deps/agg/src/agg_line_profile_aa.cpp index cb4ceb7cd..543fb6951 100644 --- a/deps/agg/src/agg_line_profile_aa.cpp +++ b/deps/agg/src/agg_line_profile_aa.cpp @@ -42,7 +42,7 @@ void line_profile_aa::width(double w) //--------------------------------------------------------------------- line_profile_aa::value_type* line_profile_aa::profile(double w) { - m_subpixel_width = uround(w * subpixel_scale); + m_subpixel_width = uround(w * static_cast(subpixel_scale)); unsigned size = m_subpixel_width + subpixel_scale * 6; if(size > m_profile.size()) { @@ -56,8 +56,8 @@ line_profile_aa::value_type* line_profile_aa::profile(double w) void line_profile_aa::set(double center_width, double smoother_width) { double base_val = 1.0; - if(center_width == 0.0) center_width = 1.0 / subpixel_scale; - if(smoother_width == 0.0) smoother_width = 1.0 / subpixel_scale; + if(center_width == 0.0) center_width = 1.0 / static_cast(subpixel_scale); + if(smoother_width == 0.0) smoother_width = 1.0 / static_cast(subpixel_scale); double width = center_width + smoother_width; if(width < m_min_width) @@ -70,15 +70,15 @@ void line_profile_aa::set(double center_width, double smoother_width) value_type* ch = profile(center_width + smoother_width); - unsigned subpixel_center_width = unsigned(center_width * subpixel_scale); - unsigned subpixel_smoother_width = unsigned(smoother_width * subpixel_scale); + unsigned subpixel_center_width = unsigned(center_width * static_cast(subpixel_scale)); + unsigned subpixel_smoother_width = unsigned(smoother_width * static_cast(subpixel_scale)); - value_type* ch_center = ch + subpixel_scale*2; + value_type* ch_center = ch + subpixel_scale * 2; value_type* ch_smoother = ch_center + subpixel_center_width; unsigned i; - unsigned val = m_gamma[unsigned(base_val * aa_mask)]; + unsigned val = m_gamma[unsigned(base_val * static_cast(aa_mask))]; ch = ch_center; for(i = 0; i < subpixel_center_width; i++) { @@ -90,7 +90,7 @@ void line_profile_aa::set(double center_width, double smoother_width) *ch_smoother++ = m_gamma[unsigned((base_val - base_val * - (double(i) / subpixel_smoother_width)) * aa_mask)]; + (double(i) / subpixel_smoother_width)) * static_cast(aa_mask))]; } unsigned n_smoother = profile_size() - @@ -113,4 +113,3 @@ void line_profile_aa::set(double center_width, double smoother_width) } - diff --git a/deps/agg/src/agg_rounded_rect.cpp b/deps/agg/src/agg_rounded_rect.cpp index 6307d60d9..17c1852f4 100644 --- a/deps/agg/src/agg_rounded_rect.cpp +++ b/deps/agg/src/agg_rounded_rect.cpp @@ -152,7 +152,9 @@ unsigned rounded_rect::vertex(double* x, double* y) else return path_cmd_line_to; case 8: - cmd = path_cmd_end_poly | path_flags_close | path_flags_ccw; + cmd = path_cmd_end_poly + | static_cast(path_flags_close) + | static_cast(path_flags_ccw); m_status++; break; } @@ -161,4 +163,3 @@ unsigned rounded_rect::vertex(double* x, double* y) } - diff --git a/deps/agg/src/agg_vcgen_contour.cpp b/deps/agg/src/agg_vcgen_contour.cpp index cb3829e6e..398dc755b 100644 --- a/deps/agg/src/agg_vcgen_contour.cpp +++ b/deps/agg/src/agg_vcgen_contour.cpp @@ -153,7 +153,9 @@ unsigned vcgen_contour::vertex(double* x, double* y) case end_poly: if(!m_closed) return path_cmd_stop; m_status = stop; - return path_cmd_end_poly | path_flags_close | path_flags_ccw; + return path_cmd_end_poly + | static_cast(path_flags_close) + | static_cast(path_flags_ccw); case stop: return path_cmd_stop; diff --git a/deps/agg/src/agg_vcgen_stroke.cpp b/deps/agg/src/agg_vcgen_stroke.cpp index 3ee336f03..ac0bd6d01 100644 --- a/deps/agg/src/agg_vcgen_stroke.cpp +++ b/deps/agg/src/agg_vcgen_stroke.cpp @@ -196,11 +196,15 @@ unsigned vcgen_stroke::vertex(double* x, double* y) case end_poly1: m_status = m_prev_status; - return path_cmd_end_poly | path_flags_close | path_flags_ccw; + return path_cmd_end_poly + | static_cast(path_flags_close) + | static_cast(path_flags_ccw); case end_poly2: m_status = m_prev_status; - return path_cmd_end_poly | path_flags_close | path_flags_cw; + return path_cmd_end_poly + | static_cast(path_flags_close) + | static_cast(path_flags_cw); case stop: cmd = path_cmd_stop; diff --git a/deps/boost/.clang-format b/deps/boost/.clang-format new file mode 100644 index 000000000..e3845288a --- /dev/null +++ b/deps/boost/.clang-format @@ -0,0 +1 @@ +DisableFormat: true diff --git a/deps/mapbox/.clang-format b/deps/mapbox/.clang-format new file mode 100644 index 000000000..e3845288a --- /dev/null +++ b/deps/mapbox/.clang-format @@ -0,0 +1 @@ +DisableFormat: true diff --git a/deps/mapnik/sparsehash/internal/densehashtable.h b/deps/mapnik/sparsehash/internal/densehashtable.h index c0a2fedca..608a43f47 100644 --- a/deps/mapnik/sparsehash/internal/densehashtable.h +++ b/deps/mapnik/sparsehash/internal/densehashtable.h @@ -91,32 +91,32 @@ #include #include -#include // for FILE, fwrite, fread -#include // For swap(), eg -#include // For iterator tags -#include // for numeric_limits -#include // For uninitialized_fill -#include // for pair +#include // for FILE, fwrite, fread +#include // For swap(), eg +#include // For iterator tags +#include // for numeric_limits +#include // For uninitialized_fill +#include // for pair #include #include #include -#include // For length_error +#include // For length_error _START_GOOGLE_NAMESPACE_ -namespace base { // just to make google->opensource transition easier -using GOOGLE_NAMESPACE::true_type; +namespace base { // just to make google->opensource transition easier using GOOGLE_NAMESPACE::false_type; using GOOGLE_NAMESPACE::integral_constant; using GOOGLE_NAMESPACE::is_same; using GOOGLE_NAMESPACE::remove_const; -} +using GOOGLE_NAMESPACE::true_type; +} // namespace base // The probing method // Linear probing // #define JUMP_(key, num_probes) ( 1 ) // Quadratic probing -#define JUMP_(key, num_probes) ( num_probes ) +#define JUMP_(key, num_probes) (num_probes) // Hashtable class, used to implement the hashed associative containers // hash_set and hash_map. @@ -135,1168 +135,1299 @@ using GOOGLE_NAMESPACE::remove_const; // if they are both associated with the same Value). // Alloc: STL allocator to use to allocate memory. -template +template class dense_hashtable; -template +template struct dense_hashtable_iterator; -template +template struct dense_hashtable_const_iterator; // We're just an array, but we need to skip over empty and deleted elements -template -struct dense_hashtable_iterator { - private: - typedef typename A::template rebind::other value_alloc_type; +template +struct dense_hashtable_iterator +{ + private: + typedef typename A::template rebind::other value_alloc_type; - public: - typedef dense_hashtable_iterator iterator; - typedef dense_hashtable_const_iterator const_iterator; + public: + typedef dense_hashtable_iterator iterator; + typedef dense_hashtable_const_iterator const_iterator; - typedef std::forward_iterator_tag iterator_category; // very little defined! - typedef V value_type; - typedef typename value_alloc_type::difference_type difference_type; - typedef typename value_alloc_type::size_type size_type; - typedef typename value_alloc_type::reference reference; - typedef typename value_alloc_type::pointer pointer; + typedef std::forward_iterator_tag iterator_category; // very little defined! + typedef V value_type; + typedef typename value_alloc_type::difference_type difference_type; + typedef typename value_alloc_type::size_type size_type; + typedef typename value_alloc_type::reference reference; + typedef typename value_alloc_type::pointer pointer; - // "Real" constructor and default constructor - dense_hashtable_iterator(const dense_hashtable *h, - pointer it, pointer it_end, bool advance) - : ht(h), pos(it), end(it_end) { - if (advance) advance_past_empty_and_deleted(); - } - dense_hashtable_iterator() { } - // The default destructor is fine; we don't define one - // The default operator= is fine; we don't define one + // "Real" constructor and default constructor + dense_hashtable_iterator(const dense_hashtable* h, + pointer it, + pointer it_end, + bool advance) + : ht(h) + , pos(it) + , end(it_end) + { + if (advance) + advance_past_empty_and_deleted(); + } + dense_hashtable_iterator() {} + // The default destructor is fine; we don't define one + // The default operator= is fine; we don't define one - // Happy dereferencer - reference operator*() const { return *pos; } - pointer operator->() const { return &(operator*()); } + // Happy dereferencer + reference operator*() const { return *pos; } + pointer operator->() const { return &(operator*()); } - // Arithmetic. The only hard part is making sure that - // we're not on an empty or marked-deleted array element - void advance_past_empty_and_deleted() { - while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this)) ) - ++pos; - } - iterator& operator++() { - assert(pos != end); ++pos; advance_past_empty_and_deleted(); return *this; - } - iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; } + // Arithmetic. The only hard part is making sure that + // we're not on an empty or marked-deleted array element + void advance_past_empty_and_deleted() + { + while (pos != end && (ht->test_empty(*this) || ht->test_deleted(*this))) + ++pos; + } + iterator& operator++() + { + assert(pos != end); + ++pos; + advance_past_empty_and_deleted(); + return *this; + } + iterator operator++(int) + { + iterator tmp(*this); + ++*this; + return tmp; + } - // Comparison. - bool operator==(const iterator& it) const { return pos == it.pos; } - bool operator!=(const iterator& it) const { return pos != it.pos; } + // Comparison. + bool operator==(const iterator& it) const { return pos == it.pos; } + bool operator!=(const iterator& it) const { return pos != it.pos; } - - // The actual data - const dense_hashtable *ht; - pointer pos, end; + // The actual data + const dense_hashtable* ht; + pointer pos, end; }; - // Now do it all again, but with const-ness! -template -struct dense_hashtable_const_iterator { - private: - typedef typename A::template rebind::other value_alloc_type; +template +struct dense_hashtable_const_iterator +{ + private: + typedef typename A::template rebind::other value_alloc_type; - public: - typedef dense_hashtable_iterator iterator; - typedef dense_hashtable_const_iterator const_iterator; + public: + typedef dense_hashtable_iterator iterator; + typedef dense_hashtable_const_iterator const_iterator; - typedef std::forward_iterator_tag iterator_category; // very little defined! - typedef V value_type; - typedef typename value_alloc_type::difference_type difference_type; - typedef typename value_alloc_type::size_type size_type; - typedef typename value_alloc_type::const_reference reference; - typedef typename value_alloc_type::const_pointer pointer; + typedef std::forward_iterator_tag iterator_category; // very little defined! + typedef V value_type; + typedef typename value_alloc_type::difference_type difference_type; + typedef typename value_alloc_type::size_type size_type; + typedef typename value_alloc_type::const_reference reference; + typedef typename value_alloc_type::const_pointer pointer; - // "Real" constructor and default constructor - dense_hashtable_const_iterator( - const dense_hashtable *h, - pointer it, pointer it_end, bool advance) - : ht(h), pos(it), end(it_end) { - if (advance) advance_past_empty_and_deleted(); - } - dense_hashtable_const_iterator() - : ht(NULL), pos(pointer()), end(pointer()) { } - // This lets us convert regular iterators to const iterators - dense_hashtable_const_iterator(const iterator &it) - : ht(it.ht), pos(it.pos), end(it.end) { } - // The default destructor is fine; we don't define one - // The default operator= is fine; we don't define one + // "Real" constructor and default constructor + dense_hashtable_const_iterator(const dense_hashtable* h, + pointer it, + pointer it_end, + bool advance) + : ht(h) + , pos(it) + , end(it_end) + { + if (advance) + advance_past_empty_and_deleted(); + } + dense_hashtable_const_iterator() + : ht(NULL) + , pos(pointer()) + , end(pointer()) + {} + // This lets us convert regular iterators to const iterators + dense_hashtable_const_iterator(const iterator& it) + : ht(it.ht) + , pos(it.pos) + , end(it.end) + {} + // The default destructor is fine; we don't define one + // The default operator= is fine; we don't define one - // Happy dereferencer - reference operator*() const { return *pos; } - pointer operator->() const { return &(operator*()); } + // Happy dereferencer + reference operator*() const { return *pos; } + pointer operator->() const { return &(operator*()); } - // Arithmetic. The only hard part is making sure that - // we're not on an empty or marked-deleted array element - void advance_past_empty_and_deleted() { - while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this)) ) - ++pos; - } - const_iterator& operator++() { - assert(pos != end); ++pos; advance_past_empty_and_deleted(); return *this; - } - const_iterator operator++(int) { const_iterator tmp(*this); ++*this; return tmp; } + // Arithmetic. The only hard part is making sure that + // we're not on an empty or marked-deleted array element + void advance_past_empty_and_deleted() + { + while (pos != end && (ht->test_empty(*this) || ht->test_deleted(*this))) + ++pos; + } + const_iterator& operator++() + { + assert(pos != end); + ++pos; + advance_past_empty_and_deleted(); + return *this; + } + const_iterator operator++(int) + { + const_iterator tmp(*this); + ++*this; + return tmp; + } - // Comparison. - bool operator==(const const_iterator& it) const { return pos == it.pos; } - bool operator!=(const const_iterator& it) const { return pos != it.pos; } + // Comparison. + bool operator==(const const_iterator& it) const { return pos == it.pos; } + bool operator!=(const const_iterator& it) const { return pos != it.pos; } - - // The actual data - const dense_hashtable *ht; - pointer pos, end; + // The actual data + const dense_hashtable* ht; + pointer pos, end; }; -template -class dense_hashtable { - private: - typedef typename Alloc::template rebind::other value_alloc_type; +template +class dense_hashtable +{ + private: + typedef typename Alloc::template rebind::other value_alloc_type; - public: - typedef Key key_type; - typedef Value value_type; - typedef HashFcn hasher; - typedef EqualKey key_equal; - typedef Alloc allocator_type; + public: + typedef Key key_type; + typedef Value value_type; + typedef HashFcn hasher; + typedef EqualKey key_equal; + typedef Alloc allocator_type; - typedef typename value_alloc_type::size_type size_type; - typedef typename value_alloc_type::difference_type difference_type; - typedef typename value_alloc_type::reference reference; - typedef typename value_alloc_type::const_reference const_reference; - typedef typename value_alloc_type::pointer pointer; - typedef typename value_alloc_type::const_pointer const_pointer; - typedef dense_hashtable_iterator - iterator; + typedef typename value_alloc_type::size_type size_type; + typedef typename value_alloc_type::difference_type difference_type; + typedef typename value_alloc_type::reference reference; + typedef typename value_alloc_type::const_reference const_reference; + typedef typename value_alloc_type::pointer pointer; + typedef typename value_alloc_type::const_pointer const_pointer; + typedef dense_hashtable_iterator iterator; - typedef dense_hashtable_const_iterator - const_iterator; + typedef dense_hashtable_const_iterator const_iterator; - // These come from tr1. For us they're the same as regular iterators. - typedef iterator local_iterator; - typedef const_iterator const_local_iterator; + // These come from tr1. For us they're the same as regular iterators. + typedef iterator local_iterator; + typedef const_iterator const_local_iterator; - // How full we let the table get before we resize, by default. - // Knuth says .8 is good -- higher causes us to probe too much, - // though it saves memory. - static const int HT_OCCUPANCY_PCT; // defined at the bottom of this file + // How full we let the table get before we resize, by default. + // Knuth says .8 is good -- higher causes us to probe too much, + // though it saves memory. + static const int HT_OCCUPANCY_PCT; // defined at the bottom of this file - // How empty we let the table get before we resize lower, by default. - // (0.0 means never resize lower.) - // It should be less than OCCUPANCY_PCT / 2 or we thrash resizing - static const int HT_EMPTY_PCT; // defined at the bottom of this file + // How empty we let the table get before we resize lower, by default. + // (0.0 means never resize lower.) + // It should be less than OCCUPANCY_PCT / 2 or we thrash resizing + static const int HT_EMPTY_PCT; // defined at the bottom of this file - // Minimum size we're willing to let hashtables be. - // Must be a power of two, and at least 4. - // Note, however, that for a given hashtable, the initial size is a - // function of the first constructor arg, and may be >HT_MIN_BUCKETS. - static const size_type HT_MIN_BUCKETS = 4; + // Minimum size we're willing to let hashtables be. + // Must be a power of two, and at least 4. + // Note, however, that for a given hashtable, the initial size is a + // function of the first constructor arg, and may be >HT_MIN_BUCKETS. + static const size_type HT_MIN_BUCKETS = 4; - // By default, if you don't specify a hashtable size at - // construction-time, we use this size. Must be a power of two, and - // at least HT_MIN_BUCKETS. - static const size_type HT_DEFAULT_STARTING_BUCKETS = 32; + // By default, if you don't specify a hashtable size at + // construction-time, we use this size. Must be a power of two, and + // at least HT_MIN_BUCKETS. + static const size_type HT_DEFAULT_STARTING_BUCKETS = 32; - // ITERATOR FUNCTIONS - iterator begin() { return iterator(this, table, - table + num_buckets, true); } - iterator end() { return iterator(this, table + num_buckets, - table + num_buckets, true); } - const_iterator begin() const { return const_iterator(this, table, - table+num_buckets,true);} - const_iterator end() const { return const_iterator(this, table + num_buckets, - table+num_buckets,true);} + // ITERATOR FUNCTIONS + iterator begin() { return iterator(this, table, table + num_buckets, true); } + iterator end() { return iterator(this, table + num_buckets, table + num_buckets, true); } + const_iterator begin() const { return const_iterator(this, table, table + num_buckets, true); } + const_iterator end() const { return const_iterator(this, table + num_buckets, table + num_buckets, true); } - // These come from tr1 unordered_map. They iterate over 'bucket' n. - // We'll just consider bucket n to be the n-th element of the table. - local_iterator begin(size_type i) { - return local_iterator(this, table + i, table + i+1, false); - } - local_iterator end(size_type i) { - local_iterator it = begin(i); - if (!test_empty(i) && !test_deleted(i)) - ++it; - return it; - } - const_local_iterator begin(size_type i) const { - return const_local_iterator(this, table + i, table + i+1, false); - } - const_local_iterator end(size_type i) const { - const_local_iterator it = begin(i); - if (!test_empty(i) && !test_deleted(i)) - ++it; - return it; - } - - // ACCESSOR FUNCTIONS for the things we templatize on, basically - hasher hash_funct() const { return settings; } - key_equal key_eq() const { return key_info; } - allocator_type get_allocator() const { - return allocator_type(val_info); - } - - // Accessor function for statistics gathering. - int num_table_copies() const { return settings.num_ht_copies(); } - - private: - // Annoyingly, we can't copy values around, because they might have - // const components (they're probably pair). We use - // explicit destructor invocation and placement new to get around - // this. Arg. - void set_value(pointer dst, const_reference src) { - dst->~value_type(); // delete the old value, if any - new(dst) value_type(src); - } - - void destroy_buckets(size_type first, size_type last) { - for ( ; first != last; ++first) - table[first].~value_type(); - } - - // DELETE HELPER FUNCTIONS - // This lets the user describe a key that will indicate deleted - // table entries. This key should be an "impossible" entry -- - // if you try to insert it for real, you won't be able to retrieve it! - // (NB: while you pass in an entire value, only the key part is looked - // at. This is just because I don't know how to assign just a key.) - private: - void squash_deleted() { // gets rid of any deleted entries we have - if ( num_deleted ) { // get rid of deleted before writing - dense_hashtable tmp(*this); // copying will get rid of deleted - swap(tmp); // now we are tmp + // These come from tr1 unordered_map. They iterate over 'bucket' n. + // We'll just consider bucket n to be the n-th element of the table. + local_iterator begin(size_type i) { return local_iterator(this, table + i, table + i + 1, false); } + local_iterator end(size_type i) + { + local_iterator it = begin(i); + if (!test_empty(i) && !test_deleted(i)) + ++it; + return it; } - assert(num_deleted == 0); - } - - // Test if the given key is the deleted indicator. Requires - // num_deleted > 0, for correctness of read(), and because that - // guarantees that key_info.delkey is valid. - bool test_deleted_key(const key_type& key) const { - assert(num_deleted > 0); - return equals(key_info.delkey, key); - } - - public: - void set_deleted_key(const key_type &key) { - // the empty indicator (if specified) and the deleted indicator - // must be different - assert((!settings.use_empty() || !equals(key, get_key(val_info.emptyval))) - && "Passed the empty-key to set_deleted_key"); - // It's only safe to change what "deleted" means if we purge deleted guys - squash_deleted(); - settings.set_use_deleted(true); - key_info.delkey = key; - } - void clear_deleted_key() { - squash_deleted(); - settings.set_use_deleted(false); - } - key_type deleted_key() const { - assert(settings.use_deleted() - && "Must set deleted key before calling deleted_key"); - return key_info.delkey; - } - - // These are public so the iterators can use them - // True if the item at position bucknum is "deleted" marker - bool test_deleted(size_type bucknum) const { - // Invariant: !use_deleted() implies num_deleted is 0. - assert(settings.use_deleted() || num_deleted == 0); - return num_deleted > 0 && test_deleted_key(get_key(table[bucknum])); - } - bool test_deleted(const iterator &it) const { - // Invariant: !use_deleted() implies num_deleted is 0. - assert(settings.use_deleted() || num_deleted == 0); - return num_deleted > 0 && test_deleted_key(get_key(*it)); - } - bool test_deleted(const const_iterator &it) const { - // Invariant: !use_deleted() implies num_deleted is 0. - assert(settings.use_deleted() || num_deleted == 0); - return num_deleted > 0 && test_deleted_key(get_key(*it)); - } - - private: - void check_use_deleted(const char* caller) { - (void)caller; // could log it if the assert failed - assert(settings.use_deleted()); - } - - // Set it so test_deleted is true. true if object didn't used to be deleted. - bool set_deleted(iterator &it) { - check_use_deleted("set_deleted()"); - bool retval = !test_deleted(it); - // &* converts from iterator to value-type. - set_key(&(*it), key_info.delkey); - return retval; - } - // Set it so test_deleted is false. true if object used to be deleted. - bool clear_deleted(iterator &it) { - check_use_deleted("clear_deleted()"); - // Happens automatically when we assign something else in its place. - return test_deleted(it); - } - - // We also allow to set/clear the deleted bit on a const iterator. - // We allow a const_iterator for the same reason you can delete a - // const pointer: it's convenient, and semantically you can't use - // 'it' after it's been deleted anyway, so its const-ness doesn't - // really matter. - bool set_deleted(const_iterator &it) { - check_use_deleted("set_deleted()"); - bool retval = !test_deleted(it); - set_key(const_cast(&(*it)), key_info.delkey); - return retval; - } - // Set it so test_deleted is false. true if object used to be deleted. - bool clear_deleted(const_iterator &it) { - check_use_deleted("clear_deleted()"); - return test_deleted(it); - } - - // EMPTY HELPER FUNCTIONS - // This lets the user describe a key that will indicate empty (unused) - // table entries. This key should be an "impossible" entry -- - // if you try to insert it for real, you won't be able to retrieve it! - // (NB: while you pass in an entire value, only the key part is looked - // at. This is just because I don't know how to assign just a key.) - public: - // These are public so the iterators can use them - // True if the item at position bucknum is "empty" marker - bool test_empty(size_type bucknum) const { - assert(settings.use_empty()); // we always need to know what's empty! - return equals(get_key(val_info.emptyval), get_key(table[bucknum])); - } - bool test_empty(const iterator &it) const { - assert(settings.use_empty()); // we always need to know what's empty! - return equals(get_key(val_info.emptyval), get_key(*it)); - } - bool test_empty(const const_iterator &it) const { - assert(settings.use_empty()); // we always need to know what's empty! - return equals(get_key(val_info.emptyval), get_key(*it)); - } - - private: - void fill_range_with_empty(pointer table_start, pointer table_end) { - std::uninitialized_fill(table_start, table_end, val_info.emptyval); - } - - public: - // TODO(csilvers): change all callers of this to pass in a key instead, - // and take a const key_type instead of const value_type. - void set_empty_key(const_reference val) { - // Once you set the empty key, you can't change it - assert(!settings.use_empty() && "Calling set_empty_key multiple times"); - // The deleted indicator (if specified) and the empty indicator - // must be different. - assert((!settings.use_deleted() || !equals(get_key(val), key_info.delkey)) - && "Setting the empty key the same as the deleted key"); - settings.set_use_empty(true); - set_value(&val_info.emptyval, val); - - assert(!table); // must set before first use - // num_buckets was set in constructor even though table was NULL - table = val_info.allocate(num_buckets); - assert(table); - fill_range_with_empty(table, table + num_buckets); - } - // TODO(user): return a key_type rather than a value_type - value_type empty_key() const { - assert(settings.use_empty()); - return val_info.emptyval; - } - - // FUNCTIONS CONCERNING SIZE - public: - size_type size() const { return num_elements - num_deleted; } - size_type max_size() const { return val_info.max_size(); } - bool empty() const { return size() == 0; } - size_type bucket_count() const { return num_buckets; } - size_type max_bucket_count() const { return max_size(); } - size_type nonempty_bucket_count() const { return num_elements; } - // These are tr1 methods. Their idea of 'bucket' doesn't map well to - // what we do. We just say every bucket has 0 or 1 items in it. - size_type bucket_size(size_type i) const { - return begin(i) == end(i) ? 0 : 1; - } - - private: - // Because of the above, size_type(-1) is never legal; use it for errors - static const size_type ILLEGAL_BUCKET = size_type(-1); - - // Used after a string of deletes. Returns true if we actually shrunk. - // TODO(csilvers): take a delta so we can take into account inserts - // done after shrinking. Maybe make part of the Settings class? - bool maybe_shrink() { - assert(num_elements >= num_deleted); - assert((bucket_count() & (bucket_count()-1)) == 0); // is a power of two - assert(bucket_count() >= HT_MIN_BUCKETS); - bool retval = false; - - // If you construct a hashtable with < HT_DEFAULT_STARTING_BUCKETS, - // we'll never shrink until you get relatively big, and we'll never - // shrink below HT_DEFAULT_STARTING_BUCKETS. Otherwise, something - // like "dense_hash_set x; x.insert(4); x.erase(4);" will - // shrink us down to HT_MIN_BUCKETS buckets, which is too small. - const size_type num_remain = num_elements - num_deleted; - const size_type shrink_threshold = settings.shrink_threshold(); - if (shrink_threshold > 0 && num_remain < shrink_threshold && - bucket_count() > HT_DEFAULT_STARTING_BUCKETS) { - const float shrink_factor = settings.shrink_factor(); - size_type sz = bucket_count() / 2; // find how much we should shrink - while (sz > HT_DEFAULT_STARTING_BUCKETS && - num_remain < sz * shrink_factor) { - sz /= 2; // stay a power of 2 - } - dense_hashtable tmp(*this, sz); // Do the actual resizing - swap(tmp); // now we are tmp - retval = true; + const_local_iterator begin(size_type i) const + { + return const_local_iterator(this, table + i, table + i + 1, false); } - settings.set_consider_shrink(false); // because we just considered it - return retval; - } - - // We'll let you resize a hashtable -- though this makes us copy all! - // When you resize, you say, "make it big enough for this many more elements" - // Returns true if we actually resized, false if size was already ok. - bool resize_delta(size_type delta) { - bool did_resize = false; - if ( settings.consider_shrink() ) { // see if lots of deletes happened - if ( maybe_shrink() ) - did_resize = true; + const_local_iterator end(size_type i) const + { + const_local_iterator it = begin(i); + if (!test_empty(i) && !test_deleted(i)) + ++it; + return it; } - if (num_elements >= - (std::numeric_limits::max)() - delta) { - throw std::length_error("resize overflow"); + + // ACCESSOR FUNCTIONS for the things we templatize on, basically + hasher hash_funct() const { return settings; } + key_equal key_eq() const { return key_info; } + allocator_type get_allocator() const { return allocator_type(val_info); } + + // Accessor function for statistics gathering. + int num_table_copies() const { return settings.num_ht_copies(); } + + private: + // Annoyingly, we can't copy values around, because they might have + // const components (they're probably pair). We use + // explicit destructor invocation and placement new to get around + // this. Arg. + void set_value(pointer dst, const_reference src) + { + dst->~value_type(); // delete the old value, if any + new (dst) value_type(src); } - if ( bucket_count() >= HT_MIN_BUCKETS && - (num_elements + delta) <= settings.enlarge_threshold() ) - return did_resize; // we're ok as we are - // Sometimes, we need to resize just to get rid of all the - // "deleted" buckets that are clogging up the hashtable. So when - // deciding whether to resize, count the deleted buckets (which - // are currently taking up room). But later, when we decide what - // size to resize to, *don't* count deleted buckets, since they - // get discarded during the resize. - const size_type needed_size = settings.min_buckets(num_elements + delta, 0); - if ( needed_size <= bucket_count() ) // we have enough buckets - return did_resize; - - size_type resize_to = - settings.min_buckets(num_elements - num_deleted + delta, bucket_count()); - - if (resize_to < needed_size && // may double resize_to - resize_to < (std::numeric_limits::max)() / 2) { - // This situation means that we have enough deleted elements, - // that once we purge them, we won't actually have needed to - // grow. But we may want to grow anyway: if we just purge one - // element, say, we'll have to grow anyway next time we - // insert. Might as well grow now, since we're already going - // through the trouble of copying (in order to purge the - // deleted elements). - const size_type target = - static_cast(settings.shrink_size(resize_to*2)); - if (num_elements - num_deleted + delta >= target) { - // Good, we won't be below the shrink threshhold even if we double. - resize_to *= 2; - } + void destroy_buckets(size_type first, size_type last) + { + for (; first != last; ++first) + table[first].~value_type(); } - dense_hashtable tmp(*this, resize_to); - swap(tmp); // now we are tmp - return true; - } - // We require table be not-NULL and empty before calling this. - void resize_table(size_type /*old_size*/, size_type new_size, - base::true_type) { - table = val_info.realloc_or_die(table, new_size); - } - - void resize_table(size_type old_size, size_type new_size, base::false_type) { - val_info.deallocate(table, old_size); - table = val_info.allocate(new_size); - } - - // Used to actually do the rehashing when we grow/shrink a hashtable - void copy_from(const dense_hashtable &ht, size_type min_buckets_wanted) { - clear_to_size(settings.min_buckets(ht.size(), min_buckets_wanted)); - - // We use a normal iterator to get non-deleted bcks from ht - // We could use insert() here, but since we know there are - // no duplicates and no deleted items, we can be more efficient - assert((bucket_count() & (bucket_count()-1)) == 0); // a power of two - for ( const_iterator it = ht.begin(); it != ht.end(); ++it ) { - size_type num_probes = 0; // how many times we've probed - size_type bucknum; - const size_type bucket_count_minus_one = bucket_count() - 1; - for (bucknum = hash(get_key(*it)) & bucket_count_minus_one; - !test_empty(bucknum); // not empty - bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one) { - ++num_probes; - assert(num_probes < bucket_count() - && "Hashtable is full: an error in key_equal<> or hash<>"); - } - set_value(&table[bucknum], *it); // copies the value to here - num_elements++; + // DELETE HELPER FUNCTIONS + // This lets the user describe a key that will indicate deleted + // table entries. This key should be an "impossible" entry -- + // if you try to insert it for real, you won't be able to retrieve it! + // (NB: while you pass in an entire value, only the key part is looked + // at. This is just because I don't know how to assign just a key.) + private: + void squash_deleted() + { // gets rid of any deleted entries we have + if (num_deleted) + { // get rid of deleted before writing + dense_hashtable tmp(*this); // copying will get rid of deleted + swap(tmp); // now we are tmp + } + assert(num_deleted == 0); } - settings.inc_num_ht_copies(); - } - // Required by the spec for hashed associative container - public: - // Though the docs say this should be num_buckets, I think it's much - // more useful as num_elements. As a special feature, calling with - // req_elements==0 will cause us to shrink if we can, saving space. - void resize(size_type req_elements) { // resize to this or larger - if ( settings.consider_shrink() || req_elements == 0 ) - maybe_shrink(); - if ( req_elements > num_elements ) - resize_delta(req_elements - num_elements); - } - - // Get and change the value of shrink_factor and enlarge_factor. The - // description at the beginning of this file explains how to choose - // the values. Setting the shrink parameter to 0.0 ensures that the - // table never shrinks. - void get_resizing_parameters(float* shrink, float* grow) const { - *shrink = settings.shrink_factor(); - *grow = settings.enlarge_factor(); - } - void set_resizing_parameters(float shrink, float grow) { - settings.set_resizing_parameters(shrink, grow); - settings.reset_thresholds(bucket_count()); - } - - // CONSTRUCTORS -- as required by the specs, we take a size, - // but also let you specify a hashfunction, key comparator, - // and key extractor. We also define a copy constructor and =. - // DESTRUCTOR -- needs to free the table - explicit dense_hashtable(size_type expected_max_items_in_table = 0, - const HashFcn& hf = HashFcn(), - const EqualKey& eql = EqualKey(), - const ExtractKey& ext = ExtractKey(), - const SetKey& set = SetKey(), - const Alloc& alloc = Alloc()) - : settings(hf), - key_info(ext, set, eql), - num_deleted(0), - num_elements(0), - num_buckets(expected_max_items_in_table == 0 - ? HT_DEFAULT_STARTING_BUCKETS - : settings.min_buckets(expected_max_items_in_table, 0)), - val_info(alloc_impl(alloc)), - table(NULL) { - // table is NULL until emptyval is set. However, we set num_buckets - // here so we know how much space to allocate once emptyval is set - settings.reset_thresholds(bucket_count()); - } - - // As a convenience for resize(), we allow an optional second argument - // which lets you make this new hashtable a different size than ht - dense_hashtable(const dense_hashtable& ht, - size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS) - : settings(ht.settings), - key_info(ht.key_info), - num_deleted(0), - num_elements(0), - num_buckets(0), - val_info(ht.val_info), - table(NULL) { - if (!ht.settings.use_empty()) { - // If use_empty isn't set, copy_from will crash, so we do our own copying. - assert(ht.empty()); - num_buckets = settings.min_buckets(ht.size(), min_buckets_wanted); - settings.reset_thresholds(bucket_count()); - return; + // Test if the given key is the deleted indicator. Requires + // num_deleted > 0, for correctness of read(), and because that + // guarantees that key_info.delkey is valid. + bool test_deleted_key(const key_type& key) const + { + assert(num_deleted > 0); + return equals(key_info.delkey, key); } - settings.reset_thresholds(bucket_count()); - copy_from(ht, min_buckets_wanted); // copy_from() ignores deleted entries - } - dense_hashtable& operator= (const dense_hashtable& ht) { - if (&ht == this) return *this; // don't copy onto ourselves - if (!ht.settings.use_empty()) { - assert(ht.empty()); - dense_hashtable empty_table(ht); // empty table with ht's thresholds - this->swap(empty_table); - return *this; + public: + void set_deleted_key(const key_type& key) + { + // the empty indicator (if specified) and the deleted indicator + // must be different + assert((!settings.use_empty() || !equals(key, get_key(val_info.emptyval))) && + "Passed the empty-key to set_deleted_key"); + // It's only safe to change what "deleted" means if we purge deleted guys + squash_deleted(); + settings.set_use_deleted(true); + key_info.delkey = key; } - settings = ht.settings; - key_info = ht.key_info; - set_value(&val_info.emptyval, ht.val_info.emptyval); - // copy_from() calls clear and sets num_deleted to 0 too - copy_from(ht, HT_MIN_BUCKETS); - // we purposefully don't copy the allocator, which may not be copyable - return *this; - } - - ~dense_hashtable() { - if (table) { - destroy_buckets(0, num_buckets); - val_info.deallocate(table, num_buckets); + void clear_deleted_key() + { + squash_deleted(); + settings.set_use_deleted(false); } - } - - // Many STL algorithms use swap instead of copy constructors - void swap(dense_hashtable& ht) { - std::swap(settings, ht.settings); - std::swap(key_info, ht.key_info); - std::swap(num_deleted, ht.num_deleted); - std::swap(num_elements, ht.num_elements); - std::swap(num_buckets, ht.num_buckets); - { value_type tmp; // for annoying reasons, swap() doesn't work - set_value(&tmp, val_info.emptyval); - set_value(&val_info.emptyval, ht.val_info.emptyval); - set_value(&ht.val_info.emptyval, tmp); + key_type deleted_key() const + { + assert(settings.use_deleted() && "Must set deleted key before calling deleted_key"); + return key_info.delkey; } - std::swap(table, ht.table); - settings.reset_thresholds(bucket_count()); // also resets consider_shrink - ht.settings.reset_thresholds(ht.bucket_count()); - // we purposefully don't swap the allocator, which may not be swap-able - } - private: - void clear_to_size(size_type new_num_buckets) { - if (!table) { - table = val_info.allocate(new_num_buckets); - } else { - destroy_buckets(0, num_buckets); - if (new_num_buckets != num_buckets) { // resize, if necessary - typedef base::integral_constant >::value> - realloc_ok; - resize_table(num_buckets, new_num_buckets, realloc_ok()); - } + // These are public so the iterators can use them + // True if the item at position bucknum is "deleted" marker + bool test_deleted(size_type bucknum) const + { + // Invariant: !use_deleted() implies num_deleted is 0. + assert(settings.use_deleted() || num_deleted == 0); + return num_deleted > 0 && test_deleted_key(get_key(table[bucknum])); } - assert(table); - fill_range_with_empty(table, table + new_num_buckets); - num_elements = 0; - num_deleted = 0; - num_buckets = new_num_buckets; // our new size - settings.reset_thresholds(bucket_count()); - } - - public: - // It's always nice to be able to clear a table without deallocating it - void clear() { - // If the table is already empty, and the number of buckets is - // already as we desire, there's nothing to do. - const size_type new_num_buckets = settings.min_buckets(0, 0); - if (num_elements == 0 && new_num_buckets == num_buckets) { - return; + bool test_deleted(const iterator& it) const + { + // Invariant: !use_deleted() implies num_deleted is 0. + assert(settings.use_deleted() || num_deleted == 0); + return num_deleted > 0 && test_deleted_key(get_key(*it)); } - clear_to_size(new_num_buckets); - } - - // Clear the table without resizing it. - // Mimicks the stl_hashtable's behaviour when clear()-ing in that it - // does not modify the bucket count - void clear_no_resize() { - if (num_elements > 0) { - assert(table); - destroy_buckets(0, num_buckets); - fill_range_with_empty(table, table + num_buckets); + bool test_deleted(const const_iterator& it) const + { + // Invariant: !use_deleted() implies num_deleted is 0. + assert(settings.use_deleted() || num_deleted == 0); + return num_deleted > 0 && test_deleted_key(get_key(*it)); } - // don't consider to shrink before another erase() - settings.reset_thresholds(bucket_count()); - num_elements = 0; - num_deleted = 0; - } - // LOOKUP ROUTINES - private: - // Returns a pair of positions: 1st where the object is, 2nd where - // it would go if you wanted to insert it. 1st is ILLEGAL_BUCKET - // if object is not found; 2nd is ILLEGAL_BUCKET if it is. - // Note: because of deletions where-to-insert is not trivial: it's the - // first deleted bucket we see, as long as we don't find the key later - std::pair find_position(const key_type &key) const { - size_type num_probes = 0; // how many times we've probed - const size_type bucket_count_minus_one = bucket_count() - 1; - size_type bucknum = hash(key) & bucket_count_minus_one; - size_type insert_pos = ILLEGAL_BUCKET; // where we would insert - while ( 1 ) { // probe until something happens - if ( test_empty(bucknum) ) { // bucket is empty - if ( insert_pos == ILLEGAL_BUCKET ) // found no prior place to insert - return std::pair(ILLEGAL_BUCKET, bucknum); + private: + void check_use_deleted(const char* caller) + { + (void)caller; // could log it if the assert failed + assert(settings.use_deleted()); + } + + // Set it so test_deleted is true. true if object didn't used to be deleted. + bool set_deleted(iterator& it) + { + check_use_deleted("set_deleted()"); + bool retval = !test_deleted(it); + // &* converts from iterator to value-type. + set_key(&(*it), key_info.delkey); + return retval; + } + // Set it so test_deleted is false. true if object used to be deleted. + bool clear_deleted(iterator& it) + { + check_use_deleted("clear_deleted()"); + // Happens automatically when we assign something else in its place. + return test_deleted(it); + } + + // We also allow to set/clear the deleted bit on a const iterator. + // We allow a const_iterator for the same reason you can delete a + // const pointer: it's convenient, and semantically you can't use + // 'it' after it's been deleted anyway, so its const-ness doesn't + // really matter. + bool set_deleted(const_iterator& it) + { + check_use_deleted("set_deleted()"); + bool retval = !test_deleted(it); + set_key(const_cast(&(*it)), key_info.delkey); + return retval; + } + // Set it so test_deleted is false. true if object used to be deleted. + bool clear_deleted(const_iterator& it) + { + check_use_deleted("clear_deleted()"); + return test_deleted(it); + } + + // EMPTY HELPER FUNCTIONS + // This lets the user describe a key that will indicate empty (unused) + // table entries. This key should be an "impossible" entry -- + // if you try to insert it for real, you won't be able to retrieve it! + // (NB: while you pass in an entire value, only the key part is looked + // at. This is just because I don't know how to assign just a key.) + public: + // These are public so the iterators can use them + // True if the item at position bucknum is "empty" marker + bool test_empty(size_type bucknum) const + { + assert(settings.use_empty()); // we always need to know what's empty! + return equals(get_key(val_info.emptyval), get_key(table[bucknum])); + } + bool test_empty(const iterator& it) const + { + assert(settings.use_empty()); // we always need to know what's empty! + return equals(get_key(val_info.emptyval), get_key(*it)); + } + bool test_empty(const const_iterator& it) const + { + assert(settings.use_empty()); // we always need to know what's empty! + return equals(get_key(val_info.emptyval), get_key(*it)); + } + + private: + void fill_range_with_empty(pointer table_start, pointer table_end) + { + std::uninitialized_fill(table_start, table_end, val_info.emptyval); + } + + public: + // TODO(csilvers): change all callers of this to pass in a key instead, + // and take a const key_type instead of const value_type. + void set_empty_key(const_reference val) + { + // Once you set the empty key, you can't change it + assert(!settings.use_empty() && "Calling set_empty_key multiple times"); + // The deleted indicator (if specified) and the empty indicator + // must be different. + assert((!settings.use_deleted() || !equals(get_key(val), key_info.delkey)) && + "Setting the empty key the same as the deleted key"); + settings.set_use_empty(true); + set_value(&val_info.emptyval, val); + + assert(!table); // must set before first use + // num_buckets was set in constructor even though table was NULL + table = val_info.allocate(num_buckets); + assert(table); + fill_range_with_empty(table, table + num_buckets); + } + // TODO(user): return a key_type rather than a value_type + value_type empty_key() const + { + assert(settings.use_empty()); + return val_info.emptyval; + } + + // FUNCTIONS CONCERNING SIZE + public: + size_type size() const { return num_elements - num_deleted; } + size_type max_size() const { return val_info.max_size(); } + bool empty() const { return size() == 0; } + size_type bucket_count() const { return num_buckets; } + size_type max_bucket_count() const { return max_size(); } + size_type nonempty_bucket_count() const { return num_elements; } + // These are tr1 methods. Their idea of 'bucket' doesn't map well to + // what we do. We just say every bucket has 0 or 1 items in it. + size_type bucket_size(size_type i) const { return begin(i) == end(i) ? 0 : 1; } + + private: + // Because of the above, size_type(-1) is never legal; use it for errors + static const size_type ILLEGAL_BUCKET = size_type(-1); + + // Used after a string of deletes. Returns true if we actually shrunk. + // TODO(csilvers): take a delta so we can take into account inserts + // done after shrinking. Maybe make part of the Settings class? + bool maybe_shrink() + { + assert(num_elements >= num_deleted); + assert((bucket_count() & (bucket_count() - 1)) == 0); // is a power of two + assert(bucket_count() >= HT_MIN_BUCKETS); + bool retval = false; + + // If you construct a hashtable with < HT_DEFAULT_STARTING_BUCKETS, + // we'll never shrink until you get relatively big, and we'll never + // shrink below HT_DEFAULT_STARTING_BUCKETS. Otherwise, something + // like "dense_hash_set x; x.insert(4); x.erase(4);" will + // shrink us down to HT_MIN_BUCKETS buckets, which is too small. + const size_type num_remain = num_elements - num_deleted; + const size_type shrink_threshold = settings.shrink_threshold(); + if (shrink_threshold > 0 && num_remain < shrink_threshold && bucket_count() > HT_DEFAULT_STARTING_BUCKETS) + { + const float shrink_factor = settings.shrink_factor(); + size_type sz = bucket_count() / 2; // find how much we should shrink + while (sz > HT_DEFAULT_STARTING_BUCKETS && num_remain < sz * shrink_factor) + { + sz /= 2; // stay a power of 2 + } + dense_hashtable tmp(*this, sz); // Do the actual resizing + swap(tmp); // now we are tmp + retval = true; + } + settings.set_consider_shrink(false); // because we just considered it + return retval; + } + + // We'll let you resize a hashtable -- though this makes us copy all! + // When you resize, you say, "make it big enough for this many more elements" + // Returns true if we actually resized, false if size was already ok. + bool resize_delta(size_type delta) + { + bool did_resize = false; + if (settings.consider_shrink()) + { // see if lots of deletes happened + if (maybe_shrink()) + did_resize = true; + } + if (num_elements >= (std::numeric_limits::max)() - delta) + { + throw std::length_error("resize overflow"); + } + if (bucket_count() >= HT_MIN_BUCKETS && (num_elements + delta) <= settings.enlarge_threshold()) + return did_resize; // we're ok as we are + + // Sometimes, we need to resize just to get rid of all the + // "deleted" buckets that are clogging up the hashtable. So when + // deciding whether to resize, count the deleted buckets (which + // are currently taking up room). But later, when we decide what + // size to resize to, *don't* count deleted buckets, since they + // get discarded during the resize. + const size_type needed_size = settings.min_buckets(num_elements + delta, 0); + if (needed_size <= bucket_count()) // we have enough buckets + return did_resize; + + size_type resize_to = settings.min_buckets(num_elements - num_deleted + delta, bucket_count()); + + if (resize_to < needed_size && // may double resize_to + resize_to < (std::numeric_limits::max)() / 2) + { + // This situation means that we have enough deleted elements, + // that once we purge them, we won't actually have needed to + // grow. But we may want to grow anyway: if we just purge one + // element, say, we'll have to grow anyway next time we + // insert. Might as well grow now, since we're already going + // through the trouble of copying (in order to purge the + // deleted elements). + const size_type target = static_cast(settings.shrink_size(resize_to * 2)); + if (num_elements - num_deleted + delta >= target) + { + // Good, we won't be below the shrink threshhold even if we double. + resize_to *= 2; + } + } + dense_hashtable tmp(*this, resize_to); + swap(tmp); // now we are tmp + return true; + } + + // We require table be not-NULL and empty before calling this. + void resize_table(size_type /*old_size*/, size_type new_size, base::true_type) + { + table = val_info.realloc_or_die(table, new_size); + } + + void resize_table(size_type old_size, size_type new_size, base::false_type) + { + val_info.deallocate(table, old_size); + table = val_info.allocate(new_size); + } + + // Used to actually do the rehashing when we grow/shrink a hashtable + void copy_from(const dense_hashtable& ht, size_type min_buckets_wanted) + { + clear_to_size(settings.min_buckets(ht.size(), min_buckets_wanted)); + + // We use a normal iterator to get non-deleted bcks from ht + // We could use insert() here, but since we know there are + // no duplicates and no deleted items, we can be more efficient + assert((bucket_count() & (bucket_count() - 1)) == 0); // a power of two + for (const_iterator it = ht.begin(); it != ht.end(); ++it) + { + size_type num_probes = 0; // how many times we've probed + size_type bucknum; + const size_type bucket_count_minus_one = bucket_count() - 1; + for (bucknum = hash(get_key(*it)) & bucket_count_minus_one; !test_empty(bucknum); // not empty + bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one) + { + ++num_probes; + assert(num_probes < bucket_count() && "Hashtable is full: an error in key_equal<> or hash<>"); + } + set_value(&table[bucknum], *it); // copies the value to here + num_elements++; + } + settings.inc_num_ht_copies(); + } + + // Required by the spec for hashed associative container + public: + // Though the docs say this should be num_buckets, I think it's much + // more useful as num_elements. As a special feature, calling with + // req_elements==0 will cause us to shrink if we can, saving space. + void resize(size_type req_elements) + { // resize to this or larger + if (settings.consider_shrink() || req_elements == 0) + maybe_shrink(); + if (req_elements > num_elements) + resize_delta(req_elements - num_elements); + } + + // Get and change the value of shrink_factor and enlarge_factor. The + // description at the beginning of this file explains how to choose + // the values. Setting the shrink parameter to 0.0 ensures that the + // table never shrinks. + void get_resizing_parameters(float* shrink, float* grow) const + { + *shrink = settings.shrink_factor(); + *grow = settings.enlarge_factor(); + } + void set_resizing_parameters(float shrink, float grow) + { + settings.set_resizing_parameters(shrink, grow); + settings.reset_thresholds(bucket_count()); + } + + // CONSTRUCTORS -- as required by the specs, we take a size, + // but also let you specify a hashfunction, key comparator, + // and key extractor. We also define a copy constructor and =. + // DESTRUCTOR -- needs to free the table + explicit dense_hashtable(size_type expected_max_items_in_table = 0, + const HashFcn& hf = HashFcn(), + const EqualKey& eql = EqualKey(), + const ExtractKey& ext = ExtractKey(), + const SetKey& set = SetKey(), + const Alloc& alloc = Alloc()) + : settings(hf) + , key_info(ext, set, eql) + , num_deleted(0) + , num_elements(0) + , num_buckets(expected_max_items_in_table == 0 ? HT_DEFAULT_STARTING_BUCKETS + : settings.min_buckets(expected_max_items_in_table, 0)) + , val_info(alloc_impl(alloc)) + , table(NULL) + { + // table is NULL until emptyval is set. However, we set num_buckets + // here so we know how much space to allocate once emptyval is set + settings.reset_thresholds(bucket_count()); + } + + // As a convenience for resize(), we allow an optional second argument + // which lets you make this new hashtable a different size than ht + dense_hashtable(const dense_hashtable& ht, size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS) + : settings(ht.settings) + , key_info(ht.key_info) + , num_deleted(0) + , num_elements(0) + , num_buckets(0) + , val_info(ht.val_info) + , table(NULL) + { + if (!ht.settings.use_empty()) + { + // If use_empty isn't set, copy_from will crash, so we do our own copying. + assert(ht.empty()); + num_buckets = settings.min_buckets(ht.size(), min_buckets_wanted); + settings.reset_thresholds(bucket_count()); + return; + } + settings.reset_thresholds(bucket_count()); + copy_from(ht, min_buckets_wanted); // copy_from() ignores deleted entries + } + + dense_hashtable& operator=(const dense_hashtable& ht) + { + if (&ht == this) + return *this; // don't copy onto ourselves + if (!ht.settings.use_empty()) + { + assert(ht.empty()); + dense_hashtable empty_table(ht); // empty table with ht's thresholds + this->swap(empty_table); + return *this; + } + settings = ht.settings; + key_info = ht.key_info; + set_value(&val_info.emptyval, ht.val_info.emptyval); + // copy_from() calls clear and sets num_deleted to 0 too + copy_from(ht, HT_MIN_BUCKETS); + // we purposefully don't copy the allocator, which may not be copyable + return *this; + } + + ~dense_hashtable() + { + if (table) + { + destroy_buckets(0, num_buckets); + val_info.deallocate(table, num_buckets); + } + } + + // Many STL algorithms use swap instead of copy constructors + void swap(dense_hashtable& ht) + { + std::swap(settings, ht.settings); + std::swap(key_info, ht.key_info); + std::swap(num_deleted, ht.num_deleted); + std::swap(num_elements, ht.num_elements); + std::swap(num_buckets, ht.num_buckets); + { + value_type tmp; // for annoying reasons, swap() doesn't work + set_value(&tmp, val_info.emptyval); + set_value(&val_info.emptyval, ht.val_info.emptyval); + set_value(&ht.val_info.emptyval, tmp); + } + std::swap(table, ht.table); + settings.reset_thresholds(bucket_count()); // also resets consider_shrink + ht.settings.reset_thresholds(ht.bucket_count()); + // we purposefully don't swap the allocator, which may not be swap-able + } + + private: + void clear_to_size(size_type new_num_buckets) + { + if (!table) + { + table = val_info.allocate(new_num_buckets); + } else - return std::pair(ILLEGAL_BUCKET, insert_pos); - - } else if ( test_deleted(bucknum) ) {// keep searching, but mark to insert - if ( insert_pos == ILLEGAL_BUCKET ) - insert_pos = bucknum; - - } else if ( equals(key, get_key(table[bucknum])) ) { - return std::pair(bucknum, ILLEGAL_BUCKET); - } - ++num_probes; // we're doing another probe - bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one; - assert(num_probes < bucket_count() - && "Hashtable is full: an error in key_equal<> or hash<>"); - } - } - - public: - - iterator find(const key_type& key) { - if ( size() == 0 ) return end(); - std::pair pos = find_position(key); - if ( pos.first == ILLEGAL_BUCKET ) // alas, not there - return end(); - else - return iterator(this, table + pos.first, table + num_buckets, false); - } - - const_iterator find(const key_type& key) const { - if ( size() == 0 ) return end(); - std::pair pos = find_position(key); - if ( pos.first == ILLEGAL_BUCKET ) // alas, not there - return end(); - else - return const_iterator(this, table + pos.first, table+num_buckets, false); - } - - // This is a tr1 method: the bucket a given key is in, or what bucket - // it would be put in, if it were to be inserted. Shrug. - size_type bucket(const key_type& key) const { - std::pair pos = find_position(key); - return pos.first == ILLEGAL_BUCKET ? pos.second : pos.first; - } - - // Counts how many elements have key key. For maps, it's either 0 or 1. - size_type count(const key_type &key) const { - std::pair pos = find_position(key); - return pos.first == ILLEGAL_BUCKET ? 0 : 1; - } - - // Likewise, equal_range doesn't really make sense for us. Oh well. - std::pair equal_range(const key_type& key) { - iterator pos = find(key); // either an iterator or end - if (pos == end()) { - return std::pair(pos, pos); - } else { - const iterator startpos = pos++; - return std::pair(startpos, pos); - } - } - std::pair equal_range(const key_type& key) - const { - const_iterator pos = find(key); // either an iterator or end - if (pos == end()) { - return std::pair(pos, pos); - } else { - const const_iterator startpos = pos++; - return std::pair(startpos, pos); - } - } - - - // INSERTION ROUTINES - private: - // Private method used by insert_noresize and find_or_insert. - iterator insert_at(const_reference obj, size_type pos) { - if (size() >= max_size()) { - throw std::length_error("insert overflow"); - } - if ( test_deleted(pos) ) { // just replace if it's been del. - // shrug: shouldn't need to be const. - const_iterator delpos(this, table + pos, table + num_buckets, false); - clear_deleted(delpos); - assert( num_deleted > 0); - --num_deleted; // used to be, now it isn't - } else { - ++num_elements; // replacing an empty bucket - } - set_value(&table[pos], obj); - return iterator(this, table + pos, table + num_buckets, false); - } - - // If you know *this is big enough to hold obj, use this routine - std::pair insert_noresize(const_reference obj) { - // First, double-check we're not inserting delkey or emptyval - assert((!settings.use_empty() || !equals(get_key(obj), - get_key(val_info.emptyval))) - && "Inserting the empty key"); - assert((!settings.use_deleted() || !equals(get_key(obj), key_info.delkey)) - && "Inserting the deleted key"); - const std::pair pos = find_position(get_key(obj)); - if ( pos.first != ILLEGAL_BUCKET) { // object was already there - return std::pair(iterator(this, table + pos.first, - table + num_buckets, false), - false); // false: we didn't insert - } else { // pos.second says where to put it - return std::pair(insert_at(obj, pos.second), true); - } - } - - // Specializations of insert(it, it) depending on the power of the iterator: - // (1) Iterator supports operator-, resize before inserting - template - void insert(ForwardIterator f, ForwardIterator l, std::forward_iterator_tag) { - size_t dist = std::distance(f, l); - if (dist >= (std::numeric_limits::max)()) { - throw std::length_error("insert-range overflow"); - } - resize_delta(static_cast(dist)); - for ( ; dist > 0; --dist, ++f) { - insert_noresize(*f); - } - } - - // (2) Arbitrary iterator, can't tell how much to resize - template - void insert(InputIterator f, InputIterator l, std::input_iterator_tag) { - for ( ; f != l; ++f) - insert(*f); - } - - public: - // This is the normal insert routine, used by the outside world - std::pair insert(const_reference obj) { - resize_delta(1); // adding an object, grow if need be - return insert_noresize(obj); - } - - // When inserting a lot at a time, we specialize on the type of iterator - template - void insert(InputIterator f, InputIterator l) { - // specializes on iterator type - insert(f, l, - typename std::iterator_traits::iterator_category()); - } - - // DefaultValue is a functor that takes a key and returns a value_type - // representing the default value to be inserted if none is found. - template - value_type& find_or_insert(const key_type& key) { - // First, double-check we're not inserting emptykey or delkey - assert((!settings.use_empty() || !equals(key, get_key(val_info.emptyval))) - && "Inserting the empty key"); - assert((!settings.use_deleted() || !equals(key, key_info.delkey)) - && "Inserting the deleted key"); - const std::pair pos = find_position(key); - DefaultValue default_value; - if ( pos.first != ILLEGAL_BUCKET) { // object was already there - return table[pos.first]; - } else if (resize_delta(1)) { // needed to rehash to make room - // Since we resized, we can't use pos, so recalculate where to insert. - return *insert_noresize(default_value(key)).first; - } else { // no need to rehash, insert right here - return *insert_at(default_value(key), pos.second); - } - } - - - // DELETION ROUTINES - size_type erase(const key_type& key) { - // First, double-check we're not trying to erase delkey or emptyval. - assert((!settings.use_empty() || !equals(key, get_key(val_info.emptyval))) - && "Erasing the empty key"); - assert((!settings.use_deleted() || !equals(key, key_info.delkey)) - && "Erasing the deleted key"); - const_iterator pos = find(key); // shrug: shouldn't need to be const - if ( pos != end() ) { - assert(!test_deleted(pos)); // or find() shouldn't have returned it - set_deleted(pos); - ++num_deleted; - settings.set_consider_shrink(true); // will think about shrink after next insert - return 1; // because we deleted one thing - } else { - return 0; // because we deleted nothing - } - } - - // We return the iterator past the deleted item. - void erase(iterator pos) { - if ( pos == end() ) return; // sanity check - if ( set_deleted(pos) ) { // true if object has been newly deleted - ++num_deleted; - settings.set_consider_shrink(true); // will think about shrink after next insert - } - } - - void erase(iterator f, iterator l) { - for ( ; f != l; ++f) { - if ( set_deleted(f) ) // should always be true - ++num_deleted; - } - settings.set_consider_shrink(true); // will think about shrink after next insert - } - - // We allow you to erase a const_iterator just like we allow you to - // erase an iterator. This is in parallel to 'delete': you can delete - // a const pointer just like a non-const pointer. The logic is that - // you can't use the object after it's erased anyway, so it doesn't matter - // if it's const or not. - void erase(const_iterator pos) { - if ( pos == end() ) return; // sanity check - if ( set_deleted(pos) ) { // true if object has been newly deleted - ++num_deleted; - settings.set_consider_shrink(true); // will think about shrink after next insert - } - } - void erase(const_iterator f, const_iterator l) { - for ( ; f != l; ++f) { - if ( set_deleted(f) ) // should always be true - ++num_deleted; - } - settings.set_consider_shrink(true); // will think about shrink after next insert - } - - - // COMPARISON - bool operator==(const dense_hashtable& ht) const { - if (size() != ht.size()) { - return false; - } else if (this == &ht) { - return true; - } else { - // Iterate through the elements in "this" and see if the - // corresponding element is in ht - for ( const_iterator it = begin(); it != end(); ++it ) { - const_iterator it2 = ht.find(get_key(*it)); - if ((it2 == ht.end()) || (*it != *it2)) { - return false; + { + destroy_buckets(0, num_buckets); + if (new_num_buckets != num_buckets) + { // resize, if necessary + typedef base::integral_constant< + bool, + base::is_same>::value> + realloc_ok; + resize_table(num_buckets, new_num_buckets, realloc_ok()); + } } - } - return true; + assert(table); + fill_range_with_empty(table, table + new_num_buckets); + num_elements = 0; + num_deleted = 0; + num_buckets = new_num_buckets; // our new size + settings.reset_thresholds(bucket_count()); } - } - bool operator!=(const dense_hashtable& ht) const { - return !(*this == ht); - } - - // I/O - // We support reading and writing hashtables to disk. Alas, since - // I don't know how to write a hasher or key_equal, you have to make - // sure everything but the table is the same. We compact before writing. - private: - // Every time the disk format changes, this should probably change too - typedef unsigned long MagicNumberType; - static const MagicNumberType MAGIC_NUMBER = 0x13578642; - - public: - // I/O -- this is an add-on for writing hash table to disk - // - // INPUT and OUTPUT must be either a FILE, *or* a C++ stream - // (istream, ostream, etc) *or* a class providing - // Read(void*, size_t) and Write(const void*, size_t) - // (respectively), which writes a buffer into a stream - // (which the INPUT/OUTPUT instance presumably owns). - - typedef sparsehash_internal::pod_serializer NopointerSerializer; - - // ValueSerializer: a functor. operator()(OUTPUT*, const value_type&) - template - bool serialize(ValueSerializer serializer, OUTPUT *fp) { - squash_deleted(); // so we don't have to worry about delkey - if ( !sparsehash_internal::write_bigendian_number(fp, MAGIC_NUMBER, 4) ) - return false; - if ( !sparsehash_internal::write_bigendian_number(fp, num_buckets, 8) ) - return false; - if ( !sparsehash_internal::write_bigendian_number(fp, num_elements, 8) ) - return false; - // Now write a bitmap of non-empty buckets. - for ( size_type i = 0; i < num_buckets; i += 8 ) { - unsigned char bits = 0; - for ( int bit = 0; bit < 8; ++bit ) { - if ( i + bit < num_buckets && !test_empty(i + bit) ) - bits |= (1 << bit); - } - if ( !sparsehash_internal::write_data(fp, &bits, sizeof(bits)) ) - return false; - for ( int bit = 0; bit < 8; ++bit ) { - if ( bits & (1 << bit) ) { - if ( !serializer(fp, table[i + bit]) ) return false; + public: + // It's always nice to be able to clear a table without deallocating it + void clear() + { + // If the table is already empty, and the number of buckets is + // already as we desire, there's nothing to do. + const size_type new_num_buckets = settings.min_buckets(0, 0); + if (num_elements == 0 && new_num_buckets == num_buckets) + { + return; } - } + clear_to_size(new_num_buckets); } - return true; - } - // INPUT: anything we've written an overload of read_data() for. - // ValueSerializer: a functor. operator()(INPUT*, value_type*) - template - bool unserialize(ValueSerializer serializer, INPUT *fp) { - assert(settings.use_empty() && "empty_key not set for read"); - - clear(); // just to be consistent - MagicNumberType magic_read; - if ( !sparsehash_internal::read_bigendian_number(fp, &magic_read, 4) ) - return false; - if ( magic_read != MAGIC_NUMBER ) { - return false; - } - size_type new_num_buckets; - if ( !sparsehash_internal::read_bigendian_number(fp, &new_num_buckets, 8) ) - return false; - clear_to_size(new_num_buckets); - if ( !sparsehash_internal::read_bigendian_number(fp, &num_elements, 8) ) - return false; - - // Read the bitmap of non-empty buckets. - for (size_type i = 0; i < num_buckets; i += 8) { - unsigned char bits; - if ( !sparsehash_internal::read_data(fp, &bits, sizeof(bits)) ) - return false; - for ( int bit = 0; bit < 8; ++bit ) { - if ( i + bit < num_buckets && (bits & (1 << bit)) ) { // not empty - if ( !serializer(fp, &table[i + bit]) ) return false; + // Clear the table without resizing it. + // Mimicks the stl_hashtable's behaviour when clear()-ing in that it + // does not modify the bucket count + void clear_no_resize() + { + if (num_elements > 0) + { + assert(table); + destroy_buckets(0, num_buckets); + fill_range_with_empty(table, table + num_buckets); } - } - } - return true; - } - - private: - template - class alloc_impl : public A { - public: - typedef typename A::pointer pointer; - typedef typename A::size_type size_type; - - // Convert a normal allocator to one that has realloc_or_die() - alloc_impl(const A& a) : A(a) { } - - // realloc_or_die should only be used when using the default - // allocator (libc_allocator_with_realloc). - pointer realloc_or_die(pointer /*ptr*/, size_type /*n*/) { - fprintf(stderr, "realloc_or_die is only supported for " - "libc_allocator_with_realloc\n"); - //exit(1); - return NULL; - } - }; - - // A template specialization of alloc_impl for - // libc_allocator_with_realloc that can handle realloc_or_die. - template - class alloc_impl > - : public libc_allocator_with_realloc { - public: - typedef typename libc_allocator_with_realloc::pointer pointer; - typedef typename libc_allocator_with_realloc::size_type size_type; - - alloc_impl(const libc_allocator_with_realloc& a) - : libc_allocator_with_realloc(a) { } - - pointer realloc_or_die(pointer ptr, size_type n) { - pointer retval = this->reallocate(ptr, n); - if (retval == NULL) { - fprintf(stderr, "sparsehash: FATAL ERROR: failed to reallocate " - "%lu elements for ptr %p", static_cast(n), ptr); - //exit(1); - } - return retval; - } - }; - - // Package allocator with emptyval to eliminate memory needed for - // the zero-size allocator. - // If new fields are added to this class, we should add them to - // operator= and swap. - class ValInfo : public alloc_impl { - public: - typedef typename alloc_impl::value_type value_type; - - ValInfo(const alloc_impl& a) - : alloc_impl(a), emptyval() { } - ValInfo(const ValInfo& v) - : alloc_impl(v), emptyval(v.emptyval) { } - - value_type emptyval; // which key marks unused entries - }; - - - // Package functors with another class to eliminate memory needed for - // zero-size functors. Since ExtractKey and hasher's operator() might - // have the same function signature, they must be packaged in - // different classes. - struct Settings : - sparsehash_internal::sh_hashtable_settings { - explicit Settings(const hasher& hf) - : sparsehash_internal::sh_hashtable_settings( - hf, HT_OCCUPANCY_PCT / 100.0f, HT_EMPTY_PCT / 100.0f) {} - }; - - // Packages ExtractKey and SetKey functors. - class KeyInfo : public ExtractKey, public SetKey, public EqualKey { - public: - KeyInfo(const ExtractKey& ek, const SetKey& sk, const EqualKey& eq) - : ExtractKey(ek), - SetKey(sk), - EqualKey(eq) { + // don't consider to shrink before another erase() + settings.reset_thresholds(bucket_count()); + num_elements = 0; + num_deleted = 0; } - // We want to return the exact same type as ExtractKey: Key or const Key& - typename ExtractKey::result_type get_key(const_reference v) const { - return ExtractKey::operator()(v); - } - void set_key(pointer v, const key_type& k) const { - SetKey::operator()(v, k); - } - bool equals(const key_type& a, const key_type& b) const { - return EqualKey::operator()(a, b); + // LOOKUP ROUTINES + private: + // Returns a pair of positions: 1st where the object is, 2nd where + // it would go if you wanted to insert it. 1st is ILLEGAL_BUCKET + // if object is not found; 2nd is ILLEGAL_BUCKET if it is. + // Note: because of deletions where-to-insert is not trivial: it's the + // first deleted bucket we see, as long as we don't find the key later + std::pair find_position(const key_type& key) const + { + size_type num_probes = 0; // how many times we've probed + const size_type bucket_count_minus_one = bucket_count() - 1; + size_type bucknum = hash(key) & bucket_count_minus_one; + size_type insert_pos = ILLEGAL_BUCKET; // where we would insert + while (1) + { // probe until something happens + if (test_empty(bucknum)) + { // bucket is empty + if (insert_pos == ILLEGAL_BUCKET) // found no prior place to insert + return std::pair(ILLEGAL_BUCKET, bucknum); + else + return std::pair(ILLEGAL_BUCKET, insert_pos); + } + else if (test_deleted(bucknum)) + { // keep searching, but mark to insert + if (insert_pos == ILLEGAL_BUCKET) + insert_pos = bucknum; + } + else if (equals(key, get_key(table[bucknum]))) + { + return std::pair(bucknum, ILLEGAL_BUCKET); + } + ++num_probes; // we're doing another probe + bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one; + assert(num_probes < bucket_count() && "Hashtable is full: an error in key_equal<> or hash<>"); + } } - // Which key marks deleted entries. - // TODO(csilvers): make a pointer, and get rid of use_deleted (benchmark!) - typename base::remove_const::type delkey; - }; + public: - // Utility functions to access the templated operators - size_type hash(const key_type& v) const { - return settings.hash(v); - } - bool equals(const key_type& a, const key_type& b) const { - return key_info.equals(a, b); - } - typename ExtractKey::result_type get_key(const_reference v) const { - return key_info.get_key(v); - } - void set_key(pointer v, const key_type& k) const { - key_info.set_key(v, k); - } + iterator find(const key_type& key) + { + if (size() == 0) + return end(); + std::pair pos = find_position(key); + if (pos.first == ILLEGAL_BUCKET) // alas, not there + return end(); + else + return iterator(this, table + pos.first, table + num_buckets, false); + } - private: - // Actual data - Settings settings; - KeyInfo key_info; + const_iterator find(const key_type& key) const + { + if (size() == 0) + return end(); + std::pair pos = find_position(key); + if (pos.first == ILLEGAL_BUCKET) // alas, not there + return end(); + else + return const_iterator(this, table + pos.first, table + num_buckets, false); + } - size_type num_deleted; // how many occupied buckets are marked deleted - size_type num_elements; - size_type num_buckets; - ValInfo val_info; // holds emptyval, and also the allocator - pointer table; + // This is a tr1 method: the bucket a given key is in, or what bucket + // it would be put in, if it were to be inserted. Shrug. + size_type bucket(const key_type& key) const + { + std::pair pos = find_position(key); + return pos.first == ILLEGAL_BUCKET ? pos.second : pos.first; + } + + // Counts how many elements have key key. For maps, it's either 0 or 1. + size_type count(const key_type& key) const + { + std::pair pos = find_position(key); + return pos.first == ILLEGAL_BUCKET ? 0 : 1; + } + + // Likewise, equal_range doesn't really make sense for us. Oh well. + std::pair equal_range(const key_type& key) + { + iterator pos = find(key); // either an iterator or end + if (pos == end()) + { + return std::pair(pos, pos); + } + else + { + const iterator startpos = pos++; + return std::pair(startpos, pos); + } + } + std::pair equal_range(const key_type& key) const + { + const_iterator pos = find(key); // either an iterator or end + if (pos == end()) + { + return std::pair(pos, pos); + } + else + { + const const_iterator startpos = pos++; + return std::pair(startpos, pos); + } + } + + // INSERTION ROUTINES + private: + // Private method used by insert_noresize and find_or_insert. + iterator insert_at(const_reference obj, size_type pos) + { + if (size() >= max_size()) + { + throw std::length_error("insert overflow"); + } + if (test_deleted(pos)) + { // just replace if it's been del. + // shrug: shouldn't need to be const. + const_iterator delpos(this, table + pos, table + num_buckets, false); + clear_deleted(delpos); + assert(num_deleted > 0); + --num_deleted; // used to be, now it isn't + } + else + { + ++num_elements; // replacing an empty bucket + } + set_value(&table[pos], obj); + return iterator(this, table + pos, table + num_buckets, false); + } + + // If you know *this is big enough to hold obj, use this routine + std::pair insert_noresize(const_reference obj) + { + // First, double-check we're not inserting delkey or emptyval + assert((!settings.use_empty() || !equals(get_key(obj), get_key(val_info.emptyval))) && + "Inserting the empty key"); + assert((!settings.use_deleted() || !equals(get_key(obj), key_info.delkey)) && "Inserting the deleted key"); + const std::pair pos = find_position(get_key(obj)); + if (pos.first != ILLEGAL_BUCKET) + { // object was already there + return std::pair(iterator(this, table + pos.first, table + num_buckets, false), + false); // false: we didn't insert + } + else + { // pos.second says where to put it + return std::pair(insert_at(obj, pos.second), true); + } + } + + // Specializations of insert(it, it) depending on the power of the iterator: + // (1) Iterator supports operator-, resize before inserting + template + void insert(ForwardIterator f, ForwardIterator l, std::forward_iterator_tag) + { + size_t dist = std::distance(f, l); + if (dist >= (std::numeric_limits::max)()) + { + throw std::length_error("insert-range overflow"); + } + resize_delta(static_cast(dist)); + for (; dist > 0; --dist, ++f) + { + insert_noresize(*f); + } + } + + // (2) Arbitrary iterator, can't tell how much to resize + template + void insert(InputIterator f, InputIterator l, std::input_iterator_tag) + { + for (; f != l; ++f) + insert(*f); + } + + public: + // This is the normal insert routine, used by the outside world + std::pair insert(const_reference obj) + { + resize_delta(1); // adding an object, grow if need be + return insert_noresize(obj); + } + + // When inserting a lot at a time, we specialize on the type of iterator + template + void insert(InputIterator f, InputIterator l) + { + // specializes on iterator type + insert(f, l, typename std::iterator_traits::iterator_category()); + } + + // DefaultValue is a functor that takes a key and returns a value_type + // representing the default value to be inserted if none is found. + template + value_type& find_or_insert(const key_type& key) + { + // First, double-check we're not inserting emptykey or delkey + assert((!settings.use_empty() || !equals(key, get_key(val_info.emptyval))) && "Inserting the empty key"); + assert((!settings.use_deleted() || !equals(key, key_info.delkey)) && "Inserting the deleted key"); + const std::pair pos = find_position(key); + DefaultValue default_value; + if (pos.first != ILLEGAL_BUCKET) + { // object was already there + return table[pos.first]; + } + else if (resize_delta(1)) + { // needed to rehash to make room + // Since we resized, we can't use pos, so recalculate where to insert. + return *insert_noresize(default_value(key)).first; + } + else + { // no need to rehash, insert right here + return *insert_at(default_value(key), pos.second); + } + } + + // DELETION ROUTINES + size_type erase(const key_type& key) + { + // First, double-check we're not trying to erase delkey or emptyval. + assert((!settings.use_empty() || !equals(key, get_key(val_info.emptyval))) && "Erasing the empty key"); + assert((!settings.use_deleted() || !equals(key, key_info.delkey)) && "Erasing the deleted key"); + const_iterator pos = find(key); // shrug: shouldn't need to be const + if (pos != end()) + { + assert(!test_deleted(pos)); // or find() shouldn't have returned it + set_deleted(pos); + ++num_deleted; + settings.set_consider_shrink(true); // will think about shrink after next insert + return 1; // because we deleted one thing + } + else + { + return 0; // because we deleted nothing + } + } + + // We return the iterator past the deleted item. + void erase(iterator pos) + { + if (pos == end()) + return; // sanity check + if (set_deleted(pos)) + { // true if object has been newly deleted + ++num_deleted; + settings.set_consider_shrink(true); // will think about shrink after next insert + } + } + + void erase(iterator f, iterator l) + { + for (; f != l; ++f) + { + if (set_deleted(f)) // should always be true + ++num_deleted; + } + settings.set_consider_shrink(true); // will think about shrink after next insert + } + + // We allow you to erase a const_iterator just like we allow you to + // erase an iterator. This is in parallel to 'delete': you can delete + // a const pointer just like a non-const pointer. The logic is that + // you can't use the object after it's erased anyway, so it doesn't matter + // if it's const or not. + void erase(const_iterator pos) + { + if (pos == end()) + return; // sanity check + if (set_deleted(pos)) + { // true if object has been newly deleted + ++num_deleted; + settings.set_consider_shrink(true); // will think about shrink after next insert + } + } + void erase(const_iterator f, const_iterator l) + { + for (; f != l; ++f) + { + if (set_deleted(f)) // should always be true + ++num_deleted; + } + settings.set_consider_shrink(true); // will think about shrink after next insert + } + + // COMPARISON + bool operator==(const dense_hashtable& ht) const + { + if (size() != ht.size()) + { + return false; + } + else if (this == &ht) + { + return true; + } + else + { + // Iterate through the elements in "this" and see if the + // corresponding element is in ht + for (const_iterator it = begin(); it != end(); ++it) + { + const_iterator it2 = ht.find(get_key(*it)); + if ((it2 == ht.end()) || (*it != *it2)) + { + return false; + } + } + return true; + } + } + bool operator!=(const dense_hashtable& ht) const { return !(*this == ht); } + + // I/O + // We support reading and writing hashtables to disk. Alas, since + // I don't know how to write a hasher or key_equal, you have to make + // sure everything but the table is the same. We compact before writing. + private: + // Every time the disk format changes, this should probably change too + typedef unsigned long MagicNumberType; + static const MagicNumberType MAGIC_NUMBER = 0x13578642; + + public: + // I/O -- this is an add-on for writing hash table to disk + // + // INPUT and OUTPUT must be either a FILE, *or* a C++ stream + // (istream, ostream, etc) *or* a class providing + // Read(void*, size_t) and Write(const void*, size_t) + // (respectively), which writes a buffer into a stream + // (which the INPUT/OUTPUT instance presumably owns). + + typedef sparsehash_internal::pod_serializer NopointerSerializer; + + // ValueSerializer: a functor. operator()(OUTPUT*, const value_type&) + template + bool serialize(ValueSerializer serializer, OUTPUT* fp) + { + squash_deleted(); // so we don't have to worry about delkey + if (!sparsehash_internal::write_bigendian_number(fp, MAGIC_NUMBER, 4)) + return false; + if (!sparsehash_internal::write_bigendian_number(fp, num_buckets, 8)) + return false; + if (!sparsehash_internal::write_bigendian_number(fp, num_elements, 8)) + return false; + // Now write a bitmap of non-empty buckets. + for (size_type i = 0; i < num_buckets; i += 8) + { + unsigned char bits = 0; + for (int bit = 0; bit < 8; ++bit) + { + if (i + bit < num_buckets && !test_empty(i + bit)) + bits |= (1 << bit); + } + if (!sparsehash_internal::write_data(fp, &bits, sizeof(bits))) + return false; + for (int bit = 0; bit < 8; ++bit) + { + if (bits & (1 << bit)) + { + if (!serializer(fp, table[i + bit])) + return false; + } + } + } + return true; + } + + // INPUT: anything we've written an overload of read_data() for. + // ValueSerializer: a functor. operator()(INPUT*, value_type*) + template + bool unserialize(ValueSerializer serializer, INPUT* fp) + { + assert(settings.use_empty() && "empty_key not set for read"); + + clear(); // just to be consistent + MagicNumberType magic_read; + if (!sparsehash_internal::read_bigendian_number(fp, &magic_read, 4)) + return false; + if (magic_read != MAGIC_NUMBER) + { + return false; + } + size_type new_num_buckets; + if (!sparsehash_internal::read_bigendian_number(fp, &new_num_buckets, 8)) + return false; + clear_to_size(new_num_buckets); + if (!sparsehash_internal::read_bigendian_number(fp, &num_elements, 8)) + return false; + + // Read the bitmap of non-empty buckets. + for (size_type i = 0; i < num_buckets; i += 8) + { + unsigned char bits; + if (!sparsehash_internal::read_data(fp, &bits, sizeof(bits))) + return false; + for (int bit = 0; bit < 8; ++bit) + { + if (i + bit < num_buckets && (bits & (1 << bit))) + { // not empty + if (!serializer(fp, &table[i + bit])) + return false; + } + } + } + return true; + } + + private: + template + class alloc_impl : public A + { + public: + typedef typename A::pointer pointer; + typedef typename A::size_type size_type; + + // Convert a normal allocator to one that has realloc_or_die() + alloc_impl(const A& a) + : A(a) + {} + + // realloc_or_die should only be used when using the default + // allocator (libc_allocator_with_realloc). + pointer realloc_or_die(pointer /*ptr*/, size_type /*n*/) + { + fprintf(stderr, + "realloc_or_die is only supported for " + "libc_allocator_with_realloc\n"); + // exit(1); + return NULL; + } + }; + + // A template specialization of alloc_impl for + // libc_allocator_with_realloc that can handle realloc_or_die. + template + class alloc_impl> : public libc_allocator_with_realloc + { + public: + typedef typename libc_allocator_with_realloc::pointer pointer; + typedef typename libc_allocator_with_realloc::size_type size_type; + + alloc_impl(const libc_allocator_with_realloc& a) + : libc_allocator_with_realloc(a) + {} + + pointer realloc_or_die(pointer ptr, size_type n) + { + pointer retval = this->reallocate(ptr, n); + if (retval == NULL) + { + fprintf(stderr, + "sparsehash: FATAL ERROR: failed to reallocate " + "%lu elements for ptr %p", + static_cast(n), + ptr); + // exit(1); + } + return retval; + } + }; + + // Package allocator with emptyval to eliminate memory needed for + // the zero-size allocator. + // If new fields are added to this class, we should add them to + // operator= and swap. + class ValInfo : public alloc_impl + { + public: + typedef typename alloc_impl::value_type value_type; + + ValInfo(const alloc_impl& a) + : alloc_impl(a) + , emptyval() + {} + ValInfo(const ValInfo& v) + : alloc_impl(v) + , emptyval(v.emptyval) + {} + + value_type emptyval; // which key marks unused entries + }; + + // Package functors with another class to eliminate memory needed for + // zero-size functors. Since ExtractKey and hasher's operator() might + // have the same function signature, they must be packaged in + // different classes. + struct Settings : sparsehash_internal::sh_hashtable_settings + { + explicit Settings(const hasher& hf) + : sparsehash_internal::sh_hashtable_settings( + hf, + HT_OCCUPANCY_PCT / 100.0f, + HT_EMPTY_PCT / 100.0f) + {} + }; + + // Packages ExtractKey and SetKey functors. + class KeyInfo : public ExtractKey, + public SetKey, + public EqualKey + { + public: + KeyInfo(const ExtractKey& ek, const SetKey& sk, const EqualKey& eq) + : ExtractKey(ek) + , SetKey(sk) + , EqualKey(eq) + {} + + // We want to return the exact same type as ExtractKey: Key or const Key& + typename ExtractKey::result_type get_key(const_reference v) const { return ExtractKey::operator()(v); } + void set_key(pointer v, const key_type& k) const { SetKey::operator()(v, k); } + bool equals(const key_type& a, const key_type& b) const { return EqualKey::operator()(a, b); } + + // Which key marks deleted entries. + // TODO(csilvers): make a pointer, and get rid of use_deleted (benchmark!) + typename base::remove_const::type delkey; + }; + + // Utility functions to access the templated operators + size_type hash(const key_type& v) const { return settings.hash(v); } + bool equals(const key_type& a, const key_type& b) const { return key_info.equals(a, b); } + typename ExtractKey::result_type get_key(const_reference v) const { return key_info.get_key(v); } + void set_key(pointer v, const key_type& k) const { key_info.set_key(v, k); } + + private: + // Actual data + Settings settings; + KeyInfo key_info; + + size_type num_deleted; // how many occupied buckets are marked deleted + size_type num_elements; + size_type num_buckets; + ValInfo val_info; // holds emptyval, and also the allocator + pointer table; }; - // We need a global swap as well -template -inline void swap(dense_hashtable &x, - dense_hashtable &y) { - x.swap(y); +template +inline void swap(dense_hashtable& x, dense_hashtable& y) +{ + x.swap(y); } #undef JUMP_ -template -const typename dense_hashtable::size_type - dense_hashtable::ILLEGAL_BUCKET; +template +const typename dense_hashtable::size_type + dense_hashtable::ILLEGAL_BUCKET; // How full we let the table get before we resize. Knuth says .8 is // good -- higher causes us to probe too much, though saves memory. @@ -1304,15 +1435,14 @@ const typename dense_hashtable::size_type // more space (a trade-off densehashtable explicitly chooses to make). // Feel free to play around with different values, though, via // max_load_factor() and/or set_resizing_parameters(). -template -const int dense_hashtable::HT_OCCUPANCY_PCT = 50; +template +const int dense_hashtable::HT_OCCUPANCY_PCT = 50; // How empty we let the table get before we resize lower. // It should be less than OCCUPANCY_PCT / 2 or we thrash resizing. -template -const int dense_hashtable::HT_EMPTY_PCT - = static_cast(0.4 * - dense_hashtable::HT_OCCUPANCY_PCT); +template +const int dense_hashtable::HT_EMPTY_PCT = + static_cast(0.4 * dense_hashtable::HT_OCCUPANCY_PCT); _END_GOOGLE_NAMESPACE_ diff --git a/deps/mapnik/sparsehash/internal/hashtable-common.h b/deps/mapnik/sparsehash/internal/hashtable-common.h index fa403e6aa..73d7c14eb 100644 --- a/deps/mapnik/sparsehash/internal/hashtable-common.h +++ b/deps/mapnik/sparsehash/internal/hashtable-common.h @@ -43,9 +43,9 @@ #include #include #include -#include // for size_t +#include // for size_t #include -#include // For length_error +#include // For length_error _START_GOOGLE_NAMESPACE_ @@ -80,15 +80,15 @@ namespace sparsehash_internal { // ----- low-level I/O for FILE* ---- template -inline bool read_data_internal(Ignored*, FILE* fp, - void* data, size_t length) { - return fread(data, length, 1, fp) == 1; +inline bool read_data_internal(Ignored*, FILE* fp, void* data, size_t length) +{ + return fread(data, length, 1, fp) == 1; } template -inline bool write_data_internal(Ignored*, FILE* fp, - const void* data, size_t length) { - return fwrite(data, length, 1, fp) == 1; +inline bool write_data_internal(Ignored*, FILE* fp, const void* data, size_t length) +{ + return fwrite(data, length, 1, fp) == 1; } // ----- low-level I/O for iostream ---- @@ -98,55 +98,57 @@ inline bool write_data_internal(Ignored*, FILE* fp, // it's only legal to delay the instantiation the way we want to if // the istream/ostream is a template type. So we jump through hoops. template -inline bool read_data_internal_for_istream(ISTREAM* fp, - void* data, size_t length) { - return fp->read(reinterpret_cast(data), length).good(); +inline bool read_data_internal_for_istream(ISTREAM* fp, void* data, size_t length) +{ + return fp->read(reinterpret_cast(data), length).good(); } template -inline bool read_data_internal(Ignored*, std::istream* fp, - void* data, size_t length) { - return read_data_internal_for_istream(fp, data, length); +inline bool read_data_internal(Ignored*, std::istream* fp, void* data, size_t length) +{ + return read_data_internal_for_istream(fp, data, length); } template -inline bool write_data_internal_for_ostream(OSTREAM* fp, - const void* data, size_t length) { - return fp->write(reinterpret_cast(data), length).good(); +inline bool write_data_internal_for_ostream(OSTREAM* fp, const void* data, size_t length) +{ + return fp->write(reinterpret_cast(data), length).good(); } template -inline bool write_data_internal(Ignored*, std::ostream* fp, - const void* data, size_t length) { - return write_data_internal_for_ostream(fp, data, length); +inline bool write_data_internal(Ignored*, std::ostream* fp, const void* data, size_t length) +{ + return write_data_internal_for_ostream(fp, data, length); } // ----- low-level I/O for custom streams ---- // The INPUT type needs to support a Read() method that takes a // buffer and a length and returns the number of bytes read. -template -inline bool read_data_internal(INPUT* fp, void*, - void* data, size_t length) { - return static_cast(fp->Read(data, length)) == length; +template +inline bool read_data_internal(INPUT* fp, void*, void* data, size_t length) +{ + return static_cast(fp->Read(data, length)) == length; } // The OUTPUT type needs to support a Write() operation that takes // a buffer and a length and returns the number of bytes written. -template -inline bool write_data_internal(OUTPUT* fp, void*, - const void* data, size_t length) { - return static_cast(fp->Write(data, length)) == length; +template +inline bool write_data_internal(OUTPUT* fp, void*, const void* data, size_t length) +{ + return static_cast(fp->Write(data, length)) == length; } // ----- low-level I/O: the public API ---- -template -inline bool read_data(INPUT* fp, void* data, size_t length) { - return read_data_internal(fp, fp, data, length); +template +inline bool read_data(INPUT* fp, void* data, size_t length) +{ + return read_data_internal(fp, fp, data, length); } -template -inline bool write_data(OUTPUT* fp, const void* data, size_t length) { - return write_data_internal(fp, fp, data, length); +template +inline bool write_data(OUTPUT* fp, const void* data, size_t length) +{ + return write_data_internal(fp, fp, data, length); } // Uses read_data() and write_data() to read/write an integer. @@ -154,26 +156,32 @@ inline bool write_data(OUTPUT* fp, const void* data, size_t length) { // from sizeof(IntType), allowing us to save on a 32-bit system // and load on a 64-bit system). Excess bytes are taken to be 0. // INPUT and OUTPUT must match legal inputs to read/write_data (above). -template -bool read_bigendian_number(INPUT* fp, IntType* value, size_t length) { - *value = 0; - unsigned char byte; - for (size_t i = 0; i < length; ++i) { - if (!read_data(fp, &byte, sizeof(byte))) return false; - *value |= static_cast(byte) << ((length - 1 - i) * 8); - } - return true; +template +bool read_bigendian_number(INPUT* fp, IntType* value, size_t length) +{ + *value = 0; + unsigned char byte; + for (size_t i = 0; i < length; ++i) + { + if (!read_data(fp, &byte, sizeof(byte))) + return false; + *value |= static_cast(byte) << ((length - 1 - i) * 8); + } + return true; } -template -bool write_bigendian_number(OUTPUT* fp, IntType value, size_t length) { - unsigned char byte; - for (size_t i = 0; i < length; ++i) { - byte = (sizeof(value) <= length-1 - i) - ? 0 : static_cast((value >> ((length-1 - i) * 8)) & 255); - if (!write_data(fp, &byte, sizeof(byte))) return false; - } - return true; +template +bool write_bigendian_number(OUTPUT* fp, IntType value, size_t length) +{ + unsigned char byte; + for (size_t i = 0; i < length; ++i) + { + byte = + (sizeof(value) <= length - 1 - i) ? 0 : static_cast((value >> ((length - 1 - i) * 8)) & 255); + if (!write_data(fp, &byte, sizeof(byte))) + return false; + } + return true; } // If your keys and values are simple enough, you can pass this @@ -181,19 +189,22 @@ bool write_bigendian_number(OUTPUT* fp, IntType value, size_t length) { // value_type is a POD type that contains no pointers. Note, // however, we don't try to normalize endianness. // This is the type used for NopointerSerializer. -template struct pod_serializer { - template - bool operator()(INPUT* fp, value_type* value) const { - return read_data(fp, value, sizeof(*value)); - } +template +struct pod_serializer +{ + template + bool operator()(INPUT* fp, value_type* value) const + { + return read_data(fp, value, sizeof(*value)); + } - template - bool operator()(OUTPUT* fp, const value_type& value) const { - return write_data(fp, &value, sizeof(value)); - } + template + bool operator()(OUTPUT* fp, const value_type& value) const + { + return write_data(fp, &value, sizeof(value)); + } }; - // Settings contains parameters for growing and shrinking the table. // It also packages zero-size functor (ie. hasher). // @@ -206,165 +217,136 @@ template struct pod_serializer { // for sure that the hash is the identity hash. If it's not, this // is needless work (and possibly, though not likely, harmful). -template -class sh_hashtable_settings : public HashFunc { - public: - typedef Key key_type; - typedef HashFunc hasher; - typedef SizeType size_type; +template +class sh_hashtable_settings : public HashFunc +{ + public: + typedef Key key_type; + typedef HashFunc hasher; + typedef SizeType size_type; - public: - sh_hashtable_settings(const hasher& hf, - const float ht_occupancy_flt, - const float ht_empty_flt) - : hasher(hf), - enlarge_threshold_(0), - shrink_threshold_(0), - consider_shrink_(false), - use_empty_(false), - use_deleted_(false), - num_ht_copies_(0) { - set_enlarge_factor(ht_occupancy_flt); - set_shrink_factor(ht_empty_flt); - } - - size_type hash(const key_type& v) const { - // We munge the hash value when we don't trust hasher::operator(). - return hash_munger::MungedHash(hasher::operator()(v)); - } - - float enlarge_factor() const { - return enlarge_factor_; - } - void set_enlarge_factor(float f) { - enlarge_factor_ = f; - } - float shrink_factor() const { - return shrink_factor_; - } - void set_shrink_factor(float f) { - shrink_factor_ = f; - } - - size_type enlarge_threshold() const { - return enlarge_threshold_; - } - void set_enlarge_threshold(size_type t) { - enlarge_threshold_ = t; - } - size_type shrink_threshold() const { - return shrink_threshold_; - } - void set_shrink_threshold(size_type t) { - shrink_threshold_ = t; - } - - size_type enlarge_size(size_type x) const { - return static_cast(x * enlarge_factor_); - } - size_type shrink_size(size_type x) const { - return static_cast(x * shrink_factor_); - } - - bool consider_shrink() const { - return consider_shrink_; - } - void set_consider_shrink(bool t) { - consider_shrink_ = t; - } - - bool use_empty() const { - return use_empty_; - } - void set_use_empty(bool t) { - use_empty_ = t; - } - - bool use_deleted() const { - return use_deleted_; - } - void set_use_deleted(bool t) { - use_deleted_ = t; - } - - size_type num_ht_copies() const { - return static_cast(num_ht_copies_); - } - void inc_num_ht_copies() { - ++num_ht_copies_; - } - - // Reset the enlarge and shrink thresholds - void reset_thresholds(size_type num_buckets) { - set_enlarge_threshold(enlarge_size(num_buckets)); - set_shrink_threshold(shrink_size(num_buckets)); - // whatever caused us to reset already considered - set_consider_shrink(false); - } - - // Caller is resposible for calling reset_threshold right after - // set_resizing_parameters. - void set_resizing_parameters(float shrink, float grow) { - assert(shrink >= 0.0); - assert(grow <= 1.0); - if (shrink > grow/2.0f) - shrink = grow / 2.0f; // otherwise we thrash hashtable size - set_shrink_factor(shrink); - set_enlarge_factor(grow); - } - - // This is the smallest size a hashtable can be without being too crowded - // If you like, you can give a min #buckets as well as a min #elts - size_type min_buckets(size_type num_elts, size_type min_buckets_wanted) { - float enlarge = enlarge_factor(); - size_type sz = HT_MIN_BUCKETS; // min buckets allowed - while ( sz < min_buckets_wanted || - num_elts >= static_cast(sz * enlarge) ) { - // This just prevents overflowing size_type, since sz can exceed - // max_size() here. - if (static_cast(sz * 2) < sz) { - throw std::length_error("resize overflow"); // protect against overflow - } - sz *= 2; + public: + sh_hashtable_settings(const hasher& hf, const float ht_occupancy_flt, const float ht_empty_flt) + : hasher(hf) + , enlarge_threshold_(0) + , shrink_threshold_(0) + , consider_shrink_(false) + , use_empty_(false) + , use_deleted_(false) + , num_ht_copies_(0) + { + set_enlarge_factor(ht_occupancy_flt); + set_shrink_factor(ht_empty_flt); } - return sz; - } - private: - template class hash_munger { - public: - static size_t MungedHash(size_t hash) { - return hash; + size_type hash(const key_type& v) const + { + // We munge the hash value when we don't trust hasher::operator(). + return hash_munger::MungedHash(hasher::operator()(v)); } - }; - // This matches when the hashtable key is a pointer. - template class hash_munger { - public: - static size_t MungedHash(size_t hash) { - // TODO(csilvers): consider rotating instead: - // static const int shift = (sizeof(void *) == 4) ? 2 : 3; - // return (hash << (sizeof(hash) * 8) - shift)) | (hash >> shift); - // This matters if we ever change sparse/dense_hash_* to compare - // hashes before comparing actual values. It's speedy on x86. - return hash / sizeof(void*); // get rid of known-0 bits - } - }; - size_type enlarge_threshold_; // table.size() * enlarge_factor - size_type shrink_threshold_; // table.size() * shrink_factor - float enlarge_factor_; // how full before resize - float shrink_factor_; // how empty before resize - // consider_shrink=true if we should try to shrink before next insert - bool consider_shrink_; - bool use_empty_; // used only by densehashtable, not sparsehashtable - bool use_deleted_; // false until delkey has been set - // num_ht_copies is a counter incremented every Copy/Move - unsigned int num_ht_copies_; + float enlarge_factor() const { return enlarge_factor_; } + void set_enlarge_factor(float f) { enlarge_factor_ = f; } + float shrink_factor() const { return shrink_factor_; } + void set_shrink_factor(float f) { shrink_factor_ = f; } + + size_type enlarge_threshold() const { return enlarge_threshold_; } + void set_enlarge_threshold(size_type t) { enlarge_threshold_ = t; } + size_type shrink_threshold() const { return shrink_threshold_; } + void set_shrink_threshold(size_type t) { shrink_threshold_ = t; } + + size_type enlarge_size(size_type x) const { return static_cast(x * enlarge_factor_); } + size_type shrink_size(size_type x) const { return static_cast(x * shrink_factor_); } + + bool consider_shrink() const { return consider_shrink_; } + void set_consider_shrink(bool t) { consider_shrink_ = t; } + + bool use_empty() const { return use_empty_; } + void set_use_empty(bool t) { use_empty_ = t; } + + bool use_deleted() const { return use_deleted_; } + void set_use_deleted(bool t) { use_deleted_ = t; } + + size_type num_ht_copies() const { return static_cast(num_ht_copies_); } + void inc_num_ht_copies() { ++num_ht_copies_; } + + // Reset the enlarge and shrink thresholds + void reset_thresholds(size_type num_buckets) + { + set_enlarge_threshold(enlarge_size(num_buckets)); + set_shrink_threshold(shrink_size(num_buckets)); + // whatever caused us to reset already considered + set_consider_shrink(false); + } + + // Caller is resposible for calling reset_threshold right after + // set_resizing_parameters. + void set_resizing_parameters(float shrink, float grow) + { + assert(shrink >= 0.0); + assert(grow <= 1.0); + if (shrink > grow / 2.0f) + shrink = grow / 2.0f; // otherwise we thrash hashtable size + set_shrink_factor(shrink); + set_enlarge_factor(grow); + } + + // This is the smallest size a hashtable can be without being too crowded + // If you like, you can give a min #buckets as well as a min #elts + size_type min_buckets(size_type num_elts, size_type min_buckets_wanted) + { + float enlarge = enlarge_factor(); + size_type sz = HT_MIN_BUCKETS; // min buckets allowed + while (sz < min_buckets_wanted || num_elts >= static_cast(sz * enlarge)) + { + // This just prevents overflowing size_type, since sz can exceed + // max_size() here. + if (static_cast(sz * 2) < sz) + { + throw std::length_error("resize overflow"); // protect against overflow + } + sz *= 2; + } + return sz; + } + + private: + template + class hash_munger + { + public: + static size_t MungedHash(size_t hash) { return hash; } + }; + // This matches when the hashtable key is a pointer. + template + class hash_munger + { + public: + static size_t MungedHash(size_t hash) + { + // TODO(csilvers): consider rotating instead: + // static const int shift = (sizeof(void *) == 4) ? 2 : 3; + // return (hash << (sizeof(hash) * 8) - shift)) | (hash >> shift); + // This matters if we ever change sparse/dense_hash_* to compare + // hashes before comparing actual values. It's speedy on x86. + return hash / sizeof(void*); // get rid of known-0 bits + } + }; + + size_type enlarge_threshold_; // table.size() * enlarge_factor + size_type shrink_threshold_; // table.size() * shrink_factor + float enlarge_factor_; // how full before resize + float shrink_factor_; // how empty before resize + // consider_shrink=true if we should try to shrink before next insert + bool consider_shrink_; + bool use_empty_; // used only by densehashtable, not sparsehashtable + bool use_deleted_; // false until delkey has been set + // num_ht_copies is a counter incremented every Copy/Move + unsigned int num_ht_copies_; }; -} // namespace sparsehash_internal +} // namespace sparsehash_internal _END_GOOGLE_NAMESPACE_ -#endif // UTIL_GTL_HASHTABLE_COMMON_H_ +#endif // UTIL_GTL_HASHTABLE_COMMON_H_ diff --git a/deps/mapnik/sparsehash/internal/libc_allocator_with_realloc.h b/deps/mapnik/sparsehash/internal/libc_allocator_with_realloc.h index 3689701b9..dcf095dae 100644 --- a/deps/mapnik/sparsehash/internal/libc_allocator_with_realloc.h +++ b/deps/mapnik/sparsehash/internal/libc_allocator_with_realloc.h @@ -33,87 +33,82 @@ #define UTIL_GTL_LIBC_ALLOCATOR_WITH_REALLOC_H_ #include -#include // for malloc/realloc/free -#include // for ptrdiff_t -#include // for placement new +#include // for malloc/realloc/free +#include // for ptrdiff_t +#include // for placement new _START_GOOGLE_NAMESPACE_ template -class libc_allocator_with_realloc { - public: - typedef T value_type; - typedef size_t size_type; - typedef ptrdiff_t difference_type; +class libc_allocator_with_realloc +{ + public: + typedef T value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; - libc_allocator_with_realloc() {} - libc_allocator_with_realloc(const libc_allocator_with_realloc&) {} - ~libc_allocator_with_realloc() {} + libc_allocator_with_realloc() {} + libc_allocator_with_realloc(const libc_allocator_with_realloc&) {} + ~libc_allocator_with_realloc() {} - pointer address(reference r) const { return &r; } - const_pointer address(const_reference r) const { return &r; } + pointer address(reference r) const { return &r; } + const_pointer address(const_reference r) const { return &r; } - pointer allocate(size_type n, const_pointer = 0) { - return static_cast(malloc(n * sizeof(value_type))); - } - void deallocate(pointer p, size_type) { - free(p); - } - pointer reallocate(pointer p, size_type n) { - return static_cast(realloc(p, n * sizeof(value_type))); - } + pointer allocate(size_type n, const_pointer = 0) { return static_cast(malloc(n * sizeof(value_type))); } + void deallocate(pointer p, size_type) { free(p); } + pointer reallocate(pointer p, size_type n) { return static_cast(realloc(p, n * sizeof(value_type))); } - size_type max_size() const { - return static_cast(-1) / sizeof(value_type); - } + size_type max_size() const { return static_cast(-1) / sizeof(value_type); } - void construct(pointer p, const value_type& val) { - new(p) value_type(val); - } - void destroy(pointer p) { p->~value_type(); } + void construct(pointer p, const value_type& val) { new (p) value_type(val); } + void destroy(pointer p) { p->~value_type(); } - template - libc_allocator_with_realloc(const libc_allocator_with_realloc&) {} + template + libc_allocator_with_realloc(const libc_allocator_with_realloc&) + {} - template - struct rebind { - typedef libc_allocator_with_realloc other; - }; + template + struct rebind + { + typedef libc_allocator_with_realloc other; + }; }; // libc_allocator_with_realloc specialization. template<> -class libc_allocator_with_realloc { - public: - typedef void value_type; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef void* pointer; - typedef const void* const_pointer; +class libc_allocator_with_realloc +{ + public: + typedef void value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef void* pointer; + typedef const void* const_pointer; - template - struct rebind { - typedef libc_allocator_with_realloc other; - }; + template + struct rebind + { + typedef libc_allocator_with_realloc other; + }; }; template -inline bool operator==(const libc_allocator_with_realloc&, - const libc_allocator_with_realloc&) { - return true; +inline bool operator==(const libc_allocator_with_realloc&, const libc_allocator_with_realloc&) +{ + return true; } template -inline bool operator!=(const libc_allocator_with_realloc&, - const libc_allocator_with_realloc&) { - return false; +inline bool operator!=(const libc_allocator_with_realloc&, const libc_allocator_with_realloc&) +{ + return false; } _END_GOOGLE_NAMESPACE_ -#endif // UTIL_GTL_LIBC_ALLOCATOR_WITH_REALLOC_H_ +#endif // UTIL_GTL_LIBC_ALLOCATOR_WITH_REALLOC_H_ diff --git a/deps/mapnik/sparsehash/template_util.h b/deps/mapnik/sparsehash/template_util.h index d6f7fa64e..35b4c798e 100644 --- a/deps/mapnik/sparsehash/template_util.h +++ b/deps/mapnik/sparsehash/template_util.h @@ -56,14 +56,16 @@ _START_GOOGLE_NAMESPACE_ // sizeof(big_) typedef char small_; -struct big_ { - char dummy[2]; +struct big_ +{ + char dummy[2]; }; // Identity metafunction. -template -struct identity_ { - typedef T type; +template +struct identity_ +{ + typedef T type; }; // integral_constant, defined in tr1, is a wrapper for an integer @@ -72,63 +74,64 @@ struct identity_ { // general integer_constant for compatibility with tr1. template -struct integral_constant { - static const T value = v; - typedef T value_type; - typedef integral_constant type; +struct integral_constant +{ + static const T value = v; + typedef T value_type; + typedef integral_constant type; }; -template const T integral_constant::value; - +template +const T integral_constant::value; // Abbreviations: true_type and false_type are structs that represent boolean // true and false values. Also define the boost::mpl versions of those names, // true_ and false_. -typedef integral_constant true_type; +typedef integral_constant true_type; typedef integral_constant false_type; -typedef true_type true_; +typedef true_type true_; typedef false_type false_; // if_ is a templatized conditional statement. // if_ is a compile time evaluation of cond. // if_<>::type contains A if cond is true, B otherwise. template -struct if_{ - typedef A type; +struct if_ +{ + typedef A type; }; template -struct if_ { - typedef B type; +struct if_ +{ + typedef B type; }; - // type_equals_ is a template type comparator, similar to Loki IsSameType. // type_equals_::value is true iff "A" is the same type as "B". // // New code should prefer base::is_same, defined in base/type_traits.h. // It is functionally identical, but is_same is the standard spelling. template -struct type_equals_ : public false_ { -}; +struct type_equals_ : public false_ +{}; template -struct type_equals_ : public true_ { -}; +struct type_equals_ : public true_ +{}; // and_ is a template && operator. // and_::value evaluates "A::value && B::value". template -struct and_ : public integral_constant { -}; +struct and_ : public integral_constant +{}; // or_ is a template || operator. // or_::value evaluates "A::value || B::value". template -struct or_ : public integral_constant { -}; - +struct or_ : public integral_constant +{}; _END_GOOGLE_NAMESPACE_ -#endif // BASE_TEMPLATE_UTIL_H_ +#endif // BASE_TEMPLATE_UTIL_H_ diff --git a/deps/mapnik/sparsehash/type_traits.h b/deps/mapnik/sparsehash/type_traits.h index c11904c82..d93004219 100644 --- a/deps/mapnik/sparsehash/type_traits.h +++ b/deps/mapnik/sparsehash/type_traits.h @@ -58,106 +58,188 @@ #define BASE_TYPE_TRAITS_H_ #include -#include // For pair +#include // For pair -#include // For true_type and false_type +#include // For true_type and false_type _START_GOOGLE_NAMESPACE_ -template struct is_integral; -template struct is_floating_point; -template struct is_pointer; +template +struct is_integral; +template +struct is_floating_point; +template +struct is_pointer; // MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least) #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) // is_enum uses is_convertible, which is not available on MSVC. -template struct is_enum; +template +struct is_enum; #endif -template struct is_reference; -template struct is_pod; -template struct has_trivial_constructor; -template struct has_trivial_copy; -template struct has_trivial_assign; -template struct has_trivial_destructor; -template struct remove_const; -template struct remove_volatile; -template struct remove_cv; -template struct remove_reference; -template struct add_reference; -template struct remove_pointer; -template struct is_same; +template +struct is_reference; +template +struct is_pod; +template +struct has_trivial_constructor; +template +struct has_trivial_copy; +template +struct has_trivial_assign; +template +struct has_trivial_destructor; +template +struct remove_const; +template +struct remove_volatile; +template +struct remove_cv; +template +struct remove_reference; +template +struct add_reference; +template +struct remove_pointer; +template +struct is_same; #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) -template struct is_convertible; +template +struct is_convertible; #endif // is_integral is false except for the built-in integer types. A // cv-qualified type is integral if and only if the underlying type is. -template struct is_integral : false_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; +template +struct is_integral : false_type +{}; +template<> +struct is_integral : true_type +{}; +template<> +struct is_integral : true_type +{}; +template<> +struct is_integral : true_type +{}; +template<> +struct is_integral : true_type +{}; #if defined(_MSC_VER) // wchar_t is not by default a distinct type from unsigned short in // Microsoft C. // See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx -template<> struct is_integral<__wchar_t> : true_type { }; +template<> +struct is_integral<__wchar_t> : true_type +{}; #else -template<> struct is_integral : true_type { }; +template<> +struct is_integral : true_type +{}; #endif -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; +template<> +struct is_integral : true_type +{}; +template<> +struct is_integral : true_type +{}; +template<> +struct is_integral : true_type +{}; +template<> +struct is_integral : true_type +{}; +template<> +struct is_integral : true_type +{}; +template<> +struct is_integral : true_type +{}; #ifdef HAVE_LONG_LONG -template<> struct is_integral : true_type { }; -template<> struct is_integral : true_type { }; +template<> +struct is_integral : true_type +{}; +template<> +struct is_integral : true_type +{}; #endif -template struct is_integral : is_integral { }; -template struct is_integral : is_integral { }; -template struct is_integral : is_integral { }; +template +struct is_integral : is_integral +{}; +template +struct is_integral : is_integral +{}; +template +struct is_integral : is_integral +{}; // is_floating_point is false except for the built-in floating-point types. // A cv-qualified type is integral if and only if the underlying type is. -template struct is_floating_point : false_type { }; -template<> struct is_floating_point : true_type { }; -template<> struct is_floating_point : true_type { }; -template<> struct is_floating_point : true_type { }; -template struct is_floating_point - : is_floating_point { }; -template struct is_floating_point - : is_floating_point { }; -template struct is_floating_point - : is_floating_point { }; +template +struct is_floating_point : false_type +{}; +template<> +struct is_floating_point : true_type +{}; +template<> +struct is_floating_point : true_type +{}; +template<> +struct is_floating_point : true_type +{}; +template +struct is_floating_point : is_floating_point +{}; +template +struct is_floating_point : is_floating_point +{}; +template +struct is_floating_point : is_floating_point +{}; // is_pointer is false except for pointer types. A cv-qualified type (e.g. // "int* const", as opposed to "int const*") is cv-qualified if and only if // the underlying type is. -template struct is_pointer : false_type { }; -template struct is_pointer : true_type { }; -template struct is_pointer : is_pointer { }; -template struct is_pointer : is_pointer { }; -template struct is_pointer : is_pointer { }; +template +struct is_pointer : false_type +{}; +template +struct is_pointer : true_type +{}; +template +struct is_pointer : is_pointer +{}; +template +struct is_pointer : is_pointer +{}; +template +struct is_pointer : is_pointer +{}; #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) namespace internal { -template struct is_class_or_union { - template static small_ tester(void (U::*)()); - template static big_ tester(...); - static const bool value = sizeof(tester(0)) == sizeof(small_); +template +struct is_class_or_union +{ + template + static small_ tester(void (U::*)()); + template + static big_ tester(...); + static const bool value = sizeof(tester(0)) == sizeof(small_); }; // is_convertible chokes if the first argument is an array. That's why // we use add_reference here. -template struct is_enum_impl - : is_convertible::type, int> { }; +template +struct is_enum_impl : is_convertible::type, int> +{}; -template struct is_enum_impl : false_type { }; +template +struct is_enum_impl : false_type +{}; -} // namespace internal +} // namespace internal // Specified by TR1 [4.5.1] primary type categories. @@ -174,127 +256,212 @@ template struct is_enum_impl : false_type { }; // Is-convertible-to-int check is done only if all other checks pass, // because it can't be used with some types (e.g. void or classes with // inaccessible conversion operators). -template struct is_enum - : internal::is_enum_impl< - is_same::value || - is_integral::value || - is_floating_point::value || - is_reference::value || - internal::is_class_or_union::value, - T> { }; +template +struct is_enum + : internal::is_enum_impl::value || is_integral::value || is_floating_point::value || + is_reference::value || internal::is_class_or_union::value, + T> +{}; -template struct is_enum : is_enum { }; -template struct is_enum : is_enum { }; -template struct is_enum : is_enum { }; +template +struct is_enum : is_enum +{}; +template +struct is_enum : is_enum +{}; +template +struct is_enum : is_enum +{}; #endif // is_reference is false except for reference types. -template struct is_reference : false_type {}; -template struct is_reference : true_type {}; - +template +struct is_reference : false_type +{}; +template +struct is_reference : true_type +{}; // We can't get is_pod right without compiler help, so fail conservatively. // We will assume it's false except for arithmetic types, enumerations, // pointers and cv-qualified versions thereof. Note that std::pair // is not a POD even if T and U are PODs. -template struct is_pod - : integral_constant::value || - is_floating_point::value || +template +struct is_pod : integral_constant::value || is_floating_point::value || #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) - // is_enum is not available on MSVC. - is_enum::value || + // is_enum is not available on MSVC. + is_enum::value || #endif - is_pointer::value)> { }; -template struct is_pod : is_pod { }; -template struct is_pod : is_pod { }; -template struct is_pod : is_pod { }; - + is_pointer::value)> +{}; +template +struct is_pod : is_pod +{}; +template +struct is_pod : is_pod +{}; +template +struct is_pod : is_pod +{}; // We can't get has_trivial_constructor right without compiler help, so // fail conservatively. We will assume it's false except for: (1) types // for which is_pod is true. (2) std::pair of types with trivial // constructors. (3) array of a type with a trivial constructor. // (4) const versions thereof. -template struct has_trivial_constructor : is_pod { }; -template struct has_trivial_constructor > - : integral_constant::value && - has_trivial_constructor::value)> { }; -template struct has_trivial_constructor - : has_trivial_constructor { }; -template struct has_trivial_constructor - : has_trivial_constructor { }; +template +struct has_trivial_constructor : is_pod +{}; +template +struct has_trivial_constructor> + : integral_constant::value && has_trivial_constructor::value)> +{}; +template +struct has_trivial_constructor : has_trivial_constructor +{}; +template +struct has_trivial_constructor : has_trivial_constructor +{}; // We can't get has_trivial_copy right without compiler help, so fail // conservatively. We will assume it's false except for: (1) types // for which is_pod is true. (2) std::pair of types with trivial copy // constructors. (3) array of a type with a trivial copy constructor. // (4) const versions thereof. -template struct has_trivial_copy : is_pod { }; -template struct has_trivial_copy > - : integral_constant::value && - has_trivial_copy::value)> { }; -template struct has_trivial_copy - : has_trivial_copy { }; -template struct has_trivial_copy : has_trivial_copy { }; +template +struct has_trivial_copy : is_pod +{}; +template +struct has_trivial_copy> + : integral_constant::value && has_trivial_copy::value)> +{}; +template +struct has_trivial_copy : has_trivial_copy +{}; +template +struct has_trivial_copy : has_trivial_copy +{}; // We can't get has_trivial_assign right without compiler help, so fail // conservatively. We will assume it's false except for: (1) types // for which is_pod is true. (2) std::pair of types with trivial copy // constructors. (3) array of a type with a trivial assign constructor. -template struct has_trivial_assign : is_pod { }; -template struct has_trivial_assign > - : integral_constant::value && - has_trivial_assign::value)> { }; -template struct has_trivial_assign - : has_trivial_assign { }; +template +struct has_trivial_assign : is_pod +{}; +template +struct has_trivial_assign> + : integral_constant::value && has_trivial_assign::value)> +{}; +template +struct has_trivial_assign : has_trivial_assign +{}; // We can't get has_trivial_destructor right without compiler help, so // fail conservatively. We will assume it's false except for: (1) types // for which is_pod is true. (2) std::pair of types with trivial // destructors. (3) array of a type with a trivial destructor. // (4) const versions thereof. -template struct has_trivial_destructor : is_pod { }; -template struct has_trivial_destructor > - : integral_constant::value && - has_trivial_destructor::value)> { }; -template struct has_trivial_destructor - : has_trivial_destructor { }; -template struct has_trivial_destructor - : has_trivial_destructor { }; +template +struct has_trivial_destructor : is_pod +{}; +template +struct has_trivial_destructor> + : integral_constant::value && has_trivial_destructor::value)> +{}; +template +struct has_trivial_destructor : has_trivial_destructor +{}; +template +struct has_trivial_destructor : has_trivial_destructor +{}; // Specified by TR1 [4.7.1] -template struct remove_const { typedef T type; }; -template struct remove_const { typedef T type; }; -template struct remove_volatile { typedef T type; }; -template struct remove_volatile { typedef T type; }; -template struct remove_cv { - typedef typename remove_const::type>::type type; +template +struct remove_const +{ + typedef T type; +}; +template +struct remove_const +{ + typedef T type; +}; +template +struct remove_volatile +{ + typedef T type; +}; +template +struct remove_volatile +{ + typedef T type; +}; +template +struct remove_cv +{ + typedef typename remove_const::type>::type type; }; - // Specified by TR1 [4.7.2] Reference modifications. -template struct remove_reference { typedef T type; }; -template struct remove_reference { typedef T type; }; +template +struct remove_reference +{ + typedef T type; +}; +template +struct remove_reference +{ + typedef T type; +}; -template struct add_reference { typedef T& type; }; -template struct add_reference { typedef T& type; }; +template +struct add_reference +{ + typedef T& type; +}; +template +struct add_reference +{ + typedef T& type; +}; // Specified by TR1 [4.7.4] Pointer modifications. -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { typedef T type; }; -template struct remove_pointer { - typedef T type; }; +template +struct remove_pointer +{ + typedef T type; +}; +template +struct remove_pointer +{ + typedef T type; +}; +template +struct remove_pointer +{ + typedef T type; +}; +template +struct remove_pointer +{ + typedef T type; +}; +template +struct remove_pointer +{ + typedef T type; +}; // Specified by TR1 [4.6] Relationships between types -template struct is_same : public false_type { }; -template struct is_same : public true_type { }; +template +struct is_same : public false_type +{}; +template +struct is_same : public true_type +{}; // Specified by TR1 [4.6] Relationships between types #if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3) @@ -309,22 +476,22 @@ namespace internal { // had called it with an argument of type From. See Alexandrescu's // _Modern C++ Design_ for more details on this sort of trick. -template -struct ConvertHelper { - static small_ Test(To); - static big_ Test(...); - static From Create(); +template +struct ConvertHelper +{ + static small_ Test(To); + static big_ Test(...); + static From Create(); }; -} // namespace internal +} // namespace internal // Inherits from true_type if From is convertible to To, false_type otherwise. -template +template struct is_convertible : integral_constant::Test( - internal::ConvertHelper::Create())) - == sizeof(small_)> { -}; + sizeof(internal::ConvertHelper::Test(internal::ConvertHelper::Create())) == + sizeof(small_)> +{}; #endif _END_GOOGLE_NAMESPACE_ @@ -333,10 +500,10 @@ _END_GOOGLE_NAMESPACE_ // these types are PODs, for human use. They may be made more contentful // later. The typedef is just to make it legal to put a semicolon after // these macros. -#define DECLARE_POD(TypeName) typedef int Dummy_Type_For_DECLARE_POD +#define DECLARE_POD(TypeName) typedef int Dummy_Type_For_DECLARE_POD #define DECLARE_NESTED_POD(TypeName) DECLARE_POD(TypeName) -#define PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(TemplateName) \ +#define PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(TemplateName) \ typedef int Dummy_Type_For_PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT #define ENFORCE_POD(TypeName) typedef int Dummy_Type_For_ENFORCE_POD -#endif // BASE_TYPE_TRAITS_H_ +#endif // BASE_TYPE_TRAITS_H_ diff --git a/include/mapnik/debug.hpp b/include/mapnik/debug.hpp index 33f0f1ff1..161bb8298 100644 --- a/include/mapnik/debug.hpp +++ b/include/mapnik/debug.hpp @@ -96,7 +96,10 @@ class MAPNIK_DECL logger : public singleton, } // format - static std::string const& get_format() { return format_; } + static std::string const& get_format() + { + return format_; + } static void set_format(std::string const& format) { @@ -208,7 +211,10 @@ class base_log : public util::noncopyable private: #ifdef MAPNIK_LOG - inline bool check_severity() { return Severity >= logger::get_object_severity(object_name_); } + inline bool check_severity() + { + return Severity >= logger::get_object_severity(object_name_); + } typename output_policy::stream_buffer streambuf_; std::string object_name_; diff --git a/include/mapnik/hextree.hpp b/include/mapnik/hextree.hpp index 7a0f160cc..06aa63f06 100644 --- a/include/mapnik/hextree.hpp +++ b/include/mapnik/hextree.hpp @@ -152,7 +152,10 @@ class hextree : private util::noncopyable ~hextree() {} - void setMaxColors(unsigned max_colors) { max_colors_ = max_colors; } + void setMaxColors(unsigned max_colors) + { + max_colors_ = max_colors; + } void setGamma(double g) { @@ -163,9 +166,15 @@ class hextree : private util::noncopyable } } - void setTransMode(unsigned t) { trans_mode_ = t; } + void setTransMode(unsigned t) + { + trans_mode_ = t; + } - transparency_mode_t getTransMode() const { return trans_mode_; } + transparency_mode_t getTransMode() const + { + return trans_mode_; + } // process alpha value based on trans_mode_ std::uint8_t preprocessAlpha(std::uint8_t a) const diff --git a/include/mapnik/offset_converter.hpp b/include/mapnik/offset_converter.hpp index 610a0c1b4..938f119d3 100644 --- a/include/mapnik/offset_converter.hpp +++ b/include/mapnik/offset_converter.hpp @@ -640,7 +640,10 @@ struct offset_converter return cur_.cmd; } - void push_vertex(vertex2d const& v) { vertices_.push_back(v); } + void push_vertex(vertex2d const& v) + { + vertices_.push_back(v); + } Geometry& geom_; double offset_; diff --git a/include/mapnik/svg/svg_renderer_agg.hpp b/include/mapnik/svg/svg_renderer_agg.hpp index 671d11bb9..89701063b 100644 --- a/include/mapnik/svg/svg_renderer_agg.hpp +++ b/include/mapnik/svg/svg_renderer_agg.hpp @@ -73,10 +73,10 @@ class linear_gradient_from_segment { public: linear_gradient_from_segment(double x1, double y1, double x2, double y2) - : x1_(x1 * agg::gradient_subpixel_scale) - , y1_(y1 * agg::gradient_subpixel_scale) - , x2_(x2 * agg::gradient_subpixel_scale) - , y2_(y2 * agg::gradient_subpixel_scale) + : x1_(x1 * static_cast(agg::gradient_subpixel_scale)) + , y1_(y1 * static_cast(agg::gradient_subpixel_scale)) + , x2_(x2 * static_cast(agg::gradient_subpixel_scale)) + , y2_(y2 * static_cast(agg::gradient_subpixel_scale)) { double dx = x2_ - x1_; double dy = y2_ - y1_; @@ -492,8 +492,14 @@ class renderer_agg : util::noncopyable } #endif - inline VertexSource& source() const { return source_; } - inline AttributeSource const& attributes() const { return attributes_; } + inline VertexSource& source() const + { + return source_; + } + inline AttributeSource const& attributes() const + { + return attributes_; + } private: diff --git a/include/mapnik/tiff_io.hpp b/include/mapnik/tiff_io.hpp index 6e818f34f..1d09f84ed 100644 --- a/include/mapnik/tiff_io.hpp +++ b/include/mapnik/tiff_io.hpp @@ -207,12 +207,12 @@ struct tag_setter TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 4); if (data.get_premultiplied()) { - uint16 extras[] = {EXTRASAMPLE_ASSOCALPHA}; + std::uint16_t extras[] = {EXTRASAMPLE_ASSOCALPHA}; TIFFSetField(output_, TIFFTAG_EXTRASAMPLES, 1, extras); } else { - uint16 extras[] = {EXTRASAMPLE_UNASSALPHA}; + std::uint16_t extras[] = {EXTRASAMPLE_UNASSALPHA}; TIFFSetField(output_, TIFFTAG_EXTRASAMPLES, 1, extras); } if (config_.compression == COMPRESSION_DEFLATE || config_.compression == COMPRESSION_ADOBE_DEFLATE || diff --git a/include/mapnik/util/file_io.hpp b/include/mapnik/util/file_io.hpp index 3648dcd87..e29cadfa0 100644 --- a/include/mapnik/util/file_io.hpp +++ b/include/mapnik/util/file_io.hpp @@ -60,13 +60,25 @@ class file : public util::noncopyable } } - inline bool is_open() const { return file_ ? true : false; } + inline bool is_open() const + { + return file_ ? true : false; + } - explicit operator bool() const { return this->is_open(); } + explicit operator bool() const + { + return this->is_open(); + } - inline std::FILE* get() const { return file_.get(); } + inline std::FILE* get() const + { + return file_.get(); + } - inline std::size_t size() const { return size_; } + inline std::size_t size() const + { + return size_; + } inline data_type data() const { diff --git a/include/mapnik/util/singleton.hpp b/include/mapnik/util/singleton.hpp index bfc86913f..897fcee69 100644 --- a/include/mapnik/util/singleton.hpp +++ b/include/mapnik/util/singleton.hpp @@ -77,7 +77,10 @@ class singleton singleton(const singleton& rhs); singleton& operator=(const singleton&); - static void onDeadReference() { throw std::runtime_error("dead reference!"); } + static void onDeadReference() + { + throw std::runtime_error("dead reference!"); + } static void DestroySingleton() { diff --git a/plugins/input/CMakeLists.txt b/plugins/input/CMakeLists.txt index dbc06c835..878b7ff65 100644 --- a/plugins/input/CMakeLists.txt +++ b/plugins/input/CMakeLists.txt @@ -89,7 +89,7 @@ if(BUILD_SHARED_PLUGINS AND WIN32) file(COPY ${m_deps} DESTINATION "@MAPNIK_OUTPUT_DIR@") ]] m_copy_dlls_str @ONLY ) - file (GENERATE OUTPUT "copy_dlls_$.cmake" + file (GENERATE OUTPUT "copy_dlls_$.cmake" CONTENT "${m_copy_dlls_str}" ) add_custom_target(copy_plugin_dependencies ALL diff --git a/plugins/input/gdal/CMakeLists.txt b/plugins/input/gdal/CMakeLists.txt index c6ae1f633..2ef39fb14 100644 --- a/plugins/input/gdal/CMakeLists.txt +++ b/plugins/input/gdal/CMakeLists.txt @@ -11,4 +11,3 @@ target_link_libraries(input-gdal ${_plugin_visibility} mapnik::datasource-base ${GDAL_LIBRARIES} ) - diff --git a/plugins/input/geobuf/CMakeLists.txt b/plugins/input/geobuf/CMakeLists.txt index 4bd67c6e4..a467ec4e7 100644 --- a/plugins/input/geobuf/CMakeLists.txt +++ b/plugins/input/geobuf/CMakeLists.txt @@ -8,4 +8,3 @@ target_link_libraries(input-geobuf ${_plugin_visibility} mapnik::mapnik mapnik::datasource-base ) - diff --git a/plugins/input/ogr/ogr_layer_ptr.hpp b/plugins/input/ogr/ogr_layer_ptr.hpp index eab1a0774..a0ee45a55 100644 --- a/plugins/input/ogr/ogr_layer_ptr.hpp +++ b/plugins/input/ogr/ogr_layer_ptr.hpp @@ -144,11 +144,20 @@ class ogr_layer_ptr #endif } - std::string const& layer_name() const { return layer_name_; } + std::string const& layer_name() const + { + return layer_name_; + } - OGRLayer* layer() const { return layer_; } + OGRLayer* layer() const + { + return layer_; + } - bool is_valid() const { return is_valid_; } + bool is_valid() const + { + return is_valid_; + } private: diff --git a/plugins/input/pgraster/CMakeLists.txt b/plugins/input/pgraster/CMakeLists.txt index e75370c28..6a2446513 100644 --- a/plugins/input/pgraster/CMakeLists.txt +++ b/plugins/input/pgraster/CMakeLists.txt @@ -7,7 +7,7 @@ target_sources(input-pgraster ${_plugin_visibility} pgraster_wkb_reader.cpp ) target_link_libraries(input-pgraster ${_plugin_visibility} - mapnik::mapnik + mapnik::mapnik mapnik::datasource-base PostgreSQL::PostgreSQL ) diff --git a/plugins/input/postgis/CMakeLists.txt b/plugins/input/postgis/CMakeLists.txt index 7eaae3402..3c1405496 100644 --- a/plugins/input/postgis/CMakeLists.txt +++ b/plugins/input/postgis/CMakeLists.txt @@ -6,7 +6,7 @@ target_sources(input-postgis ${_plugin_visibility} postgis_featureset.cpp ) target_link_libraries(input-postgis ${_plugin_visibility} - mapnik::mapnik + mapnik::mapnik mapnik::datasource-base PostgreSQL::PostgreSQL ) diff --git a/plugins/input/postgis/connection.hpp b/plugins/input/postgis/connection.hpp index e5b0dbab8..3f7187476 100644 --- a/plugins/input/postgis/connection.hpp +++ b/plugins/input/postgis/connection.hpp @@ -236,11 +236,20 @@ class Connection return std::make_shared(result); } - std::string client_encoding() const { return PQparameterStatus(conn_, "client_encoding"); } + std::string client_encoding() const + { + return PQparameterStatus(conn_, "client_encoding"); + } - bool isOK() const { return (!closed_) && (PQstatus(conn_) != CONNECTION_BAD); } + bool isOK() const + { + return (!closed_) && (PQstatus(conn_) != CONNECTION_BAD); + } - bool isPending() const { return pending_; } + bool isPending() const + { + return pending_; + } void close() { diff --git a/plugins/input/shape/shapefile.hpp b/plugins/input/shape/shapefile.hpp index 5798f22ef..2eac16d92 100644 --- a/plugins/input/shape/shapefile.hpp +++ b/plugins/input/shape/shapefile.hpp @@ -171,15 +171,30 @@ class shape_file : public mapnik::util::mapped_memory_file file_.read(reinterpret_cast(&envelope), sizeof(envelope)); } - inline void rewind() { seek(100); } + inline void rewind() + { + seek(100); + } - inline void seek(std::streampos pos) { file_.seekg(pos, std::ios::beg); } + inline void seek(std::streampos pos) + { + file_.seekg(pos, std::ios::beg); + } - inline std::streampos pos() { return file_.tellg(); } + inline std::streampos pos() + { + return file_.tellg(); + } - inline bool is_eof() { return file_.eof(); } + inline bool is_eof() + { + return file_.eof(); + } - inline bool is_good() { return file_.good(); } + inline bool is_good() + { + return file_.good(); + } }; #endif // SHAPEFILE_HPP diff --git a/plugins/input/sqlite/sqlite_connection.hpp b/plugins/input/sqlite/sqlite_connection.hpp index 7e23eaf31..44767a799 100644 --- a/plugins/input/sqlite/sqlite_connection.hpp +++ b/plugins/input/sqlite/sqlite_connection.hpp @@ -160,7 +160,10 @@ class sqlite_connection return rc; } - sqlite3* operator*() { return db_; } + sqlite3* operator*() + { + return db_; + } bool load_extension(std::string const& ext_path) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6bf3714ce..2efe8fb3d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -65,7 +65,6 @@ if(MSVC) target_compile_options(mapnik PUBLIC "/bigobj" "/wd4068" "/wd4661" "/wd4910") endif() - target_sources(mapnik PRIVATE cairo_io.cpp color_factory.cpp @@ -132,7 +131,7 @@ target_sources(mapnik PRIVATE simplify.cpp symbolizer_enumerations.cpp symbolizer_keys.cpp - symbolizer.cpp + symbolizer.cpp transform_expression_grammar_x3.cpp transform_expression.cpp twkb.cpp @@ -145,7 +144,7 @@ target_sources(mapnik PRIVATE wkb.cpp xml_tree.cpp ) -target_sources(mapnik PRIVATE +target_sources(mapnik PRIVATE ../deps/agg/src/agg_arc.cpp ../deps/agg/src/agg_arrowhead.cpp ../deps/agg/src/agg_bezier_arc.cpp @@ -189,7 +188,7 @@ target_sources(mapnik PRIVATE agg/process_text_symbolizer.cpp ) -target_sources(mapnik PRIVATE +target_sources(mapnik PRIVATE css/css_color_grammar_x3.cpp css/css_grammar_x3.cpp ) @@ -247,12 +246,12 @@ target_sources(mapnik PRIVATE text/formatting/list.cpp text/formatting/registry.cpp text/formatting/text.cpp - + text/placements/base.cpp text/placements/dummy.cpp text/placements/list.cpp text/placements/registry.cpp - text/placements/simple.cpp + text/placements/simple.cpp ) target_sources(mapnik PRIVATE @@ -302,7 +301,7 @@ endif() if(USE_GRID_RENDERER) target_sources(mapnik PRIVATE grid/grid_renderer.cpp - grid/grid.cpp + grid/grid.cpp grid/process_building_symbolizer.cpp grid/process_group_symbolizer.cpp grid/process_line_pattern_symbolizer.cpp diff --git a/src/json/CMakeLists.txt b/src/json/CMakeLists.txt index 0444942fc..91ca4fbc0 100644 --- a/src/json/CMakeLists.txt +++ b/src/json/CMakeLists.txt @@ -17,19 +17,19 @@ target_sources(json PRIVATE target_include_directories(json PRIVATE ${JPEG_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} - ${MAPBOX_POLYLABEL_INCLUDE_DIRS} + ${MAPBOX_POLYLABEL_INCLUDE_DIRS} ${MAPBOX_GEOMETRY_INCLUDE_DIRS} ${MAPBOX_VARIANT_INCLUDE_DIRS} ) target_link_libraries(json PRIVATE mapnik::core ${ICUU_LIB}) -set_target_properties(json PROPERTIES +set_target_properties(json PROPERTIES POSITION_INDEPENDENT_CODE ON DEBUG_POSTFIX "${MAPNIK_DEBUG_POSTFIX}" OUTPUT_NAME "mapnikjson" PREFIX "lib" IMPORT_PREFIX "lib" - VERSION ${MAPNIK_VERSION} + VERSION ${MAPNIK_VERSION} # see mapnik target for explanation SOVERSION ${MAPNIK_VERSION} LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" diff --git a/src/proj_transform.cpp b/src/proj_transform.cpp index 624e9147a..29be99f8b 100644 --- a/src/proj_transform.cpp +++ b/src/proj_transform.cpp @@ -128,23 +128,25 @@ proj_transform::proj_transform(projection const& source, projection const& dest) transform_ = proj_create_crs_to_crs(ctx_, source.params().c_str(), dest.params().c_str(), nullptr); if (transform_ == nullptr) { - throw std::runtime_error(std::string("Cannot initialize proj_transform (crs_to_crs) for given projections: '") + - source.params() + "'->'" + dest.params() + + throw std::runtime_error( + std::string("Cannot initialize proj_transform (crs_to_crs) for given projections: '") + + source.params() + "'->'" + dest.params() + #if MAPNIK_PROJ_VERSION >= 80000 - "' because of " + std::string(proj_context_errno_string(ctx_, proj_context_errno(ctx_)))); + "' because of " + std::string(proj_context_errno_string(ctx_, proj_context_errno(ctx_)))); #else - "'"); + "'"); #endif } PJ* transform_gis = proj_normalize_for_visualization(ctx_, transform_); if (transform_gis == nullptr) { - throw std::runtime_error(std::string("Cannot initialize proj_transform (normalize) for given projections: '") + - source.params() + "'->'" + dest.params() + + throw std::runtime_error( + std::string("Cannot initialize proj_transform (normalize) for given projections: '") + + source.params() + "'->'" + dest.params() + #if MAPNIK_PROJ_VERSION >= 80000 - "' because of " + std::string(proj_context_errno_string(ctx_, proj_context_errno(ctx_)))); + "' because of " + std::string(proj_context_errno_string(ctx_, proj_context_errno(ctx_)))); #else - "'"); + "'"); #endif } proj_destroy(transform_); diff --git a/src/tiff_reader.hpp b/src/tiff_reader.hpp index edf9124d8..38e4be507 100644 --- a/src/tiff_reader.hpp +++ b/src/tiff_reader.hpp @@ -96,19 +96,49 @@ class tiff_reader : public image_reader unsigned width() const final; unsigned height() const final; boost::optional> bounding_box() const final; - inline bool has_alpha() const final { return has_alpha_; } + inline bool has_alpha() const final + { + return has_alpha_; + } void read(unsigned x, unsigned y, image_rgba8& image) final; image_any read(unsigned x, unsigned y, unsigned width, unsigned height) final; // methods specific to tiff reader - unsigned bits_per_sample() const { return bps_; } - unsigned sample_format() const { return sample_format_; } - unsigned photometric() const { return photometric_; } - bool is_tiled() const { return is_tiled_; } - unsigned tile_width() const { return tile_width_; } - unsigned tile_height() const { return tile_height_; } - unsigned rows_per_strip() const { return rows_per_strip_; } - unsigned planar_config() const { return planar_config_; } - unsigned compression() const { return compression_; } + unsigned bits_per_sample() const + { + return bps_; + } + unsigned sample_format() const + { + return sample_format_; + } + unsigned photometric() const + { + return photometric_; + } + bool is_tiled() const + { + return is_tiled_; + } + unsigned tile_width() const + { + return tile_width_; + } + unsigned tile_height() const + { + return tile_height_; + } + unsigned rows_per_strip() const + { + return rows_per_strip_; + } + unsigned planar_config() const + { + return planar_config_; + } + unsigned compression() const + { + return compression_; + } private: tiff_reader(const tiff_reader&); @@ -253,8 +283,8 @@ void tiff_reader::init() read_method_ = stripped; } // TIFFTAG_EXTRASAMPLES - uint16 extrasamples = 0; - uint16* sampleinfo = nullptr; + std::uint16_t extrasamples = 0; + std::uint16_t* sampleinfo = nullptr; if (TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo)) { has_alpha_ = true; @@ -265,7 +295,7 @@ void tiff_reader::init() } // Try extracting bounding box from geoTIFF tags { - uint16 count = 0; + std::uint16_t count = 0; double* pixelscale; double* tilepoint; if (TIFFGetField(tif, 33550, &count, &pixelscale) == 1 && count == 3 && diff --git a/src/wkt/CMakeLists.txt b/src/wkt/CMakeLists.txt index 562cc67e9..4fdff2229 100644 --- a/src/wkt/CMakeLists.txt +++ b/src/wkt/CMakeLists.txt @@ -9,19 +9,19 @@ target_include_directories(wkt PRIVATE ${MAPNIK_INCLUDE_PATH} ${JPEG_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR} - ${MAPBOX_POLYLABEL_INCLUDE_DIRS} + ${MAPBOX_POLYLABEL_INCLUDE_DIRS} ${MAPBOX_GEOMETRY_INCLUDE_DIRS} ${MAPBOX_VARIANT_INCLUDE_DIRS} ) target_link_libraries(wkt PRIVATE mapnik::core) -set_target_properties(wkt PROPERTIES +set_target_properties(wkt PROPERTIES POSITION_INDEPENDENT_CODE ON DEBUG_POSTFIX "${MAPNIK_DEBUG_POSTFIX}" OUTPUT_NAME "mapnikwkt" PREFIX "lib" IMPORT_PREFIX "lib" - VERSION ${MAPNIK_VERSION} + VERSION ${MAPNIK_VERSION} # see mapnik target for explanation SOVERSION ${MAPNIK_VERSION} LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 191524ae6..ecd612ed9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,7 +9,7 @@ FetchContent_Declare( GIT_TAG v2.13.7) FetchContent_MakeAvailable(Catch2) -if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19.0") +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.19.0") # for cmake 3.19+ https://cmake.org/cmake/help/git-stage/policy/CMP0110.html # might not be needed if catch updates its cmakes cmake_policy(SET CMP0110 OLD) @@ -17,7 +17,7 @@ endif() add_subdirectory(visual) -add_executable(mapnik-test-unit +add_executable(mapnik-test-unit unit/run.cpp unit/color/css_color.cpp unit/core/box2d_test.cpp @@ -100,14 +100,14 @@ add_executable(mapnik-test-unit unit/vertex_adapter/transform_path_adapter.cpp unit/vertex_adapter/vertex_adapter.cpp ) -set_target_properties(mapnik-test-unit PROPERTIES +set_target_properties(mapnik-test-unit PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib" MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>$<$:DLL>" ) target_link_libraries(mapnik-test-unit PUBLIC - Catch2::Catch2 + Catch2::Catch2 mapnik::agg mapnik::mapnik mapnik::json @@ -120,22 +120,22 @@ file(COPY cleanup.hpp DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") target_include_directories(mapnik-test-unit PRIVATE "${Catch2_SOURCE_DIR}/single_include/catch2" "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") add_executable(agg_rasterizer_integer_overflow_test standalone/agg_rasterizer_integer_overflow_test.cpp) -set_target_properties(agg_rasterizer_integer_overflow_test PROPERTIES +set_target_properties(agg_rasterizer_integer_overflow_test PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib" MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>$<$:DLL>" ) target_link_libraries(agg_rasterizer_integer_overflow_test PUBLIC - Catch2::Catch2 - mapnik::mapnik + Catch2::Catch2 + mapnik::mapnik mapnik::agg mapnik::json ) target_include_directories(agg_rasterizer_integer_overflow_test PRIVATE "${Catch2_SOURCE_DIR}/single_include/catch2" "${CMAKE_CURRENT_BINARY_DIR}") add_executable(datasource_registration_test standalone/datasource_registration_test.cpp) -set_target_properties(datasource_registration_test PROPERTIES +set_target_properties(datasource_registration_test PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib" @@ -143,36 +143,36 @@ set_target_properties(datasource_registration_test PROPERTIES ) target_link_libraries(datasource_registration_test PUBLIC Catch2::Catch2 - mapnik::mapnik + mapnik::mapnik mapnik::agg ) target_include_directories(datasource_registration_test PRIVATE "${Catch2_SOURCE_DIR}/single_include/catch2" "${CMAKE_CURRENT_BINARY_DIR}") add_executable(font_registration_test standalone/font_registration_test.cpp) -set_target_properties(font_registration_test PROPERTIES +set_target_properties(font_registration_test PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib" MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>$<$:DLL>" ) target_link_libraries(font_registration_test PUBLIC - Catch2::Catch2 - mapnik::mapnik + Catch2::Catch2 + mapnik::mapnik mapnik::agg mapnik::json ) target_include_directories(font_registration_test PRIVATE "${Catch2_SOURCE_DIR}/single_include/catch2" "${CMAKE_CURRENT_BINARY_DIR}") add_executable(map_xml_test standalone/map_xml_test.cpp) -set_target_properties(map_xml_test PROPERTIES +set_target_properties(map_xml_test PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" RUNTIME_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}" ARCHIVE_OUTPUT_DIRECTORY "${MAPNIK_OUTPUT_DIR}/lib" MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>$<$:DLL>" ) target_link_libraries(map_xml_test PUBLIC - Catch2::Catch2 - mapnik::mapnik + Catch2::Catch2 + mapnik::mapnik mapnik::agg mapnik::json ) @@ -194,8 +194,8 @@ endif() catch_discover_tests(mapnik-test-unit WORKING_DIRECTORY "${MAPNIK_OUTPUT_DIR}" - PROPERTIES - ENVIRONMENT + PROPERTIES + ENVIRONMENT "PATH=${m_test_path}" ) catch_discover_tests(agg_rasterizer_integer_overflow_test WORKING_DIRECTORY "${MAPNIK_OUTPUT_DIR}") diff --git a/test/catch.hpp b/test/catch.hpp index 7e706f947..896ad6382 100644 --- a/test/catch.hpp +++ b/test/catch.hpp @@ -12,55 +12,54 @@ #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED // start catch.hpp - #define CATCH_VERSION_MAJOR 2 #define CATCH_VERSION_MINOR 13 #define CATCH_VERSION_PATCH 7 #ifdef __clang__ -# pragma clang system_header +#pragma clang system_header #elif defined __GNUC__ -# pragma GCC system_header +#pragma GCC system_header #endif // start catch_suppress_warnings.h #ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(push) -# pragma warning(disable: 161 1682) -# else // __ICC -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wswitch-enum" -# pragma clang diagnostic ignored "-Wcovered-switch-default" -# endif +#ifdef __ICC // icpc defines the __clang__ macro +#pragma warning(push) +#pragma warning(disable: 161 1682) +#else // __ICC +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#pragma clang diagnostic ignored "-Wswitch-enum" +#pragma clang diagnostic ignored "-Wcovered-switch-default" +#endif #elif defined __GNUC__ - // Because REQUIREs trigger GCC's -Wparentheses, and because still - // supported version of g++ have only buggy support for _Pragmas, - // Wparentheses have to be suppressed globally. -# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details +// Because REQUIREs trigger GCC's -Wparentheses, and because still +// supported version of g++ have only buggy support for _Pragmas, +// Wparentheses have to be suppressed globally. +#pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic ignored "-Wpadded" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wpadded" #endif // end catch_suppress_warnings.h #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) -# define CATCH_IMPL -# define CATCH_CONFIG_ALL_PARTS +#define CATCH_IMPL +#define CATCH_CONFIG_ALL_PARTS #endif // In the impl file, we want to have access to all parts of the headers // Can also be used to sanely support PCHs #if defined(CATCH_CONFIG_ALL_PARTS) -# define CATCH_CONFIG_EXTERNAL_INTERFACES -# if defined(CATCH_CONFIG_DISABLE_MATCHERS) -# undef CATCH_CONFIG_DISABLE_MATCHERS -# endif -# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) -# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER -# endif +#define CATCH_CONFIG_EXTERNAL_INTERFACES +#if defined(CATCH_CONFIG_DISABLE_MATCHERS) +#undef CATCH_CONFIG_DISABLE_MATCHERS +#endif +#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif #endif #if !defined(CATCH_CONFIG_IMPL_ONLY) @@ -69,34 +68,33 @@ // See e.g.: // https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html #ifdef __APPLE__ -# include -# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ - (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) -# define CATCH_PLATFORM_MAC -# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) -# define CATCH_PLATFORM_IPHONE -# endif +#include +#if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) +#define CATCH_PLATFORM_MAC +#elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) +#define CATCH_PLATFORM_IPHONE +#endif #elif defined(linux) || defined(__linux) || defined(__linux__) -# define CATCH_PLATFORM_LINUX +#define CATCH_PLATFORM_LINUX #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) -# define CATCH_PLATFORM_WINDOWS +#define CATCH_PLATFORM_WINDOWS #endif // end catch_platform.h #ifdef CATCH_IMPL -# ifndef CLARA_CONFIG_MAIN -# define CLARA_CONFIG_MAIN_NOT_DEFINED -# define CLARA_CONFIG_MAIN -# endif +#ifndef CLARA_CONFIG_MAIN +#define CLARA_CONFIG_MAIN_NOT_DEFINED +#define CLARA_CONFIG_MAIN +#endif #endif // start catch_user_interfaces.h namespace Catch { - unsigned int rngSeed(); +unsigned int rngSeed(); } // end catch_user_interfaces.h @@ -125,30 +123,30 @@ namespace Catch { #ifdef __cplusplus -# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) -# define CATCH_CPP14_OR_GREATER -# endif +#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +#define CATCH_CPP14_OR_GREATER +#endif -# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -# define CATCH_CPP17_OR_GREATER -# endif +#if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#define CATCH_CPP17_OR_GREATER +#endif #endif // Only GCC compiler should be used in this block, so other compilers trying to // mask themselves as GCC should be ignored. #if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) +#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic push") +#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic pop") -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) +#define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) #endif #if defined(__clang__) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) +#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("clang diagnostic push") +#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("clang diagnostic pop") // As of this writing, IBM XL's implementation of __builtin_constant_p has a bug // which results in calls to destructors being emitted for each temporary, @@ -161,62 +159,60 @@ namespace Catch { // ``` // // Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. -# if !defined(__ibmxl__) && !defined(__CUDACC__) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ -# endif +#if !defined(__ibmxl__) && !defined(__CUDACC__) +#define CATCH_INTERNAL_IGNORE_BUT_WARN(...) \ + (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ +#endif -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ - _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") +#define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \ + _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) +#define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma("clang diagnostic ignored \"-Wparentheses\"") -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) +#define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS _Pragma("clang diagnostic ignored \"-Wunused-variable\"") -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) +#define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma("clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"") -# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ - _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) +#define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS _Pragma("clang diagnostic ignored \"-Wunused-template\"") #endif // __clang__ //////////////////////////////////////////////////////////////////////////////// // Assume that non-Windows platforms support posix signals by default #if !defined(CATCH_PLATFORM_WINDOWS) - #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS #endif //////////////////////////////////////////////////////////////////////////////// // We know some environments not to support full POSIX signals #if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) - #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS #endif #ifdef __OS400__ -# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -# define CATCH_CONFIG_COLOUR_NONE +#define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#define CATCH_CONFIG_COLOUR_NONE #endif //////////////////////////////////////////////////////////////////////////////// // Android somehow still does not support std::to_string #if defined(__ANDROID__) -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING -# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +#define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE #endif //////////////////////////////////////////////////////////////////////////////// // Not all Windows environments support SEH properly #if defined(__MINGW32__) -# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH #endif //////////////////////////////////////////////////////////////////////////////// // PS4 #if defined(__ORBIS__) -# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE +#define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE #endif //////////////////////////////////////////////////////////////////////////////// @@ -225,64 +221,63 @@ namespace Catch { // Required for some versions of Cygwin to declare gettimeofday // see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin -# define _BSD_SOURCE +#define _BSD_SOURCE // some versions of cygwin (most) do not support std::to_string. Use the libstd check. // https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 -# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ - && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) +#if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) -# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +#define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING -# endif +#endif #endif // __CYGWIN__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ #if defined(_MSC_VER) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) +#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma(warning(push)) +#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma(warning(pop)) // Universal Windows platform does not support SEH // Or console colours (or console at all...) -# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) -# define CATCH_CONFIG_COLOUR_NONE -# else -# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH -# endif +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +#define CATCH_CONFIG_COLOUR_NONE +#else +#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +#endif // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ // _MSVC_TRADITIONAL == 0 means new conformant preprocessor // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -# if !defined(__clang__) // Handle Clang masquerading for msvc -# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) -# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -# endif // MSVC_TRADITIONAL -# endif // __clang__ +#if !defined(__clang__) // Handle Clang masquerading for msvc +#if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +#define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#endif // MSVC_TRADITIONAL +#endif // __clang__ #endif // _MSC_VER #if defined(_REENTRANT) || defined(_MSC_VER) // Enable async processing, as -pthread is specified or no additional linking is required -# define CATCH_INTERNAL_CONFIG_USE_ASYNC +#define CATCH_INTERNAL_CONFIG_USE_ASYNC #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// // Check if we are compiled with -fno-exceptions or equivalent #if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) -# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED +#define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED #endif //////////////////////////////////////////////////////////////////////////////// // DJGPP #ifdef __DJGPP__ -# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#define CATCH_INTERNAL_CONFIG_NO_WCHAR #endif // __DJGPP__ //////////////////////////////////////////////////////////////////////////////// // Embarcadero C++Build #if defined(__BORLANDC__) - #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN +#define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN #endif //////////////////////////////////////////////////////////////////////////////// @@ -292,8 +287,8 @@ namespace Catch { // handled by it. // Otherwise all supported compilers support COUNTER macro, // but user still might want to turn it off -#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) - #define CATCH_INTERNAL_CONFIG_COUNTER +#if (!defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L) +#define CATCH_INTERNAL_CONFIG_COUNTER #endif //////////////////////////////////////////////////////////////////////////////// @@ -302,9 +297,9 @@ namespace Catch { // This means that it is detected as Windows, but does not provide // the same set of capabilities as real Windows does. #if defined(UNDER_RTSS) || defined(RTX64_BUILD) - #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH - #define CATCH_INTERNAL_CONFIG_NO_ASYNC - #define CATCH_CONFIG_COLOUR_NONE +#define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#define CATCH_INTERNAL_CONFIG_NO_ASYNC +#define CATCH_CONFIG_COLOUR_NONE #endif #if !defined(_GLIBCXX_USE_C99_MATH_TR1) @@ -313,162 +308,175 @@ namespace Catch { // Various stdlib support checks that require __has_include #if defined(__has_include) - // Check if string_view is available and usable - #if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW - #endif +// Check if string_view is available and usable +#if __has_include() && defined(CATCH_CPP17_OR_GREATER) +#define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW +#endif - // Check if optional is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +// Check if optional is available and usable +#if __has_include() && defined(CATCH_CPP17_OR_GREATER) +#define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL +#endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - // Check if byte is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # include - # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) - # define CATCH_INTERNAL_CONFIG_CPP17_BYTE - # endif - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +// Check if byte is available and usable +#if __has_include() && defined(CATCH_CPP17_OR_GREATER) +#include +#if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) +#define CATCH_INTERNAL_CONFIG_CPP17_BYTE +#endif +#endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - // Check if variant is available and usable - # if __has_include() && defined(CATCH_CPP17_OR_GREATER) - # if defined(__clang__) && (__clang_major__ < 8) - // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 - // fix should be in clang 8, workaround in libstdc++ 8.2 - # include - # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) - # define CATCH_CONFIG_NO_CPP17_VARIANT - # else - # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT - # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) - # else - # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT - # endif // defined(__clang__) && (__clang_major__ < 8) - # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +// Check if variant is available and usable +#if __has_include() && defined(CATCH_CPP17_OR_GREATER) +#if defined(__clang__) && (__clang_major__ < 8) +// work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 +// fix should be in clang 8, workaround in libstdc++ 8.2 +#include +#if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) +#define CATCH_CONFIG_NO_CPP17_VARIANT +#else +#define CATCH_INTERNAL_CONFIG_CPP17_VARIANT +#endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) +#else +#define CATCH_INTERNAL_CONFIG_CPP17_VARIANT +#endif // defined(__clang__) && (__clang_major__ < 8) +#endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) #endif // defined(__has_include) #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) -# define CATCH_CONFIG_COUNTER +#define CATCH_CONFIG_COUNTER #endif -#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) -# define CATCH_CONFIG_WINDOWS_SEH +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && \ + !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +#define CATCH_CONFIG_WINDOWS_SEH #endif // This is set by default, because we assume that unix compilers are posix-signal-compatible by default. -#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_CONFIG_POSIX_SIGNALS +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && \ + !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +#define CATCH_CONFIG_POSIX_SIGNALS #endif // This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. #if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) -# define CATCH_CONFIG_WCHAR +#define CATCH_CONFIG_WCHAR #endif -#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) -# define CATCH_CONFIG_CPP11_TO_STRING +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && \ + !defined(CATCH_CONFIG_CPP11_TO_STRING) +#define CATCH_CONFIG_CPP11_TO_STRING #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) -# define CATCH_CONFIG_CPP17_OPTIONAL +#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && \ + !defined(CATCH_CONFIG_CPP17_OPTIONAL) +#define CATCH_CONFIG_CPP17_OPTIONAL #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) -# define CATCH_CONFIG_CPP17_STRING_VIEW +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && \ + !defined(CATCH_CONFIG_CPP17_STRING_VIEW) +#define CATCH_CONFIG_CPP17_STRING_VIEW #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) -# define CATCH_CONFIG_CPP17_VARIANT +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && \ + !defined(CATCH_CONFIG_CPP17_VARIANT) +#define CATCH_CONFIG_CPP17_VARIANT #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) -# define CATCH_CONFIG_CPP17_BYTE +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && \ + !defined(CATCH_CONFIG_CPP17_BYTE) +#define CATCH_CONFIG_CPP17_BYTE #endif #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) -# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE +#define CATCH_INTERNAL_CONFIG_NEW_CAPTURE #endif -#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) -# define CATCH_CONFIG_NEW_CAPTURE +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && \ + !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) +#define CATCH_CONFIG_NEW_CAPTURE #endif #if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -# define CATCH_CONFIG_DISABLE_EXCEPTIONS +#define CATCH_CONFIG_DISABLE_EXCEPTIONS #endif -#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) -# define CATCH_CONFIG_POLYFILL_ISNAN +#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && \ + !defined(CATCH_CONFIG_POLYFILL_ISNAN) +#define CATCH_CONFIG_POLYFILL_ISNAN #endif -#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) -# define CATCH_CONFIG_USE_ASYNC +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && \ + !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +#define CATCH_CONFIG_USE_ASYNC #endif -#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) -# define CATCH_CONFIG_ANDROID_LOGWRITE +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && \ + !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +#define CATCH_CONFIG_ANDROID_LOGWRITE #endif -#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) -# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && \ + !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +#define CATCH_CONFIG_GLOBAL_NEXTAFTER #endif // Even if we do not think the compiler has that warning, we still have // to provide a macro that can be used by the code. #if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) -# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION #endif #if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) -# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION #endif #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS +#define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS +#define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS #endif // The goal of this macro is to avoid evaluation of the arguments, but // still have the compiler warn on problems inside... #if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) -# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) +#define CATCH_INTERNAL_IGNORE_BUT_WARN(...) #endif #if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) -# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #elif defined(__clang__) && (__clang_major__ < 5) -# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #endif #if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #endif #if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -#define CATCH_TRY if ((true)) -#define CATCH_CATCH_ALL if ((false)) +#define CATCH_TRY if ((true)) +#define CATCH_CATCH_ALL if ((false)) #define CATCH_CATCH_ANON(type) if ((false)) #else -#define CATCH_TRY try -#define CATCH_CATCH_ALL catch (...) +#define CATCH_TRY try +#define CATCH_CATCH_ALL catch (...) #define CATCH_CATCH_ANON(type) catch (type) #endif -#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && \ + !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #endif // end catch_compiler_capabilities.h -#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line -#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE(name, line) INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line) #ifdef CATCH_CONFIG_COUNTER -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __COUNTER__) #else -# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __LINE__) #endif #include @@ -476,84 +484,91 @@ namespace Catch { #include // We need a dummy global operator<< so we can bring it into Catch namespace later -struct Catch_global_namespace_dummy {}; +struct Catch_global_namespace_dummy +{}; std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); namespace Catch { - struct CaseSensitive { enum Choice { - Yes, - No - }; }; +struct CaseSensitive +{ + enum Choice { Yes, No }; +}; - class NonCopyable { - NonCopyable( NonCopyable const& ) = delete; - NonCopyable( NonCopyable && ) = delete; - NonCopyable& operator = ( NonCopyable const& ) = delete; - NonCopyable& operator = ( NonCopyable && ) = delete; +class NonCopyable +{ + NonCopyable(NonCopyable const&) = delete; + NonCopyable(NonCopyable&&) = delete; + NonCopyable& operator=(NonCopyable const&) = delete; + NonCopyable& operator=(NonCopyable&&) = delete; - protected: - NonCopyable(); - virtual ~NonCopyable(); - }; + protected: + NonCopyable(); + virtual ~NonCopyable(); +}; - struct SourceLineInfo { +struct SourceLineInfo +{ + SourceLineInfo() = delete; + SourceLineInfo(char const* _file, std::size_t _line) noexcept + : file(_file) + , line(_line) + {} - SourceLineInfo() = delete; - SourceLineInfo( char const* _file, std::size_t _line ) noexcept - : file( _file ), - line( _line ) - {} + SourceLineInfo(SourceLineInfo const& other) = default; + SourceLineInfo& operator=(SourceLineInfo const&) = default; + SourceLineInfo(SourceLineInfo&&) noexcept = default; + SourceLineInfo& operator=(SourceLineInfo&&) noexcept = default; - SourceLineInfo( SourceLineInfo const& other ) = default; - SourceLineInfo& operator = ( SourceLineInfo const& ) = default; - SourceLineInfo( SourceLineInfo&& ) noexcept = default; - SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; + bool empty() const noexcept { return file[0] == '\0'; } + bool operator==(SourceLineInfo const& other) const noexcept; + bool operator<(SourceLineInfo const& other) const noexcept; - bool empty() const noexcept { return file[0] == '\0'; } - bool operator == ( SourceLineInfo const& other ) const noexcept; - bool operator < ( SourceLineInfo const& other ) const noexcept; + char const* file; + std::size_t line; +}; - char const* file; - std::size_t line; - }; +std::ostream& operator<<(std::ostream& os, SourceLineInfo const& info); - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); +// Bring in operator<< from global namespace into Catch namespace +// This is necessary because the overload of operator<< above makes +// lookup stop at namespace Catch +using ::operator<<; - // Bring in operator<< from global namespace into Catch namespace - // This is necessary because the overload of operator<< above makes - // lookup stop at namespace Catch - using ::operator<<; - - // Use this in variadic streaming macros to allow - // >> +StreamEndStop - // as well as - // >> stuff +StreamEndStop - struct StreamEndStop { - std::string operator+() const; - }; - template - T const& operator + ( T const& value, StreamEndStop ) { - return value; - } +// Use this in variadic streaming macros to allow +// >> +StreamEndStop +// as well as +// >> stuff +StreamEndStop +struct StreamEndStop +{ + std::string operator+() const; +}; +template +T const& operator+(T const& value, StreamEndStop) +{ + return value; } +} // namespace Catch -#define CATCH_INTERNAL_LINEINFO \ - ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) +#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo(__FILE__, static_cast(__LINE__)) // end catch_common.h namespace Catch { - struct RegistrarForTagAliases { - RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); - }; +struct RegistrarForTagAliases +{ + RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo); +}; } // end namespace Catch -#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ - CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ +#define CATCH_REGISTER_TAG_ALIAS(alias, spec) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace { \ + Catch::RegistrarForTagAliases \ + INTERNAL_CATCH_UNIQUE_NAME(AutoRegisterTagAlias)(alias, spec, CATCH_INTERNAL_LINEINFO); \ + } \ CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION // end catch_tag_alias_autoregistrar.h @@ -565,28 +580,31 @@ namespace Catch { namespace Catch { - class TestSpec; +class TestSpec; - struct ITestInvoker { - virtual void invoke () const = 0; - virtual ~ITestInvoker(); - }; +struct ITestInvoker +{ + virtual void invoke() const = 0; + virtual ~ITestInvoker(); +}; - class TestCase; - struct IConfig; +class TestCase; +struct IConfig; - struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(); - virtual std::vector const& getAllTests() const = 0; - virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; - }; +struct ITestCaseRegistry +{ + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted(IConfig const& config) const = 0; +}; - bool isThrowSafe( TestCase const& testCase, IConfig const& config ); - bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); - std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); - std::vector const& getAllTestCasesSorted( IConfig const& config ); +bool isThrowSafe(TestCase const& testCase, IConfig const& config); +bool matchTest(TestCase const& testCase, TestSpec const& testSpec, IConfig const& config); +std::vector + filterTests(std::vector const& testCases, TestSpec const& testSpec, IConfig const& config); +std::vector const& getAllTestCasesSorted(IConfig const& config); -} +} // namespace Catch // end catch_interfaces_testcase.h // start catch_stringref.h @@ -598,96 +616,89 @@ namespace Catch { namespace Catch { - /// A non-owning string class (similar to the forthcoming std::string_view) - /// Note that, because a StringRef may be a substring of another string, - /// it may not be null terminated. - class StringRef { - public: - using size_type = std::size_t; - using const_iterator = const char*; +/// A non-owning string class (similar to the forthcoming std::string_view) +/// Note that, because a StringRef may be a substring of another string, +/// it may not be null terminated. +class StringRef +{ + public: + using size_type = std::size_t; + using const_iterator = const char*; - private: - static constexpr char const* const s_empty = ""; + private: + static constexpr char const* const s_empty = ""; - char const* m_start = s_empty; - size_type m_size = 0; + char const* m_start = s_empty; + size_type m_size = 0; - public: // construction - constexpr StringRef() noexcept = default; + public: // construction + constexpr StringRef() noexcept = default; - StringRef( char const* rawChars ) noexcept; + StringRef(char const* rawChars) noexcept; - constexpr StringRef( char const* rawChars, size_type size ) noexcept - : m_start( rawChars ), - m_size( size ) - {} + constexpr StringRef(char const* rawChars, size_type size) noexcept + : m_start(rawChars) + , m_size(size) + {} - StringRef( std::string const& stdString ) noexcept - : m_start( stdString.c_str() ), - m_size( stdString.size() ) - {} + StringRef(std::string const& stdString) noexcept + : m_start(stdString.c_str()) + , m_size(stdString.size()) + {} - explicit operator std::string() const { - return std::string(m_start, m_size); - } + explicit operator std::string() const { return std::string(m_start, m_size); } - public: // operators - auto operator == ( StringRef const& other ) const noexcept -> bool; - auto operator != (StringRef const& other) const noexcept -> bool { - return !(*this == other); - } + public: // operators + auto operator==(StringRef const& other) const noexcept -> bool; + auto operator!=(StringRef const& other) const noexcept -> bool { return !(*this == other); } - auto operator[] ( size_type index ) const noexcept -> char { - assert(index < m_size); - return m_start[index]; - } - - public: // named queries - constexpr auto empty() const noexcept -> bool { - return m_size == 0; - } - constexpr auto size() const noexcept -> size_type { - return m_size; - } - - // Returns the current start pointer. If the StringRef is not - // null-terminated, throws std::domain_exception - auto c_str() const -> char const*; - - public: // substrings and searches - // Returns a substring of [start, start + length). - // If start + length > size(), then the substring is [start, size()). - // If start > size(), then the substring is empty. - auto substr( size_type start, size_type length ) const noexcept -> StringRef; - - // Returns the current start pointer. May not be null-terminated. - auto data() const noexcept -> char const*; - - constexpr auto isNullTerminated() const noexcept -> bool { - return m_start[m_size] == '\0'; - } - - public: // iterators - constexpr const_iterator begin() const { return m_start; } - constexpr const_iterator end() const { return m_start + m_size; } - }; - - auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; - auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; - - constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { - return StringRef( rawChars, size ); + auto operator[](size_type index) const noexcept -> char + { + assert(index < m_size); + return m_start[index]; } + + public: // named queries + constexpr auto empty() const noexcept -> bool { return m_size == 0; } + constexpr auto size() const noexcept -> size_type { return m_size; } + + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception + auto c_str() const -> char const*; + + public: // substrings and searches + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr(size_type start, size_type length) const noexcept -> StringRef; + + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; + + constexpr auto isNullTerminated() const noexcept -> bool { return m_start[m_size] == '\0'; } + + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } +}; + +auto operator+=(std::string& lhs, StringRef const& sr) -> std::string&; +auto operator<<(std::ostream& os, StringRef const& sr) -> std::ostream&; + +constexpr auto operator"" _sr(char const* rawChars, std::size_t size) noexcept -> StringRef +{ + return StringRef(rawChars, size); +} } // namespace Catch -constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { - return Catch::StringRef( rawChars, size ); +constexpr auto operator"" _catch_sr(char const* rawChars, std::size_t size) noexcept -> Catch::StringRef +{ + return Catch::StringRef(rawChars, size); } // end catch_stringref.h // start catch_preprocessor.hpp - #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) @@ -699,9 +710,9 @@ constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) n #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ // MSVC needs more evaluations #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) #else -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) #endif #define CATCH_REC_END(...) @@ -710,41 +721,46 @@ constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) n #define CATCH_EMPTY() #define CATCH_DEFER(id) id CATCH_EMPTY() -#define CATCH_REC_GET_END2() 0, CATCH_REC_END -#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 -#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT -#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) -#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER(CATCH_REC_NEXT0)(test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) -#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))(f, peek, __VA_ARGS__) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0))(f, peek, __VA_ARGS__) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))(f, peek, __VA_ARGS__) -#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) -#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) \ + , f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD))(f, userdata, peek, __VA_ARGS__) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) \ + , f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD))(f, userdata, peek, __VA_ARGS__) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) \ + f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD))(f, userdata, peek, __VA_ARGS__) // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, // and passes userdata as the first parameter to each invocation, // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) -#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) +#define CATCH_REC_LIST_UD(f, userdata, ...) \ + CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) -#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ -#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO##__VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF #define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ #define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) #else // MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF #define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) #define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) \ + (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) #endif #define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ @@ -754,587 +770,1187 @@ constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) n #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) #else -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) \ + INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) \ + INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) #endif -#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ - CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) +#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...) CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST, __VA_ARGS__) #define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) -#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) -#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) -#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) -#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) -#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) -#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) -#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) -#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) -#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) -#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) +#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) \ + INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) +#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) \ + INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) +#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) \ + INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) +#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) \ + INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) +#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) \ + INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) \ + INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) \ + INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) +#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) \ + INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) +#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) +#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) #define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N -#define INTERNAL_CATCH_TYPE_GEN\ - template struct TypeList {};\ - template\ - constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ - template class...> struct TemplateTypeList{};\ - template class...Cs>\ - constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ - template\ - struct append;\ - template\ - struct rewrap;\ - template class, typename...>\ - struct create;\ - template class, typename>\ - struct convert;\ - \ - template \ - struct append { using type = T; };\ - template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ - struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ - template< template class L1, typename...E1, typename...Rest>\ - struct append, TypeList, Rest...> { using type = L1; };\ - \ - template< template class Container, template class List, typename...elems>\ - struct rewrap, List> { using type = TypeList>; };\ - template< template class Container, template class List, class...Elems, typename...Elements>\ - struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ - \ - template