Skip to content

Commit 80ba8e3

Browse files
committed
CDK: foundation: introduce cdk::opt<> template and fix copy semantics for cdk::variant<>.
1 parent d94dc38 commit 80ba8e3

File tree

2 files changed

+92
-6
lines changed

2 files changed

+92
-6
lines changed

cdk/include/mysql/cdk/foundation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ namespace cdk {
4646
using foundation::string;
4747
using foundation::scoped_ptr;
4848
using foundation::shared_ptr;
49+
using foundation::variant;
50+
using foundation::opt;
4951

5052
using foundation::bytes;
5153
using foundation::buffers;

cdk/include/mysql/cdk/foundation/variant.h

Lines changed: 90 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,13 @@ class variant_base<Size, Align, First, Rest...>
103103
variant_base(const First &val)
104104
: m_owns(true)
105105
{
106-
new (&m_storage) First(val);
106+
set(val);
107107
}
108108

109109
variant_base(First &&val)
110110
: m_owns(true)
111111
{
112-
new (&m_storage) First(std::move(val));
112+
set(std::move(val));
113113
}
114114

115115
template<typename T>
@@ -132,17 +132,24 @@ class variant_base<Size, Align, First, Rest...>
132132
{
133133
if (!other.m_owns)
134134
return;
135-
*reinterpret_cast<First*>(&m_storage)
136-
= *other.get((First*)nullptr);
135+
set(*other.get((First*)nullptr));
137136
}
138137

139138
variant_base(variant_base &&other)
140139
: Base(std::move(other))
141140
{
142141
if (!other.m_owns)
143142
return;
144-
*reinterpret_cast<First*>(&m_storage)
145-
= std::move(*other.get((First*)nullptr));
143+
set(std::move(*other.get((First*)nullptr)));
144+
}
145+
146+
variant_base& operator=(const variant_base &other)
147+
{
148+
if (other.m_owns)
149+
set(*other.get((First*)nullptr));
150+
else
151+
Base::operator=(static_cast<const Base&>(other));
152+
return *this;
146153
}
147154

148155
void set(const First &val)
@@ -264,6 +271,15 @@ class variant_base<Size, Align>
264271
{
265272
assert(false);
266273
}
274+
275+
void operator=(const variant_base&)
276+
{}
277+
278+
template<typename T>
279+
void operator=(const T&)
280+
{
281+
assert(false);
282+
}
267283
};
268284

269285
} // detail
@@ -277,6 +293,14 @@ class variant
277293
{
278294
typedef detail::variant_base<0,0,Types...> Base;
279295

296+
protected:
297+
298+
template <typename T>
299+
const T* get_ptr() const
300+
{
301+
return Base::get((const T*)nullptr);
302+
}
303+
280304
public:
281305

282306
variant() {}
@@ -299,6 +323,12 @@ class variant
299323
: Base(std::move(val))
300324
{}
301325

326+
variant& operator=(const variant &other)
327+
{
328+
Base::operator=(static_cast<const Base&>(other));
329+
return *this;
330+
}
331+
302332
template <typename T>
303333
variant& operator=(T&& val)
304334
{
@@ -334,6 +364,60 @@ class variant
334364
{
335365
return *Base::get((const T*)nullptr);
336366
}
367+
368+
template <typename T>
369+
const T* operator->() const
370+
{
371+
return get_ptr<T>();
372+
}
373+
};
374+
375+
376+
/*
377+
Object x of type opt<T> can be either empty or hold value of type T. In
378+
the latter case reference to stored object can be obtained with x.get()
379+
and stored object's methods can be called via operator->: x->method().
380+
*/
381+
382+
template < typename Type >
383+
class opt
384+
: private variant<Type>
385+
{
386+
typedef variant<Type> Base;
387+
388+
public:
389+
390+
opt()
391+
{}
392+
393+
opt(const opt &other)
394+
: Base(static_cast<const Base&>(other))
395+
{}
396+
397+
template <typename... T>
398+
opt(T... args)
399+
: Base(Type(args...))
400+
{}
401+
402+
opt& operator=(const opt &other)
403+
{
404+
Base::operator=(static_cast<const Base&>(other));
405+
return *this;
406+
}
407+
408+
opt& operator=(const Type& val)
409+
{
410+
Base::operator=(val);
411+
return *this;
412+
}
413+
414+
using Base::operator bool;
415+
using Base::get;
416+
417+
const Type* operator->() const
418+
{
419+
return Base::template get_ptr<Type>();
420+
}
337421
};
338422

339423

0 commit comments

Comments
 (0)