variant

class RTTR_API variant

对github项目rttr(C++反射库)解析,链接:https://github.com/rttrorg/rttr

namespace rttr
{
class variant_associative_view;
class variant_sequential_view;
class type;
class variant;
class argument;
class instance;namespace detail
{template<class T>RTTR_INLINE T* unsafe_variant_cast(variant* operand) RTTR_NOEXCEPT;template<class T>RTTR_INLINE const T* unsafe_variant_cast(const variant* operand) RTTR_NOEXCEPT;struct data_address_container;template<typename T>struct empty_type_converter;template<typename T, typename Tp, typename Converter = empty_type_converter<T>>struct variant_data_base_policy;struct variant_data_policy_nullptr_t;enum class variant_policy_operation : uint8_t;template<typename T, typename Decayed = decay_except_array_t<T>>using decay_variant_t = enable_if_t<!std::is_same<Decayed, variant>::value, Decayed>;using variant_policy_func = bool (*)(variant_policy_operation, const variant_data&, argument_wrapper);
}
class RTTR_API variant
{...private:friend class argument;friend class instance;template<typename T, typename Tp, typename Converter>friend struct detail::variant_data_base_policy;friend struct detail::variant_data_policy_nullptr_t;friend RTTR_API bool detail::variant_compare_less(const variant&, const type&, const variant&, const type&, bool& ok);template<class T>friend RTTR_INLINE T* detail::unsafe_variant_cast(variant* operand) RTTR_NOEXCEPT;detail::variant_data            m_data;detail::variant_policy_func     m_policy;
}

variant_data

namespace rttr
{
namespace detail
{/using variant_basic_types = type_list<bool,signed char, unsigned char, char, wchar_t,short int, unsigned short int, int, unsigned int,long int, unsigned long int, long long int,unsigned long long int, float, double, void*>;/*!* This is the data storage for the \ref variant class.*/
using variant_data = std::aligned_storage<max_sizeof_list<variant_basic_types>::value,max_alignof_list<variant_basic_types>::value>::type;/struct RTTR_API void_variant_type {};} // end namespace detail
} // end namespace rttr
  • std::aligned_storage
template< std::size_t Len, std::size_t Align = /*default-alignment*/ >
struct aligned_storage;
template<std::size_t Len, std::size_t Align /* 未实现默认对齐 */>
struct aligned_storage
{struct type{alignas(Align) unsigned char data[Len];};
};

std::aligned_storage对象构造完成时,即分配了长度为Len个字节的内存,且该内存满足大小为 Align 的对齐要求。

  • max_sizeof_list
template<typename... Ts>
using max_sizeof_list = std::integral_constant<std::size_t, max_sizeof_list_impl<Ts...>::value>;
  • max_alignof_list
template<typename... Ts>
using max_alignof_list = std::integral_constant<std::size_t, max_alignof_list_impl<Ts...>::value>;
  • std::integral_constant
template< class T, T v >
struct integral_constant;

传入类型T,使其成员变量成为v的数值。

  • max_alignof_list_impl
template <typename T, typename...Ts>
struct max_alignof_list_impl;template <typename T>
struct max_alignof_list_impl<T>
{static RTTR_CONSTEXPR_OR_CONST size_t value = std::alignment_of<T>::value;
};template<typename T1, typename T2, typename... U>
struct max_alignof_list_impl<T1, T2, U...>
{static RTTR_CONSTEXPR_OR_CONST std::size_t value = max_alignof_list_impl<conditional_t<std::alignment_of<T1>::value >= std::alignment_of<T2>::value, T1, T2>, U...>::value;
};template<template<class...> class List, typename... Ts>
struct max_alignof_list_impl<List<Ts...>>
{static RTTR_CONSTEXPR_OR_CONST std::size_t value = max_alignof_list_impl<Ts...>::value;
};

max_alignof_list_impl模板偏特化,using max_alignof_list = std::integral_constant<std::size_t, max_alignof_list_impl<Ts…>::value>;执行哪一个?由Ts个数决定,但最终都和std::alignment_of::value相关,最终返回T类型的按照sizeof对齐的大小。

