Optional?. Agenda Type traits intro Interface & usage Caveats

Preview:

Citation preview

Optional?

Agenda• Type traits intro• Interface & usage• Caveats

Why?• Uninitialized variables cause lots of bugs• Removes much need for 2-stage initialization of objects• A cheap 0 or 1 element container• Internal storage. Much preferable over scoped_ptr + heap

allocation• Much less bloat & faster compilation than boost::optional

Type traits are meta functions!

is_integer<int>::value => trueis_floating_point<int>::value => falsealignment_of<Vec3>::value => 128remove_reference<T&>::type => Tis_same<int, float>::value => falseis_convertible<int, uint>::value => true

• Very useful when writing generic code

Implemented with template specialization// Defaulttemplate<class T>struct is_floating_point{ enum { value = false; }};

template<>struct is_floating_point<float>{ enum { value = true; }};

template<>struct is_floating_point<double>{ enum { value = true; }};

Useful for static dispatch, among other things..template<class T>T my_cool_algorithm(T t){ return my_cool_algorithm_impl<T, is_floating_point<T>::value>(t);}

template<class T, bool>T my_cool_algorithm_impl(T t);

template<class T, true>T my_cool_algorithm_impl(T t){ // int optimized version}

template<class T, false>T my_cool_algorithm_impl(T t){ // float optimized version}

Optional interfacestruct Nothing {};

template <class T>class Optional {

Optional();Optional(Nothing); // Note implicitOptional(const T& value); // Note implicitOptional(const Optional<T>& copy);

Optional<T>& operator=(Nothing);Optional<T>& operator=(const T& value);Optional<T>& operator=(const Optional<T>& rhs);

bool isSet() const;

/// @pre isSet()T& get(); const T& get() const;

};

// Override placement new to allow constructing elements without copyingtemplate<class T> inline void* operator new(size_t, fb::Optional<T>& optional);

// Convenience functiontemplate<class T>const T& getValueOr(const Optional<T>& optional, const T& defaultValue) const; template<class T>T& getValueOr(Optional<T>& optional, T& defaultValue) const;

Basic usage

Optional<int> i;ASSERT(!i.isSet());

i = 23;ASSERT(i.isSet() && i.get()==23);

i = Nothing();ASSERT(!i.isSet());

Return from functions

// C stylebool sqrt(double n, double& result); Optional<double> sqrt(double n);

• Client code won’t forget to check the bool• All-or-nothing guarantee, can’t break output variables

Member variables not always validclass X { Optional<uint> m_resultCache;};

• Clearer than using -1 or other "invalid values“

Single item container

class X { Optional<Weapon> m_activeWeapon;};

• Does not require DefaultConstructible objects• No heap allocations! Uses placement new internally• Useful to store RAII objects

Expressive interface

class X { void setLookForEnemyAroundPosition( const Optional<Vec3>& position);

const Optional<Vec3>& getLookForEnemyAroundPosition();};

Simplifying code

class Target { // Remove, use optional instead! bool isValid() const;};

void foo(Optional<Target> t);void bar(Target t);void baz(Target t);

• Often little code that need complexity of invalid objects• Helps maintenance – expressive client code

Caveats in current implementation• Aligned types double in size• No implicit bool conversion• Unnecessary branch for some types

Most of them can be fixed simply

Aligned types double in size

sizeof(Optional<Vec3>) == 2 * sizeof(Vec3)

For Vec3, the pad data can be used

No implicit bool conversion• Missing safe implicit type conversion to bool if (Optional<double> xRoot = sqrt(x))

Unnecessary branch for some types

~Optional() {if (!HasTrivialDestructor<T>::Value &&

m_initialized) m_storage.destruct();

}

Will get C++0x features in all of our compilers soonUntil then types can be registered as having a trivial, no-

op destructor

Further reading

Unit tests in OptionalTest.cpp

Static tests in HasTrivialDestructor.cpp, AlignedStorage.cpp and Optional.cpp

Design rationale for boost.optionalhttp://www.boost.org/doc/libs/1_38_0/libs/optional/doc/html/boost_optional/development.html

Nullable i C# http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx

Recommended