QEverCloud 6.1.0
Unofficial Evernote Cloud API for Qt
|
#include <Optional.h>
Public Member Functions | |
Optional () | |
Optional (const Optional &o) | |
template<typename X > | |
Optional (const Optional< X > &o) | |
Optional (const T &value) | |
template<typename X > | |
Optional (const X &value) | |
Optional & | operator= (const Optional &o) |
template<typename X > | |
Optional & | operator= (const Optional< X > &o) |
Optional & | operator= (const T &value) |
template<typename X > | |
Optional & | operator= (const X &value) |
operator const T & () const | |
operator T& () | |
const T & | ref () const |
T & | ref () |
bool | isSet () const |
Checks if value is set. | |
void | clear () |
Optional & | init () |
T * | operator-> () |
const T * | operator-> () const |
T | value (T defaultValue=T()) const |
bool | isEqual (const Optional< T > &other) const |
bool | operator== (const Optional< T > &other) const |
bool | operator!= (const Optional< T > &other) const |
bool | operator== (const T &other) const |
bool | operator!= (const T &other) const |
Optional (Optional &&other) | |
Optional & | operator= (Optional &&other) |
Optional (T &&other) | |
Optional & | operator= (T &&other) |
Friends | |
template<typename X > | |
class | Optional |
void | swap (Optional &first, Optional &second) |
Supports optional values.
Most of the fields in the Evernote API structs are optional. But C++ does not support this notion directly.
To implement the concept of optional values conventional Thrift C++ wrapper uses a special field of a struct type where each field is of type bool with the same name as a field in the struct. This bool flag indicated was the field with the same name in the outer struct assigned or not.
While this method have its advantages (obviousness and simplicity) I found it very inconvenient to work with. You have to check by hand that both values (value itself and its __isset flag) are in sync. There is no checks whatsoever against an error and such an error is too easy to make.
So for my library I created a special class that supports the optional value notion explicitly. Basically Optional class just holds a bool value that tracks the fact that a value was assigned. But this tracking is done automatically and attempts to use unassigned values throw exceptions. In this way errors are much harder to make and it's harder for them to slip through testing unnoticed too.
|
inline |
Default constructor. Default Optional is not set.
Copy constructor.
|
inline |
Template copy constructor. Allows to be initialized with Optional of any compatible type.
Initialization with a value of the type T. Note: it's implicit.
|
inline |
Template initialization with a value of any compatible type.
|
inline |
|
inline |
Clears an Optional.
|
inline |
Fast way to initialize an Optional with a default value.
It's very useful for structs.
Two optionals are equal if they are both not set or have equal values.
|
inline |
Implicit conversion of Optional<T> to T.
const version.
|
inline |
Implicit conversion of Optional<T> to T.
Note: a reference is returned, not a copy.
|
inline |
Two syntatic constructs come to mind to use for implementation of access to a struct's/class's field directly from Optional.
One is the dereference operator. This is what boost::optional uses. While it's conceptually nice I found it to be not a very convenient way to refer to structs, especially nested ones. So I overloaded the operator-> and use smart pointer semantics.
I admit, boost::optional is much more elegant overall. It uses pointer semantics quite clearly and in an instantly understandable way. It's universal (works for any type and not just structs). There is no need for implicit type concersions and so there is no subtleties because of it. And so on.
But then referring to struct fields is a chore. And this is the most common use case of Optionals in QEverCloud.
So I decided to use non-obvious-on-the-first-sight semantics for my Optional. IMO it's much more convenient when gotten used to.
const version.
Template assignment with an Optional of any compatible value.
Assignment with a value of the type T.
|
inline |
Template assignment with a value of any compatible type.
|
inline |
|
inline |
Returs reference to the holded value.
There are contexts in C++ where impicit type conversions can't help. For example:
Explicit type conversion can be used...
... but this is indeed ugly as hell.
So I implemented ref() function that returns a reference to the holded value.
Returs a reference to the holded value.
const version.