/* * 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 "dxxsconf.h" #include "compiler-type_traits.h" #ifdef DXX_HAVE_BUILTIN_CONSTANT_P #define DXX_VALPTRIDX_STATIC_CHECK(E,F,S) \ ((void)(dxx_builtin_constant_p((E)) && !(E) && \ (DXX_ALWAYS_ERROR_FUNCTION(F,S), 0))) #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(E,S,success,failure) \ ( \ DXX_VALPTRIDX_STATIC_CHECK(E,dxx_trap_##failure,S), \ (E) ? success : throw failure(S) \ ) /* Never used with an actual void, but needed for proper two-stage * lookup. */ template typename tt::enable_if::value, void>::type get_global_array(T *); template class valbaseptridxutil_t { protected: struct null_pointer_exception : std::logic_error { null_pointer_exception(const char *s) : std::logic_error(s) {} }; struct index_mismatch_exception : std::logic_error { index_mismatch_exception(const char *s) : std::logic_error(s) {} }; struct index_range_exception : std::out_of_range { index_range_exception(const char *s) : std::out_of_range(s) {} }; typedef P *pointer_type; typedef I index_type; static constexpr decltype(get_global_array(pointer_type())) get_array() { return get_global_array(pointer_type()); } static pointer_type check_null_pointer(pointer_type p) __attribute_warn_unused_result { return DXX_VALPTRIDX_CHECK(p, "NULL pointer used", p, null_pointer_exception); } template static index_type check_index_match(const A &a, pointer_type p, index_type s) __attribute_warn_unused_result; template static index_type check_index_range(const A &a, index_type s) __attribute_warn_unused_result; }; template class vvalptr_t; template class magic_constant> class vvalidx_t; template class magic_constant> class validx_t; template < template class VP0, template class> class VI0, template class VP1, template class> class VI1, typename P, typename I, template class magic_constant, typename Prc = typename tt::remove_const

::type> struct valptridx_template_t; template class valptr_t : protected valbaseptridxutil_t { typedef valbaseptridxutil_t valutil; protected: typedef typename tt::remove_const

::type Prc; typedef valptr_t valptr_type; using valutil::check_null_pointer; using valutil::check_index_range; public: typedef typename valutil::pointer_type pointer_type; typedef P &reference; valptr_t() = delete; valptr_t(I) = delete; valptr_t(vvalptr_t &&) = delete; valptr_t(vvalptr_t &&) = delete; valptr_t(std::nullptr_t) : p(nullptr) {} template