`
oldrev
  • 浏览: 233380 次
  • 性别: Icon_minigender_1
  • 来自: 昆明
社区版块
存档分类
最新评论

port boost.variant to D

阅读更多
今晚无聊,完整用D实现了Boost.Variant 的绝大部分,权当娱乐了。


1 // Module: variant.d
2 // Author: Oldrev (wstring#AT#gmail.com)
3 // License: BSD
4
5 module dust.meta.variant;
6
7 import std.typetuple;
8 import std.traits;
9
10 private template MaxSizeImp(T, V...)
11 {
12 static if(V.length > 0)
13 private const int tailResult = MaxSizeImp!(V).result;
14 else
15 private const int tailResult = T.sizeof;
16
17 public const int result = T.sizeof > tailResult ? T.sizeof : tailResult;
18 };
19
20 template MaxSize(TList...)
21 {
22 const int MaxSize = MaxSizeImp!(TList).result;
23 }
24
25 struct Variant(TList...)
26 {
27 public alias TList TypeList;
28 public alias Variant!(TypeList) SelfType;
29 private alias ubyte[MaxSize!(TypeList)] Holder;
30
31 private Holder m_held;
32 private int m_which = -1;
33
34 public int which()
35 {
36 return m_which;
37 }
38
39 public SelfType assign(ValueType)(ValueType val)
40 {
41 static if(is(ValueType == SelfType))
42 {
43 foreach(T; TypeList)
44 {
45 const int i = IndexOf!(T, TypeList);
46 if(val.which == i)
47 {
48 assign!(T)(val.get!(T));
49 m_which = i;
50 }
51 }
52 }
53 else
54 {
55 const int i = IndexOf!(ValueType, TypeList);
56 static assert(i >= 0);
57 ValueType* heldPtr = cast(ValueType*)m_held.ptr;
58 *heldPtr = val;
59 m_which = i;
60 }
61
62 return *this;
63 }
64
65 public SelfType opAssign(ValueType)(ValueType rhs)
66 {
67 return assign!(ValueType)(rhs);
68 }
69
70 public bool opEquals(ValueType)(ValueType rhs)
71 {
72 static if(is(ValueType == SelfType))
73 {
74 foreach(T; TypeList)
75 {
76 const int i = IndexOf!(T, TypeList);
77 if(i == which)
78 {
79 return (rhs.which == which) && (get!(T) == rhs.get!(T));
80 }
81 }
82 }
83 else
84 {
85 const int i = IndexOf!(ValueType, TypeList);
86 static assert(i >= 0);
87
88 ValueType* heldPtr = cast(ValueType*)m_held.ptr;
89 return *heldPtr == rhs;
90 }
91 }
92
93 public int opCmp(ValueType)(ValueType rhs)
94 {
95 if(rhs == *this)return 0;
96 static if(is(ValueType == SelfType))
97 {
98 foreach(T; TypeList)
99 {
100 const int i = IndexOf!(T, TypeList);
101 if((i == which) && (rhs.which == which))
102 {
103 return get!(T) < rhs.get!(T) ? -1 : 1;
104 }
105 }
106 }
107 else
108 {
109 const int i = IndexOf!(ValueType, TypeList);
110 static assert(i >= 0);
111
112 ValueType* heldPtr = cast(ValueType*)m_held.ptr;
113 return *heldPtr < rhs ? -1 : 1;
114 }
115 }
116
117 public TypeInfo type()
118 {
119 foreach(T; TypeList)
120 {
121 const int i = IndexOf!(T, TypeList);
122 if(i == which)
123 {
124 return typeid(TypeList[i]);
125 }
126 }
127 }
128
129 public ValueType get(ValueType)()
130 {
131 return *(cast(ValueType*)m_held.ptr);
132 }
133
134 public bool empty()
135 {
136 return m_which < 0;
137 }
138
139 public bool isKindOf(ValueType)(ValueType val)
140 {
141 const int i = IndexOf!(ValueType, TypeList);
142 static assert(i >= 0);
143 return which == i;
144 }
145
146 }
147
148 unittest
149 {
150 class Foo
151 {
152 public:
153 int n = 0;
154 int x = 0;
155 int y = 0;
156 int z = 0;
157
158 Foo opAssign(int rhs)
159 {
160 z = rhs;
161 return this;
162 }
163 }
164
165 Variant!(double, char, int, char[], Foo) v;
166 v = 2;
167 assert(v == 2);
168 v = 2.22;
169 assert(v == 2.22);
170 assert(v.type == typeid(double));
171 v = new Foo;
172 assert(v.type == typeid(Foo));
173 v.get!(Foo)() = 2;
174 assert(v.get!(Foo)().z == 2);
175 typeof(v) v2 = v;
176 assert(v2 == v);
177 assert(v <= 2);
178 v = cast(char[])"Foobar";
179 assert(v == cast(char[])"Foobar");
180
181 }
分享到:
评论
1 楼 oldrev 2007-04-24  
1.013 终极版:

private template MaxSizeImp(T, V...)
{
    static if(V.length > 0)
        private const int tailResult = MaxSizeImp!(V).result;
    else 
        private const int tailResult = T.sizeof;

    public const int result = T.sizeof > tailResult ? T.sizeof : tailResult;
};

private template MaxSize(TList...)
{
    const int MaxSize = MaxSizeImp!(TList).result;
}


/**
  \brief A Variant implemention inspired by boost.variant
*/
struct Variant(TList...)
{
    public alias TList TypeList;
    public alias Variant!(TypeList) SelfType;
	private alias ubyte[MaxSize!(TypeList)] Holder;

    private Holder  m_held;
    private int     m_which = -1;

	template Which(T)
	{
		const int Which = IndexOf!(T, TypeList);
	}

    public static SelfType opCall(ValueType)(ValueType val)
    {
        SelfType var;
        var = val;
        return var;
    }

    public int which()
    {
        return m_which;
    }

	public SelfType opAssign(ValueType)(ValueType val)
	{
		static if(is(ValueType == SelfType))
		{
			m_held[] = val.m_held[];
			m_which = val.which;
		}
		else
		{
			const int i = IndexOf!(ValueType, TypeList);
			static assert(i >= 0);
			ValueType* heldPtr = cast(ValueType*)m_held.ptr;
			*heldPtr = val;
			m_which = i;
		}

		return *this;
	}

	public bool opEquals(ValueType)(ValueType rhs)
	{
        assert(!empty);

		static if(is(ValueType == SelfType))
		{
			foreach(T; TypeList)
			{
				const int i = IndexOf!(T, TypeList);
				if(i == which)
				{
					return (rhs.which == which) && (get!(T) == rhs.get!(T));
				}
			}
		}
		else
		{
			const int i = IndexOf!(ValueType, TypeList);
			static assert(i >= 0);
		
			return get!(ValueType)() == rhs;
		}
	}


	public int opCmp(ValueType)(ValueType rhs) //used for hash or something else
	out(result)
	{
		assert(result == 0 || result == 1 || result == -1);
	}
	body
	{
		if(rhs == *this)return 0;

		static if(is(ValueType == SelfType))
		{
			foreach(T; TypeList)
			{
				const int i = IndexOf!(T, TypeList);
				if((i == which) && (rhs.which == which))
				{
					return get!(T) < rhs.get!(T) ? -1 : 1;
				}
			}
		}
		else
		{
			const int i = IndexOf!(ValueType, TypeList);
			static assert(i >= 0);
		
			return get!(ValueType)() < rhs ? -1 : 1;
		}
	}
	
	public TypeInfo type()
	{
		foreach(T; TypeList)
		{
			const int i = IndexOf!(T, TypeList);
			if(i == which)
			{
				return typeid(TypeList[i]);
			}
		}
	}

    public ValueType get(ValueType)()
    {		
        assert(IndexOf!(ValueType, TypeList) == which) ;

        return *(cast(ValueType*)m_held.ptr);
    }

    public bool empty()
    {
        return m_which < 0;
    }

	public void swap(ref SelfType var)
	{
		Holder h;
		h[] = m_held[];
		int w = which;
		m_held[] = var.m_held[];
		m_which = var.which;
		var.m_held[] = h[];
		var.m_which = w;
	}

}

相关推荐

    Boost.Asio c++网络编程源码

    此外,C++17的`std::variant`和`std::optional`也能增强Boost.Asio的错误处理能力。 7. **示例解析**: `Example_Of_Asio`文件夹中的例子可能包含了各种网络通信模式,如服务器端和客户端的创建,数据的发送和接收...

    浅析C++中boost.variant的几种访问方法

    Boost.Variant Variant库包含一个不同于union的泛型类,用于在存储和操作来自于不同类型的对象。这个库的一个特点是支持类型安全的访问,减少了不同数据类型的类型转换代码的共同问题。 Variant 库如何改进你的程序...

    Beyond.the.C++.Standard.Library.An.Introduction.to.Boost.pdf

    Boost中的实用工具类简化了编程,例如`Boost.Any`可以存储任意类型的对象,而`Boost.Variant`则可以存储一组预定义类型的其中一个。 4. 容器和数据结构(Containers and Data Structures): Boost提供了一些灵活的...

    THE BOOST C++ LIBRARIES

    THE BOOST C++ LIBRARIES是一份自己编译的chm格式文档,描述了...14.4 Boost.Variant 14.5 Exercises Chapter 15: Error Handling 15.1 General 15.2 Boost.System 15.3 Boost.Exception Chapter 16: Cast Operators

    boost.tar.gz

    5. **类型安全和错误处理**:Boost库的`boost::optional`、`boost::variant`和`boost::any`等组件增强了类型安全,使得程序更健壮。同时,`boost::spirit`库则提供了一种高级的解析器构造框架,有助于避免语法错误。...

    variant, Eggs.Variant 是 C 11/14/17 泛型,类型安全,可以识别的联合.zip

    variant, Eggs.Variant 是 C 11/14/17 泛型,类型安全,可以识别的联合 Eggs.Variant简介英镑 Eggs.Variant 为英镑 C 11/14/17 型,类型安全,可以区分。 参见 http://eggs-cpp.github.io/variant/的文档。要求库...

    boost中文手册.rar

    这部分可能会讲解如何配置环境,如何编译和链接Boost库,以及如何开始使用一些基础的Boost组件,例如智能指针(shared_ptr、unique_ptr)和容器(如any、variant)。 开发手册则深入到Boost的各个模块,详细解释每...

    json序列化的库Kapok.zip

    kapok是一个高性能跨平台的对象-json序列化的库,对象序列化后是标准的... kapok除了支持结构体、容器和数组之外,还支持boost.optional和boost.variant,使用起来非常方便。 详细信息请看这里。 标签:Kapok

    boost-build-2.0-m12

    7. **VARIANT系统**:Boost.Build的VARIANT系统允许构建不同配置的目标,如调试和发布版本,或者针对不同硬件架构的版本。 8. **多工具集支持**:Boost.Build可以同时处理多个工具集(编译器和链接器的组合),这...

    超越C++标准库-boost程序库导论

    - **Boost.Variant**:支持多种类型的联合体。 - **Boost.Tuple**:提供固定大小的元组类型。 #### Smart_ptr库 - **scoped_ptr**:拥有一个非共享资源的所有权,并在其作用域结束时自动释放资源。 - **scoped_...

    boost中文手册C++

    3. 容器扩展:Boost库扩展了标准库中的容器,如multi_array用于多维数组,unordered_map和unordered_set提供了更高效的哈希表实现,variant则用于存储多种类型的值。 4. 算法:Boost库包含了大量算法,例如foreach...

    boost最新官方帮助文档1.56.0

    此外,`boost::variant`和`boost::any`可以处理多种类型的数据。 6. **编译时元编程**:`boost.preprocessor`库提供了丰富的宏元编程工具,而`boost.type_traits`库则提供了类型属性检查和类型转换。 7. **序列化*...

    C++ BOOST 库中文指南

    - **数据结构**:熟悉Boost库中提供的各种高效数据结构,如元组、`Boost.Any`、`Boost.Variant`等。 - **错误处理**:掌握错误处理的最佳实践,包括`Boost.System`和`Boost.Exception`的使用方法。 - **类型转换操作...

    STL_Boost.doc

    - `Variant`:可以持有多种类型的联合体。 3. 迭代器库: - `GIL`:图像库中的迭代器。 - `Graph`:图结构的迭代器。 - `Iterators`:创建新迭代器的框架。 - `Operators`:简化操作符重载。 - `Tokenizer`:...

    firebreath控件需要的boost

    7. **算法和容器**:Boost还提供了许多增强的算法和容器,如`foreach`宏、`variant`类型、`multi_array`等,这些工具可以提升代码的可读性和效率。 8. **元编程**:Boost.MPL和Boost.TypeTraits等库提供了元编程...

    C++11/14高级编程 Boost程序库探秘 中文版 第三版 高清完整

    7. **Boost.Any** 和 **Boost_variant**:存储任意类型数据的容器,增强了代码的灵活性。 通过学习这本书,读者不仅可以掌握C++11和C++14的现代编程技巧,还能深入了解Boost库的应用,提高编程效率,编写出更高效、...

    boost_1_34_0的包含文件(boost目录下的全部文件)

    Boost库的核心目标是推动C++标准的发展,并且很多Boost库最终被纳入到了C++标准库中,例如`shared_ptr`、`unique_ptr`、`bind`、`lambda`、`variant`和`tuple`等。下面将详细探讨一些在`boost_1_34_0`中重要的库和...

    linux下编译boost.python简单方法

    ### Linux下编译Boost.Python的方法详解 #### 一、引言 在现代软件开发中,混合编程(例如C++与Python结合)变得越来越常见。Boost.Python库作为连接这两种语言的强大桥梁,使得C++代码能够轻松地调用Python脚本...

    java-jacob 打印

    The package names replace com.ms with com.jacob (for example com.ms.com.Variant maps to com.jacob.com.Variant. jacob.dll: a small Win32 DLL which you must add to your PATH. samples: provided in ...

Global site tag (gtag.js) - Google Analytics