  • max_sizeof_list
template <typename T, typename...Ts>
struct max_sizeof_list_impl;template <typename T>
struct max_sizeof_list_impl<T>
{static RTTR_CONSTEXPR_OR_CONST size_t value = sizeof(T);
};template<typename T1, typename T2, typename... U>
struct max_sizeof_list_impl<T1, T2, U...>
{static RTTR_CONSTEXPR_OR_CONST std::size_t value = max_sizeof_list_impl< conditional_t< sizeof(T1) >= sizeof(T2),T1,T2>,U...>::value;
};template<template<class...> class List, class... Ts>
struct max_sizeof_list_impl<List<Ts...>>
{static RTTR_CONSTEXPR_OR_CONST std::size_t value = max_sizeof_list_impl<Ts...>::value;
};

同理max_alignof_list_impl,和sizeof(T)相关。

  • variant_basic_types
using variant_basic_types = type_list<bool,signed char, unsigned char, char, wchar_t,short int, unsigned short int, int, unsigned int,long int, unsigned long int, long long int,unsigned long long int, float, double, void*>;
  • type_list
namespace rttr
{
template<typename...T>
struct type_list
{static RTTR_CONSTEXPR_OR_CONST auto size = sizeof...(T); //!< The amount of template parameters
};
} // end namespace rttr

variant_data是做什么?

using variant_data = std::aligned_storage<max_sizeof_list<variant_basic_types>::value,max_alignof_list<variant_basic_types>::value>::type;

找到type_list类模板中最大的类型大小以及最大的对齐大小,并按照此最大类型的大小分配内存并满足最大的对齐大小的对齐要求。

variant_data = alignas(max_alignof_list<variant_basic_types>::value) unsigned char data[max_sizeof_list<variant_basic_types>::value];

variant_policy_func

using variant_policy_func = bool (*)(variant_policy_operation, const variant_data&, argument_wrapper);
  • variant_policy_operation
enum class variant_policy_operation : uint8_t
{DESTROY,CLONE,SWAP,EXTRACT_WRAPPED_VALUE,CREATE_WRAPPED_VALUE,GET_VALUE,GET_TYPE,GET_PTR,GET_RAW_TYPE,GET_RAW_PTR,GET_ADDRESS_CONTAINER,IS_ASSOCIATIVE_CONTAINER,IS_SEQUENTIAL_CONTAINER,CREATE_ASSOCIATIV_VIEW,CREATE_SEQUENTIAL_VIEW,IS_VALID,IS_NULLPTR,CONVERT,COMPARE_EQUAL,COMPARE_LESS
};
  • argument_wrapper
struct argument_wrapper
{argument_wrapper() : m_data(nullptr) {}template<typename T, typename Tp = typename std::enable_if<!std::is_same<T, argument_wrapper>::value, T>::type>argument_wrapper(T&& data) : m_data(const_cast<void*>(reinterpret_cast<const void*>(std::addressof(data)))) {}template<typename T>T& get_value() const{using raw_type = typename std::remove_reference<T>::type;return (*reinterpret_cast<raw_type*>(const_cast<void *>(m_data)));}void* m_data;
};

argument_wrapper的主要作用:将T类型的数据存放进m_data并有能力获取m_data地址

class RTTR_API variant

  • RTTR_INLINE variant();

    RTTR_INLINE variant::variant()
    :   m_policy(&detail::variant_data_policy_empty::invoke)
    {
    }
    

    只是对m_policy成员初始化并没有对m_data初始化?

    • variant_data_policy_empty::invoke
    static bool invoke(variant_policy_operation op, const variant_data& src_data, argument_wrapper arg)
    
