18
Optional?

Optional?. Agenda Type traits intro Interface & usage Caveats

Embed Size (px)

Citation preview

Page 1: Optional?. Agenda Type traits intro Interface & usage Caveats

Optional?

Page 2: Optional?. Agenda Type traits intro Interface & usage Caveats

Agenda• Type traits intro• Interface & usage• Caveats

Page 3: 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

Page 4: Optional?. Agenda Type traits intro Interface & usage Caveats

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

Page 5: Optional?. Agenda Type traits intro Interface & usage Caveats

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; }};

Page 6: Optional?. Agenda Type traits intro Interface & usage Caveats

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}

Page 7: Optional?. Agenda Type traits intro Interface & usage Caveats

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;

Page 8: Optional?. Agenda Type traits intro Interface & usage Caveats

Basic usage

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

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

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

Page 9: Optional?. Agenda Type traits intro Interface & usage Caveats

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

Page 10: Optional?. Agenda Type traits intro Interface & usage Caveats

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

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

Page 11: Optional?. Agenda Type traits intro Interface & usage Caveats

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

Page 12: Optional?. Agenda Type traits intro Interface & usage Caveats

Expressive interface

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

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

Page 13: Optional?. Agenda Type traits intro Interface & usage Caveats

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

Page 14: Optional?. Agenda Type traits intro Interface & usage Caveats

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

Page 15: Optional?. Agenda Type traits intro Interface & usage Caveats

Aligned types double in size

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

For Vec3, the pad data can be used

Page 16: Optional?. Agenda Type traits intro Interface & usage Caveats

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

Page 17: Optional?. Agenda Type traits intro Interface & usage Caveats

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

Page 18: Optional?. Agenda Type traits intro Interface & usage Caveats

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