/* * This file is part of the DXX-Rebirth project . * It is copyright by its individual contributors, as recorded in the * project's Git history. See COPYING.txt at the top level for license * terms and a link to the Git history. */ #pragma once #include #include #include "fwd-valptridx.h" #include "compiler-array.h" #include "compiler-static_assert.h" #include "compiler-type_traits.h" #include "pack.h" #include "poison.h" #ifdef DXX_CONSTANT_TRUE #define DXX_VALPTRIDX_STATIC_CHECK(SUCCESS_CONDITION,FAILURE_FUNCTION,FAILURE_STRING) \ ( \ static_cast(DXX_CONSTANT_TRUE(!(SUCCESS_CONDITION)) && \ (DXX_ALWAYS_ERROR_FUNCTION(FAILURE_FUNCTION, FAILURE_STRING), 0) \ ) \ ) #ifdef DXX_HAVE_ATTRIBUTE_WARNING /* This causes many warnings because some conversions are not checked for * safety. Eliminating the warnings by changing the call sites to check first * would be a useful improvement. */ //#define DXX_VALPTRIDX_WARN_CALL_NOT_OPTIMIZED_OUT __attribute__((__warning__("call not eliminated"))) #endif #else #define DXX_VALPTRIDX_STATIC_CHECK(E,F,S) \ ((void)0) #endif #ifdef DXX_HAVE_CXX11_REF_QUALIFIER #define DXX_VALPTRIDX_REF_QUALIFIER_LVALUE & #else #define DXX_VALPTRIDX_REF_QUALIFIER_LVALUE #endif #define DXX_VALPTRIDX_CHECK(SUCCESS_CONDITION,EXCEPTION,FAILURE_STRING,...) \ ( \ static_cast(DXX_VALPTRIDX_STATIC_CHECK((SUCCESS_CONDITION), dxx_trap_##EXCEPTION, FAILURE_STRING), \ (SUCCESS_CONDITION) || (EXCEPTION::report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_PASS_VA(__VA_ARGS__)), 0) \ ) \ ) #ifndef DXX_VALPTRIDX_WARN_CALL_NOT_OPTIMIZED_OUT #define DXX_VALPTRIDX_WARN_CALL_NOT_OPTIMIZED_OUT #endif namespace detail { class valptridx_array_type_count { unsigned count; public: unsigned get_count() const { return count; } void set_count(const unsigned c) { count = c; } }; } template constexpr std::size_t valptridx_specialized_type_parameters::array_size; template class valptridx

::index_mismatch_exception : public std::logic_error { DXX_INHERIT_CONSTRUCTORS(index_mismatch_exception, logic_error); public: __attribute_cold __attribute_noreturn DXX_VALPTRIDX_WARN_CALL_NOT_OPTIMIZED_OUT static void report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const array_managed_type &, index_type, const_pointer_type, const_pointer_type); }; template class valptridx

::index_range_exception : public std::out_of_range { DXX_INHERIT_CONSTRUCTORS(index_range_exception, out_of_range); public: __attribute_cold __attribute_noreturn DXX_VALPTRIDX_WARN_CALL_NOT_OPTIMIZED_OUT static void report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const array_managed_type *, long); }; template class valptridx

::null_pointer_exception : public std::logic_error { DXX_INHERIT_CONSTRUCTORS(null_pointer_exception, logic_error); public: __attribute_cold __attribute_noreturn DXX_VALPTRIDX_WARN_CALL_NOT_OPTIMIZED_OUT static void report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_N_DEFN_VARS); __attribute_cold __attribute_noreturn DXX_VALPTRIDX_WARN_CALL_NOT_OPTIMIZED_OUT static void report(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const array_managed_type &); }; template void valptridx::check_index_match(DXX_VALPTRIDX_REPORT_STANDARD_LEADER_COMMA_R_DEFN_VARS const managed_type &r, index_type i, const array_managed_type &a) { const auto pi = &a[i]; DXX_VALPTRIDX_CHECK(pi == &r, index_mismatch_exception, "pointer/index mismatch", a, i, pi, &r); } template template