    static bool invoke(variant_policy_operation op, const variant_data& src_data, argument_wrapper arg)
    {switch (op){case variant_policy_operation::DESTROY:case variant_policy_operation::CLONE:case variant_policy_operation::SWAP:case variant_policy_operation::EXTRACT_WRAPPED_VALUE:case variant_policy_operation::CREATE_WRAPPED_VALUE:{break;}case variant_policy_operation::GET_VALUE:{arg.get_value<const void*>() = nullptr;break;}case variant_policy_operation::GET_TYPE:{arg.get_value<type>() = get_invalid_type();break;}case variant_policy_operation::GET_PTR:{arg.get_value<void*>() = nullptr;break;}case variant_policy_operation::GET_RAW_TYPE:{arg.get_value<type>() = get_invalid_type();break;}case variant_policy_operation::GET_RAW_PTR:{arg.get_value<void*>() = nullptr;break;}case variant_policy_operation::GET_ADDRESS_CONTAINER:{data_address_container& data        = arg.get_value<data_address_container>();data.m_type                         = get_invalid_type();data.m_wrapped_type                 = get_invalid_type();data.m_data_address                 = nullptr;data.m_data_address_wrapped_type    = nullptr;break;}case variant_policy_operation::IS_ASSOCIATIVE_CONTAINER:{return false;}case variant_policy_operation::IS_SEQUENTIAL_CONTAINER:{return false;}case variant_policy_operation::CREATE_ASSOCIATIV_VIEW:{break;}case variant_policy_operation::CREATE_SEQUENTIAL_VIEW:{break;}case variant_policy_operation::IS_VALID:{return false;}case variant_policy_operation::IS_NULLPTR:{return false;}case variant_policy_operation::CONVERT:{return false;}case variant_policy_operation::COMPARE_EQUAL:{const auto& param   = arg.get_value<std::tuple<const variant&, const variant&, bool&>>();const variant& rhs  = std::get<1>(param);bool& ok            = std::get<2>(param);if (!rhs.is_valid())ok = true;return ok;}case variant_policy_operation::COMPARE_LESS:{return false;}}return true;
    }
    

    DESTROY、CLONE、SWAP、EXTRACT_WRAPPED_VALUE、CREATE_WRAPPED_VALUE、CREATE_ASSOCIATIV_VIEW、CREATE_SEQUENTIAL_VIEW无任何操作,GET_VALUE、GET_PTR、GET_RAW_PTR将class argument_wrapper中的m_data值置nullptr,GET_TYPE、GET_RAW_TYPE获取class RTTR_API type类型的值地址(class type后续说明),GET_ADDRESS_CONTAINER:初始化struct data_address_container成员变量,IS_ASSOCIATIVE_CONTAINER、IS_SEQUENTIAL_CONTAINER、IS_VALID、IS_NULLPTR、CONVERT、COMPARE_LESS都返回false,COMPARE_EQUAL:variant有效是false反之是true,但由代码得知始终是true

由默认构造函数得知:m_policy来控制不同操作下的bool返回结果

  • ​ template<typename T, typename Tp = detail::decay_variant_t> variant(T&& val);

    template<typename T, typename Tp>
    RTTR_INLINE variant::variant(T&& val)
    :   m_policy(&detail::variant_policy<Tp>::invoke)
    {static_assert(std::is_copy_constructible<Tp>::value || std::is_array<Tp>::value,"The given value is not copy constructible, try to add a copy constructor to the class.");detail::variant_policy<Tp>::create(std::forward<T>(val), m_data);
    }
    
    • detail::decay_variant

      template<typename T, typename Decayed = decay_except_array_t<T>>
      using decay_variant_t = enable_if_t<!std::is_same<Decayed, variant>::value, Decayed>;
      
      • decay_except_array_t

        template<typename T>
        struct decay_except_array
        {using Tp    = remove_reference_t<T>;using type  = conditional_t< std::is_function<Tp>::value,add_pointer_t<Tp>,remove_cv_t<Tp>>;
        };template<typename T>
        using decay_except_array_t = typename decay_except_array<T>::type;
        

        如何TP类型是函数,则给Tp加上指针,反之移除Tp类型的const和volatile属性。

    decay_variant_t则是Decayed和variant类型不相同时decay_variant_t = conditional_t<std: : is_function::value, add_pointer_t, remove_cv_t >.

    • variant_policy

    观察所知:struct variant_data_base_policy、struct variant_data_policy_small、struct variant_data_policy_big、struct variant_data_policy_array_small、struct variant_data_policy_array_big 、struct variant_data_policy_arithmetic、struct RTTR_API variant_data_policy_string、struct RTTR_API variant_data_policy_empty、struct RTTR_API variant_data_policy_void、struct RTTR_API variant_data_policy_nullptr_t这些函数都是根据enum variant_variant_policy_operation中的选项做出不同操作(对variant_data类型的数据和argument_wrapper类型的数据进行相关操作),具体分析函数具体作用需要针对上层调用来分析,这里具体是上层来抉择variant_policy,然后在多态中的各种variant策略中进行相关创建、析构、克隆、交换操作 。

