META_HPP_NO_EXCEPTIONS

This commit is contained in:
BlackMATov
2022-02-07 03:08:30 +07:00
parent 39c00a1694
commit 1f06462af4
11 changed files with 58 additions and 32 deletions

View File

@@ -9,6 +9,7 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <algorithm>
#include <array>
@@ -44,6 +45,10 @@
#include "meta_base/type_kinds.hpp"
#include "meta_base/type_list.hpp"
#if !defined(__cpp_exceptions)
# define META_HPP_NO_EXCEPTIONS
#endif
namespace meta_hpp
{
using detail::select_const;
@@ -57,6 +62,27 @@ namespace meta_hpp
using enum_hpp::bitflags::bitflags;
}
namespace meta_hpp
{
class exception final : public std::runtime_error {
public:
explicit exception(const char* what)
: std::runtime_error(what) {}
};
namespace detail
{
inline void throw_exception_with [[noreturn]] (const char* what) {
#ifndef META_HPP_NO_EXCEPTIONS
throw ::meta_hpp::exception(what);
#else
(void)what;
std::abort();
#endif
}
}
}
namespace meta_hpp
{
class value;

View File

@@ -6,6 +6,7 @@
#pragma once
#include <cassert>
#include <cstddef>
#include <functional>
#include <type_traits>
@@ -60,9 +61,8 @@ namespace meta_hpp::detail
}
R operator()(Args... args) const {
return vtable_
? vtable_->call(*this, std::forward<Args>(args)...)
: throw std::bad_function_call();
assert(vtable_ && "bad function call");
return vtable_->call(*this, std::forward<Args>(args)...);
}
void reset() noexcept {

View File

@@ -250,7 +250,7 @@ namespace meta_hpp::detail
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
To arg::cast() const {
if ( !can_cast_to<To>() ) {
throw std::logic_error("bad argument cast");
throw_exception_with("bad argument cast");
}
using to_raw_type_cv = std::remove_reference_t<To>;
@@ -360,6 +360,6 @@ namespace meta_hpp::detail
}
}
throw std::logic_error("bad argument cast");
throw_exception_with("bad argument cast");
}
}

View File

@@ -177,7 +177,7 @@ namespace meta_hpp::detail
template < inst_class_ref_kind Q >
decltype(auto) inst::cast() const {
if ( !can_cast_to<Q>() ) {
throw std::logic_error("bad instance cast");
throw_exception_with("bad instance cast");
}
using inst_class_cv = std::remove_reference_t<Q>;
@@ -205,6 +205,6 @@ namespace meta_hpp::detail
}
}
throw std::logic_error("bad instance cast");
throw_exception_with("bad instance cast");
}
}

View File

