Copyright 2011 Daniel Krügler. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Alternative to boost::optional for C++11, supporting move-only types and optimizations by detecting type-traits.
Notes from Brian (of http://hostilefork.com) who put this code on GitHub:
In terms of compatibility with C++11,
boost::optionallacked support for move-only types (among some other issues). In 2012 there did not exist a viable reference implementation for astd::optionalfrom the group discussing it, so Daniel Krügler was willing to share his own implementation calledxstd::optionalunder a boost license. This was not intended to compete with the standards effort, but be a stopgap measure and to experiment with some particular implementation choices.
As of 2014 there is a reference implementation which is being vetted and known as
std::experimental::optional. It is available in another GitHub repository as a single header file:
https://github.com/akrzemi1/Optional/
Due to issues brought up during review, that specification is not slated to make it into C++14, but should be adopted in a later release.
Generally speaking the
std::experimental::optionalmanaged to handle all the cases I was working with. In order to bring the two into greater alignment, I updatedxstd::optionalto usenulloptinstead ofnoneto indicate an empty optional... and also added themake_optionalhelper function.
I discussed a situation that
xstd::experimental::optionalwas not able to handle with Andrzej Krzemieński, wherexstd::optionalwas able to work. That specifically related to the type trait of copy constructibility not being inherited by optional from the type it is parameterized with:
Andrzej felt that using a technique like Daniel's to provide this ability would complicate the code.
std::vectorand other classes are subject to the same failure to answer the trait correctly, so it didn't seem like a good tradeoff to do it when the scheduled C++ Concepts Lite compiler feature would solve it generally. There may be other differences, but that's the one I noticed.
As a general heads-up, one should observe that moving the contents out of an optional for a move-only type will not register that optional as being a
nullopt. It will consider itself to be containing a value unless you explicitly assign itnullopt. There was anextract()function inxstd::optionalwhich addressed this, but that is not currently planned for inclusion instd::experimental::optional:
Many thanks to Daniel and Andrzej for their code and time (and to everyone else working through the details...)