  • RTTR_INLINE variant::~variant()
RTTR_INLINE variant::~variant()
{m_policy(detail::variant_policy_operation::DESTROY, m_data, detail::argument_wrapper());
}

通过m_policy调用invoke相关函数,根据detail::variant_policy_operation::DESTROY选项来对其数据进行析构。

总结:只要m_data相关数据操作都会使用到m_policy来调用variant_data_base_policy::invoke()函数来对不同策略进行选择性操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/1594.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

真实世界的密码学(四)

原文&#xff1a;annas-archive.org/md5/655c944001312f47533514408a1a919a 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第十六章&#xff1a;加密何时何地失败 本章涵盖 使用加密时可能遇到的一般问题 遵循烘烤良好的加密的要点 加密从业者的危险和责任 问候…

论文笔记:Time-LLM: Time Series Forecasting by Reprogramming Large Language Models

iclr 2024 reviewer 评分 3888 1 方法 提出了 Time-LLM&#xff0c; 是一个通用的大模型重编程&#xff08;LLM Reprogramming&#xff09;框架将 LLM 轻松用于一般时间序列预测&#xff0c;而无需对大语言模型本身做任何训练 为什么需要时序数据和文本数据对齐&#xff1a;时…

Oracle 窗口函数 02 (排名问题)

目录 一、什么是窗口函数 1.语法里每部分表示什么 2.窗口函数可以解决这几类经典问题 二、排名问题 1.学生成绩排名 2.去除最大值、最小值后求平均值 知识点&#xff1a; 一、什么是窗口函数 窗口函数也叫作OLAP&#xff08;Online Analytical Processing&#xff0c;联…

正确的原因是错误的:可解释的 ML 技术能否检测出虚假相关性?

Right for the Wrong Reason: Can Interpretable ML Techniques Detect Spurious Correlations? 摘要 虽然深度神经网络模型提供了无与伦比的分类性能&#xff0c;但它们容易在数据中学习虚假相关性。如果测试数据与训练数据来自相同的分布&#xff0c;则使用性能指标很难检…

mysql基础20——数据备份

数据备份 数据备份有2种 一种是物理备份 一种是逻辑备份 物理备份 物理备份 通过把数据文件复制出来 达到备份的目的 用得比较少 逻辑备份 逻辑备份 把描述数据库结构和内容的信息保存起来 达到备份的目的 是免费的 数据备份工具 mysqldump &#xff08;3种模式&#x…

【蓝桥杯2025备赛】集合求和

集合求和 题目描述 给定一个集合 s s s&#xff08;集合元素数量 ≤ 30 \le 30 ≤30&#xff09;&#xff0c;求出此集合所有子集元素之和。 输入格式 集合中的元素&#xff08;元素 ≤ 1000 \le 1000 ≤1000&#xff09; 输出格式 s s s 所有子集元素之和。 样例 #1 …

Java面试八股之marshalling和demarshalling

marshalling和demarshalling Marshalling&#xff08;序列化&#xff09;是将内存中的对象状态转化为适合传输或存储的格式&#xff08;如字节流、JSON、XML&#xff09;&#xff0c;以便进行网络通信、持久化存储或跨平台/语言交互操作。Demarshalling&#xff08;反序列化&a…

AI大模型探索之路-实战篇3:基于私有模型GLM-企业级知识库开发实战

文章目录 前言概述一、本地知识库核心架构回顾&#xff08;RAG&#xff09;1. 知识数据向量化2. 知识数据检索返回 二、大模型选择1. 模型选择标准2. ChatGLM3-6B 三、Embedding模型选择四、改造后的技术选型五、资源准备1. 安装git-lfs2. 下载GLM模型3. 下载Embeding模型 六、…

开源啦!一键部署免费使用!Kubernetes上直接运行大数据平台!

市场上首个K8s上的大数据平台&#xff0c;开源啦&#xff01; 智领云自主研发的首个 完全基于Kubernetes的容器化大数据平台 Kubernetes Data Platform (简称KDP) 开源啦&#x1f680;&#x1f680; 开发者只要准备好命令行工具&#xff0c;一键部署 Hadoop&#xff0c;Hi…

如何在Matplotlib中绘制平滑曲线

很多时候&#xff0c;我们有从非常分散的数据列表中生成的线图&#xff0c;这使得图形看起来像连接点的直线&#xff0c;或者非常密集&#xff0c;这导致数据点彼此非常接近&#xff0c;因此图看起来很混乱。 默认情况下&#xff0c;matplotlib.pyplot.plot()函数通过用直线连…

在protobuf里定义描述rpc方法的类型

service UserServiceRpc //在test.proto中定义 { rpc Login(LoginRequest)returns(LoginResponse); rpc GetFriendLists(GetFriendListRequest)returns(GetFriendListResponse); } test.proto文件生成test.pb.cc protoc test.proto --cpp_out./ 将生成的…

IDM的实用功能介绍+下载地址

下载地址 &#xff1a; 下载到idm 互联网下载管理器&#xff08;IDM&#xff09;实用功能概述 1. 多线程下载 IDM使用多线程技术&#xff0c;将文件分割成多个部分同时下载&#xff0c;显著提高下载速度。 2. 计划任务 用户可以设定下载任务的开始时间&#xff0c;甚至在特…

Wpf 使用 Prism 实战开发Day21

配置默认首页 当应用程序启动时&#xff0c;默认显示首页 一.实现思路&#xff0c;通过自定义接口来配置应用程序加载完成时&#xff0c;设置默认显示页 步骤1.创建自定义 IConfigureService 接口 namespace MyToDo.Common {/// <summary>/// 配置默认显示页接口/// <…

在一台笔记本电脑上试用Ubuntu22.04

在一台笔记本电脑上试用Ubuntu22.04。 本来想看以下该操作系统能否识别笔记本电脑上的硬盘&#xff0c;于是下载试一下。选了一个国内镜像网站下载。下载速度很快。下载以后用软件win image 将下载的iso文件写到U盘上&#xff0c;用的是usb2.0的U盘&#xff0c;该操作用时11分…

jmeter及PTS压测介绍和使用

一、常用压测工具&#xff1a; loadrunner apache ab&#xff08;单接口压测最方便&#xff09; jmeter 阿里云PTS&#xff08;原生上传jmeter脚本进行压测&#xff09; 二、jmeter可以压测不同的协议和应用 web http https jdbc for database TCP 三、使用场景及优点 1、功能…

【Qt】探索Qt框架:跨平台GUI开发的利器

文章目录 1. Qt框架概述1.1. Qt框架的优点1.2. Qt框架支持的系统1.3. Qt开发环境 2. 搭建 Qt 开发环境2.1. Qt SDK 的下载和安装2.2. 新建项目: 3. Qt 框架内容简介总结 在当今软件开发领域&#xff0c;跨平台性和用户界面的友好性是至关重要的。而Qt框架作为一款跨平台的C图形…

SQLite的知名用户(二十九)

返回&#xff1a;SQLite—系列文章目录 上一篇:SQLite作为应用程序文件格式&#xff08;二十八&#xff09; 下一篇:SQLite FTS5 扩展&#xff08;三十&#xff09; SQLite被数以百万计的应用程序使用 从字面上看&#xff0c;有数十亿次部署。 SQLite 是 当今世界。 下面…

面试高频:HTTPS 通信流程

更多大厂面试内容可见 -> http://11come.cn 面试高频&#xff1a;HTTPS 通信流程 HTTPS 的加密流程 接下来说一下 HTTPS 协议是如何进行通信的&#xff1a; HTTPS 通信使用的 对称加密 非对称加密 两者结合的算法 HTTPS 通信时&#xff0c;会先使用 非对称加密 让通信双…

C# WPF布局

布局&#xff1a; 1、Grid: <Window x:Class"WpfApp2.MainWindow" xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d"http://schemas.microsoft.com…

spring版本介绍

Spring Framework 是一个广泛使用的 Java 平台&#xff0c;用于构建企业级应用程序。它提供了一个全面的编程和配置模型&#xff0c;支持现代 Java 应用程序的最佳实践&#xff0c;如依赖注入、面向切面编程以及基于注解的编程模型。自从 Spring 1.0 发布以来&#xff0c;已经经…