@@ -33,7 +33,7 @@ namespace meta_hpp::detail
static_assert(as_object || as_raw_ptr || as_shared_ptr);
if ( args.size() != ct::arity ) {
throw std::logic_error("an attempt to call a constructor with an incorrect arity");
throw_exception_with("an attempt to call a constructor with an incorrect arity");
}
return std::invoke([
@@ -41,7 +41,7 @@ namespace meta_hpp::detail
// NOLINTNEXTLINE(readability-named-parameter)
]<std::size_t... Is>(std::index_sequence<Is...>) -> value {
if ( !(... && (args.data() + Is)->can_cast_to<type_list_at_t<Is, argument_types>>()) ) {
throw std::logic_error("an attempt to call a constructor with incorrect argument types");
throw_exception_with("an attempt to call a constructor with incorrect argument types");
}
if constexpr ( as_object ) {

View File

@@ -20,7 +20,7 @@ namespace meta_hpp::detail
using class_type = typename dt::class_type;
if ( !ptr.can_cast_to<class_type*>() ) {
throw std::logic_error("an attempt to call a destructor with an incorrect argument type");
throw_exception_with("an attempt to call a destructor with an incorrect argument type");
}
class_type* raw_ptr = ptr.cast<class_type*>();

View File

@@ -35,7 +35,7 @@ namespace meta_hpp::detail
static_assert(as_copy || as_void || ref_as_ptr);
if ( args.size() != ft::arity ) {
throw std::logic_error("an attempt to call a function with an incorrect arity");
throw_exception_with("an attempt to call a function with an incorrect arity");
}
return std::invoke([
@@ -43,7 +43,7 @@ namespace meta_hpp::detail
// NOLINTNEXTLINE(readability-named-parameter)
]<std::size_t... Is>(std::index_sequence<Is...>) -> value {
if ( !(... && (args.data() + Is)->can_cast_to<type_list_at_t<Is, argument_types>>()) ) {
throw std::logic_error("an attempt to call a function with incorrect argument types");
throw_exception_with("an attempt to call a function with incorrect argument types");
}
if constexpr ( as_void ) {

View File

@@ -34,7 +34,7 @@ namespace meta_hpp::detail
static_assert(as_copy || as_ptr || as_ref_wrap);
if ( !inst.can_cast_to<const class_type>() ) {
throw std::logic_error("an attempt to get a member with an incorrect instance type");
throw_exception_with("an attempt to get a member with an incorrect instance type");
}
if ( inst.is_const() ) {
@@ -86,18 +86,18 @@ namespace meta_hpp::detail
using value_type = typename mt::value_type;
if constexpr ( std::is_const_v<value_type> ) {
throw std::logic_error("an attempt to set a constant member");
throw_exception_with("an attempt to set a constant member");
} else {
if ( inst.is_const() ) {
throw std::logic_error("an attempt to set a member with an const instance type");
throw_exception_with("an attempt to set a member with an const instance type");
}
if ( !inst.can_cast_to<class_type>() ) {
throw std::logic_error("an attempt to set a member with an incorrect instance type");
throw_exception_with("an attempt to set a member with an incorrect instance type");
}
if ( !arg.can_cast_to<value_type>() ) {
throw std::logic_error("an attempt to set a member with an incorrect argument type");
throw_exception_with("an attempt to set a member with an incorrect argument type");
}
std::invoke(member, inst.cast<class_type>()) = arg.cast<value_type>();

View File

@@ -37,11 +37,11 @@ namespace meta_hpp::detail
static_assert(as_copy || as_void || ref_as_ptr);
if ( args.size() != mt::arity ) {
throw std::logic_error("an attempt to call a method with an incorrect arity");
throw_exception_with("an attempt to call a method with an incorrect arity");
}
if ( !inst.can_cast_to<qualified_type>() ) {
throw std::logic_error("an attempt to call a method with an incorrect instance type");
throw_exception_with("an attempt to call a method with an incorrect instance type");
}
return std::invoke([
@@ -49,7 +49,7 @@ namespace meta_hpp::detail
// NOLINTNEXTLINE(readability-named-parameter)
]<std::size_t... Is>(std::index_sequence<Is...>) -> value {
if ( !(... && (args.data() + Is)->can_cast_to<type_list_at_t<Is, argument_types>>()) ) {
throw std::logic_error("an attempt to call a method with incorrect argument types");
throw_exception_with("an attempt to call a method with incorrect argument types");
}
if constexpr ( as_void ) {

View File

@@ -52,10 +52,10 @@ namespace meta_hpp::detail
using data_type = typename pt::data_type;
if constexpr ( std::is_const_v<data_type> ) {
throw std::logic_error("an attempt to set a constant variable");
throw_exception_with("an attempt to set a constant variable");
} else {
if ( !arg.can_cast_to<data_type>() ) {
throw std::logic_error("an attempt to set a variable with an incorrect argument type");
throw_exception_with("an attempt to set a variable with an incorrect argument type");
}
*pointer = arg.cast<data_type>();
}

View File

@@ -188,7 +188,7 @@ namespace meta_hpp
if constexpr ( detail::has_deref_traits<Tp> ) {
return detail::deref_traits<Tp>{}(v.cast<Tp>());
} else {
throw std::logic_error("value type doesn't have value deref traits");
detail::throw_exception_with("value type doesn't have value deref traits");
}
},
@@ -196,7 +196,7 @@ namespace meta_hpp
if constexpr ( detail::has_index_traits<Tp> ) {
return detail::index_traits<Tp>{}(v.cast<Tp>(), i);
} else {
throw std::logic_error("value type doesn't have value index traits");
detail::throw_exception_with("value type doesn't have value index traits");
}
},
@@ -204,7 +204,7 @@ namespace meta_hpp
if constexpr ( detail::has_less_traits<Tp> ) {
return detail::less_traits<Tp>{}(l.cast<Tp>(), r.cast<Tp>());
} else {
throw std::logic_error("value type doesn't have value less traits");
detail::throw_exception_with("value type doesn't have value less traits");
}
},
@@ -212,7 +212,7 @@ namespace meta_hpp
if constexpr ( detail::has_equals_traits<Tp> ) {
return detail::equals_traits<Tp>{}(l.cast<Tp>(), r.cast<Tp>());
} else {
throw std::logic_error("value type doesn't have value equals traits");
detail::throw_exception_with("value type doesn't have value equals traits");
}
},
@@ -220,7 +220,7 @@ namespace meta_hpp
if constexpr ( detail::has_istream_traits<Tp> ) {
return detail::istream_traits<Tp>{}(is, v.cast<Tp>());
} else {
throw std::logic_error("value type doesn't have value istream traits");
detail::throw_exception_with("value type doesn't have value istream traits");
}
},
@@ -228,7 +228,7 @@ namespace meta_hpp
if constexpr ( detail::has_ostream_traits<Tp> ) {
return detail::ostream_traits<Tp>{}(os, v.cast<Tp>());
} else {
throw std::logic_error("value type doesn't have value ostream traits");
detail::throw_exception_with("value type doesn't have value ostream traits");
}
},
};
@@ -332,7 +332,7 @@ namespace meta_hpp
if ( Tp* ptr = try_cast<Tp>() ) {
return *ptr;
}
throw std::logic_error("bad value cast");
detail::throw_exception_with("bad value cast");
}
template < typename T >
@@ -341,7 +341,7 @@ namespace meta_hpp
if ( Tp* ptr = try_cast<Tp>() ) {
return std::move(*ptr);
}
throw std::logic_error("bad value cast");
detail::throw_exception_with("bad value cast");
}
template < typename T >
@@ -350,7 +350,7 @@ namespace meta_hpp
if ( const Tp* ptr = try_cast<const Tp>() ) {
return *ptr;
}
throw std::logic_error("bad value cast");
detail::throw_exception_with("bad value cast");
}
template < typename T >
@@ -359,7 +359,7 @@ namespace meta_hpp
if ( const Tp* ptr = try_cast<const Tp>() ) {
return std::move(*ptr);
}
throw std::logic_error("bad value cast");
detail::throw_exception_with("bad value cast");
}
template < typename T >