mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 11:40:35 +07:00
META_HPP_NO_EXCEPTIONS
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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*>();
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
@@ -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 >
|
||||
|
||||
Reference in New Issue
Block a user