Optional
Download
1 / 18

Optional? - PowerPoint PPT Presentation


  • 109 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Optional?' - kaoru


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

Agenda
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
Type traits are meta functions!

is_integer<int>::value => true

is_floating_point<int>::value => false

alignment_of<Vec3>::value => 128

remove_reference<T&>::type => T

is_same<int, float>::value => false

is_convertible<int, uint>::value => true

  • Very useful when writing generic code


Implemented with template specialization
Implemented with template specialization

// Default

template<class T>

structis_floating_point

{

enum { value = false; }

};

template<>

structis_floating_point<float>

{

enum { value = true; }

};

template<>

structis_floating_point<double>

{

enum { value = true; }

};


Useful for static dispatch among other things
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 interface
Optional interface

struct Nothing {};

template <class T>

class Optional

{

Optional();

Optional(Nothing); // Note implicit

Optional(const T& value); // Note implicit

Optional(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 copying

template<class T>

inline void* operator new(size_t, fb::Optional<T>& optional);

// Convenience function

template<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
Basic usage

Optional<int> i;

ASSERT(!i.isSet());

i = 23;

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

i = Nothing();

ASSERT(!i.isSet());


R eturn from functions
Return from functions

// C style

bool 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 valid
Member variables not always valid

class X {

Optional<uint> m_resultCache;

};

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


Single item container
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
Expressive interface

class X {

void setLookForEnemyAroundPosition(

const Optional<Vec3>& position);

const Optional<Vec3>&

getLookForEnemyAroundPosition();

};


Simplifying code
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
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
Aligned types double in size

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

For Vec3, the pad data can be used


No implicit bool conversion
No implicit bool conversion

  • Missing safe implicit type conversion to bool

    if (Optional<double> xRoot = sqrt(x))


Unnecessary branch for some types
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 soon

Until then types can be registered as having a trivial, no-op destructor


Further reading
Further reading

Unit tests in OptionalTest.cpp

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

Design rationale for boost.optional

http://www.boost.org/doc/libs/1_38_0/libs/optional/doc/html/boost_optional/development.html

Nullablei C#

http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx


ad