mirror of
https://github.com/BlackMATov/meta.hpp.git
synced 2025-12-14 11:40:35 +07:00
value index operator
This commit is contained in:
@@ -182,3 +182,50 @@ namespace meta_hpp
|
||||
using scope_map = std::map<scope_index, scope, std::less<>>;
|
||||
using variable_map = std::map<variable_index, variable, std::less<>>;
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail::stdex
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr std::underlying_type_t<T> to_underlying(T v) noexcept {
|
||||
return static_cast<std::underlying_type_t<T>>(v);
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail::stdex
|
||||
{
|
||||
template < typename T, typename U >
|
||||
concept same_as =
|
||||
std::is_same_v<T, U> &&
|
||||
std::is_same_v<U, T>;
|
||||
|
||||
template < typename Derived, typename Base >
|
||||
concept derived_from =
|
||||
std::is_base_of_v<Base, Derived> &&
|
||||
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
|
||||
|
||||
template < typename From, typename To >
|
||||
concept convertible_to =
|
||||
std::is_convertible_v<From, To> &&
|
||||
requires { static_cast<To>(std::declval<From>()); };
|
||||
|
||||
template < typename T >
|
||||
concept destructible =
|
||||
std::is_nothrow_destructible_v<T>;
|
||||
|
||||
template < typename T, typename... Args >
|
||||
concept constructible_from =
|
||||
destructible<T> &&
|
||||
std::is_constructible_v<T, Args...>;
|
||||
|
||||
template < typename T >
|
||||
concept move_constructible =
|
||||
constructible_from<T, T> &&
|
||||
convertible_to<T, T>;
|
||||
|
||||
template<typename T>
|
||||
concept copy_constructible =
|
||||
move_constructible<T> &&
|
||||
constructible_from<T, T&> && convertible_to<T&, T> &&
|
||||
constructible_from<T, const T&> && convertible_to<const T&, T> &&
|
||||
constructible_from<T, const T> && convertible_to<const T, T>;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace meta_hpp
|
||||
template < detail::class_kind Class >
|
||||
template < typename... Args >
|
||||
class_bind<Class>& class_bind<Class>::ctor_() {
|
||||
static_assert(detail::constructible_from<Class, Args...>);
|
||||
static_assert(detail::stdex::constructible_from<Class, Args...>);
|
||||
auto ctor_state = detail::ctor_state::make<Class, Args...>();
|
||||
data_->ctors.emplace(ctor_state->index, std::move(ctor_state));
|
||||
return *this;
|
||||
@@ -32,7 +32,7 @@ namespace meta_hpp
|
||||
template < detail::class_kind Class >
|
||||
template < detail::class_kind Base >
|
||||
class_bind<Class>& class_bind<Class>::base_() {
|
||||
static_assert(detail::derived_from<Class, Base>);
|
||||
static_assert(detail::stdex::derived_from<Class, Base>);
|
||||
data_->bases.emplace(resolve_type<Base>());
|
||||
data_->bases_info.emplace(resolve_type<Base>(), detail::class_type_data::base_info{
|
||||
.upcast = +[](void* derived) -> void* {
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace meta_hpp::detail
|
||||
evalue_state::evalue_state(evalue_index index, Enum value)
|
||||
: index{std::move(index)}
|
||||
, enum_value{value}
|
||||
, underlying_value{to_underlying(value)} {}
|
||||
, underlying_value{stdex::to_underlying(value)} {}
|
||||
|
||||
template < enum_kind Enum >
|
||||
evalue_state_ptr evalue_state::make(std::string name, Enum value) {
|
||||
|
||||
@@ -34,36 +34,6 @@ namespace meta_hpp::detail
|
||||
using copy_cvref_t = typename cvref_traits<From>::template copy_to<To>;
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
concept destructible =
|
||||
std::is_nothrow_destructible_v<T>;
|
||||
|
||||
template < typename T, typename... Args >
|
||||
concept constructible_from =
|
||||
destructible<T> &&
|
||||
std::is_constructible_v<T, Args...>;
|
||||
|
||||
template < typename Derived, typename Base >
|
||||
concept derived_from =
|
||||
std::is_base_of_v<Base, Derived> &&
|
||||
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
|
||||
|
||||
template < typename From, typename To >
|
||||
concept convertible_to =
|
||||
std::is_convertible_v<From, To> &&
|
||||
requires { static_cast<To>(std::declval<From>()); };
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
[[nodiscard]] constexpr std::underlying_type_t<T> to_underlying(T v) noexcept {
|
||||
return static_cast<std::underlying_type_t<T>>(v);
|
||||
}
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
@@ -114,34 +84,6 @@ namespace meta_hpp::detail
|
||||
(std::is_rvalue_reference_v<T> && std::is_class_v<std::remove_reference_t<T>>);
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
concept has_deref_op_kind = requires(const T& v) {
|
||||
{ *v } -> convertible_to<std::remove_pointer_t<T>>;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
concept has_less_op_kind = requires(const T& v) {
|
||||
{ v < v } -> convertible_to<bool>;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
concept has_equals_op_kind = requires(const T& v) {
|
||||
{ v == v } -> convertible_to<bool>;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
concept has_istream_op_kind = requires(std::istream& is, T& v) {
|
||||
{ is >> v } -> convertible_to<std::istream&>;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
concept has_ostream_op_kind = requires(std::ostream& os, const T& v) {
|
||||
{ os << v } -> convertible_to<std::ostream&>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
class noncopyable {
|
||||
@@ -187,9 +129,8 @@ namespace meta_hpp
|
||||
[[nodiscard]] const void* data() const noexcept;
|
||||
[[nodiscard]] const void* cdata() const noexcept;
|
||||
|
||||
[[nodiscard]] value deref();
|
||||
[[nodiscard]] value deref() const;
|
||||
[[nodiscard]] value cderef() const;
|
||||
[[nodiscard]] value operator*() const;
|
||||
[[nodiscard]] value operator[](std::size_t index) const;
|
||||
|
||||
template < typename T, typename Tp = std::decay_t<T> >
|
||||
[[nodiscard]] Tp& cast() &;
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
#include "../meta_base.hpp"
|
||||
#include "../meta_utilities.hpp"
|
||||
|
||||
#include "value_traits/deref_traits.hpp"
|
||||
#include "value_traits/equals_traits.hpp"
|
||||
#include "value_traits/index_traits.hpp"
|
||||
#include "value_traits/istream_traits.hpp"
|
||||
#include "value_traits/less_traits.hpp"
|
||||
#include "value_traits/ostream_traits.hpp"
|
||||
|
||||
namespace meta_hpp
|
||||
{
|
||||
struct value::traits final {
|
||||
@@ -17,8 +24,8 @@ namespace meta_hpp
|
||||
void* (*const data)(value&) noexcept;
|
||||
const void* (*const cdata)(const value&) noexcept;
|
||||
|
||||
value (*const deref)(value&);
|
||||
value (*const cderef)(const value&);
|
||||
value (*const deref)(const value&);
|
||||
value (*const index)(const value&, std::size_t);
|
||||
|
||||
bool (*const less)(const value&, const value&);
|
||||
bool (*const equals)(const value&, const value&);
|
||||
@@ -48,35 +55,35 @@ namespace meta_hpp
|
||||
return v.try_cast<T>();
|
||||
},
|
||||
|
||||
.deref = +[]([[maybe_unused]] value& v) -> value {
|
||||
if constexpr ( detail::has_deref_op_kind<T> ) {
|
||||
.deref = +[]([[maybe_unused]] const value& v) -> value {
|
||||
if constexpr ( detail::has_value_deref_traits<T> ) {
|
||||
return value{*v.cast<T>()};
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have deref operator");
|
||||
throw std::logic_error("value type doesn't have value deref traits");
|
||||
}
|
||||
},
|
||||
|
||||
.cderef = +[]([[maybe_unused]] const value& v) -> value {
|
||||
if constexpr ( detail::has_deref_op_kind<T> ) {
|
||||
return value{*v.cast<T>()};
|
||||
.index = +[]([[maybe_unused]] const value& v, [[maybe_unused]] std::size_t index) -> value {
|
||||
if constexpr ( detail::has_value_index_traits<T> ) {
|
||||
return detail::value_index_traits<T>{}(v.cast<T>(), index);
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have deref operator");
|
||||
throw std::logic_error("value type doesn't have value index traits");
|
||||
}
|
||||
},
|
||||
|
||||
.less = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool {
|
||||
if constexpr ( detail::has_less_op_kind<T> ) {
|
||||
return l.cast<T>() < r.cast<T>();
|
||||
if constexpr ( detail::has_value_less_traits<T> ) {
|
||||
return detail::value_less_traits<T>{}(l.cast<T>(), r.cast<T>());
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have less operator");
|
||||
throw std::logic_error("value type doesn't have value less traits");
|
||||
}
|
||||
},
|
||||
|
||||
.equals = +[]([[maybe_unused]] const value& l, [[maybe_unused]] const value& r) -> bool {
|
||||
if constexpr ( detail::has_equals_op_kind<T> ) {
|
||||
return l.cast<T>() == r.cast<T>();
|
||||
if constexpr ( detail::has_value_equals_traits<T> ) {
|
||||
return detail::value_equals_traits<T>{}(l.cast<T>(), r.cast<T>());
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have equality operator");
|
||||
throw std::logic_error("value type doesn't have value equals traits");
|
||||
}
|
||||
},
|
||||
|
||||
@@ -97,18 +104,18 @@ namespace meta_hpp
|
||||
},
|
||||
|
||||
.istream = +[]([[maybe_unused]] std::istream& is, [[maybe_unused]] value& v) -> std::istream& {
|
||||
if constexpr ( detail::has_istream_op_kind<T> ) {
|
||||
return is >> v.cast<T>();
|
||||
if constexpr ( detail::has_value_istream_traits<T> ) {
|
||||
return detail::value_istream_traits<T>{}(is, v.cast<T>());
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have istream operator");
|
||||
throw std::logic_error("value type doesn't have value istream traits");
|
||||
}
|
||||
},
|
||||
|
||||
.ostream = +[]([[maybe_unused]] std::ostream& os, [[maybe_unused]] const value& v) -> std::ostream& {
|
||||
if constexpr ( detail::has_ostream_op_kind<T> ) {
|
||||
return os << v.cast<T>();
|
||||
if constexpr ( detail::has_value_ostream_traits<T> ) {
|
||||
return detail::value_ostream_traits<T>{}(os, v.cast<T>());
|
||||
} else {
|
||||
throw std::logic_error("value type doesn't have ostream operator");
|
||||
throw std::logic_error("value type doesn't have value ostream traits");
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -181,16 +188,12 @@ namespace meta_hpp
|
||||
return traits_->cdata(*this);
|
||||
}
|
||||
|
||||
inline value value::deref() {
|
||||
inline value value::operator*() const {
|
||||
return traits_->deref(*this);
|
||||
}
|
||||
|
||||
inline value value::deref() const {
|
||||
return traits_->cderef(*this);
|
||||
}
|
||||
|
||||
inline value value::cderef() const {
|
||||
return traits_->cderef(*this);
|
||||
inline value value::operator[](std::size_t index) const {
|
||||
return traits_->index(*this, index);
|
||||
}
|
||||
|
||||
template < typename T, typename Tp >
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_utilities.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_deref_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_deref_traits = requires(const T& v) {
|
||||
{ value_deref_traits<T>{}(v) } -> stdex::convertible_to<value>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_deref_traits<T*> {
|
||||
value operator()(T* v) const {
|
||||
return value{*v};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_deref_traits<const T*> {
|
||||
value operator()(const T* v) const {
|
||||
return value{*v};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_deref_traits<std::shared_ptr<T>> {
|
||||
value operator()(const std::shared_ptr<T>& v) const {
|
||||
return value{*v};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_deref_traits<std::unique_ptr<T>> {
|
||||
value operator()(const std::unique_ptr<T>& v) const {
|
||||
return value{*v};
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_equals_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_equals_traits = requires(const T& v) {
|
||||
{ value_equals_traits<T>{}(v, v) } -> stdex::convertible_to<bool>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) {
|
||||
{ v == v } -> stdex::convertible_to<bool>;
|
||||
}
|
||||
struct value_equals_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
return l == r;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
#include "../../meta_utilities.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_index_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_index_traits = requires(const T& v, std::size_t i) {
|
||||
{ value_index_traits<T>{}(v, i) } -> stdex::convertible_to<value>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_index_traits<T*> {
|
||||
value operator()(T* v, std::size_t i) const {
|
||||
return value{*(v + i)};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T >
|
||||
struct value_index_traits<const T*> {
|
||||
value operator()(const T* v, std::size_t i) const {
|
||||
return value{*(v + i)};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T, std::size_t Size >
|
||||
struct value_index_traits<std::array<T, Size>> {
|
||||
value operator()(const std::array<T, Size>& v, std::size_t i) const {
|
||||
return value{v[i]};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T, std::size_t Extent >
|
||||
struct value_index_traits<std::span<T, Extent>> {
|
||||
value operator()(const std::span<T, Extent>& v, std::size_t i) const {
|
||||
return value{v[i]};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T, typename Traits, typename Allocator >
|
||||
struct value_index_traits<std::basic_string<T, Traits, Allocator>> {
|
||||
value operator()(const std::basic_string<T, Traits, Allocator>& v, std::size_t i) const {
|
||||
return value{v[i]};
|
||||
}
|
||||
};
|
||||
|
||||
template < stdex::copy_constructible T, typename Allocator >
|
||||
struct value_index_traits<std::vector<T, Allocator>> {
|
||||
value operator()(const std::vector<T, Allocator>& v, std::size_t i) {
|
||||
return value{v[i]};
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_istream_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_istream_traits = requires(std::istream& is, T& v) {
|
||||
{ value_istream_traits<T>{}(is, v) } -> stdex::convertible_to<std::istream&>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(std::istream& is, T& v) {
|
||||
{ is >> v } -> stdex::convertible_to<std::istream&>;
|
||||
}
|
||||
struct value_istream_traits<T> {
|
||||
std::istream& operator()(std::istream& is, T& v) const {
|
||||
return is >> v;
|
||||
}
|
||||
};
|
||||
}
|
||||
33
headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp
Normal file
33
headers/meta.hpp/meta_utilities/value_traits/less_traits.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_less_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_less_traits = requires(const T& v) {
|
||||
{ value_less_traits<T>{}(v, v) } -> stdex::convertible_to<bool>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(const T& v) {
|
||||
{ v < v } -> stdex::convertible_to<bool>;
|
||||
}
|
||||
struct value_less_traits<T> {
|
||||
bool operator()(const T& l, const T& r) const {
|
||||
return l < r;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*******************************************************************************
|
||||
* This file is part of the "https://github.com/blackmatov/meta.hpp"
|
||||
* For conditions of distribution and use, see copyright notice in LICENSE.md
|
||||
* Copyright (C) 2021, by Matvey Cherevko (blackmatov@gmail.com)
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../meta_base.hpp"
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
struct value_ostream_traits;
|
||||
|
||||
template < typename T >
|
||||
concept has_value_ostream_traits = requires(std::ostream& is, const T& v) {
|
||||
{ value_ostream_traits<T>{}(is, v) } -> stdex::convertible_to<std::ostream&>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace meta_hpp::detail
|
||||
{
|
||||
template < typename T >
|
||||
requires requires(std::ostream& os, const T& v) {
|
||||
{ os << v } -> stdex::convertible_to<std::ostream&>;
|
||||
}
|
||||
struct value_ostream_traits<T> {
|
||||
std::ostream& operator()(std::ostream& is, const T& v) const {
|
||||
return is << v;
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user