Feature #3753
closedBackport std::optional
100%
Description
Create ndn::optional
as an alias of std::experimental::optional
or boost::optional
.
Updated by Junxiao Shi over 8 years ago
I added this snippet to .waf-tools/compiler-features.py
:
STD_EXPERIMENTAL_OPTIONAL = '''
#include <tuple>
#include <experimental/optional>
int
main()
{
std::experimental::optional<int> a(std::experimental::nullopt);
try {
a.value();
}
catch (const std::experimental::bad_optional_access&) {
}
auto b = std::experimental::make_optional(2);
auto c = std::experimental::make_optional<std::tuple<int, int>>(3, 4);
c = std::experimental::nullopt;
return 0;
}
'''
@conf
def check_experimental_optional(self):
if self.check_cxx(msg='Checking for std::experimental::optional',
fragment=STD_EXPERIMENTAL_OPTIONAL,
features='cxx', mandatory=False):
self.define('HAVE_STD_EXPERIMENTAL_OPTIONAL', 1)
But it returns "no" on both Ubuntu 16.04 and OSX 10.11.
Ubuntu 16.04 build/config.log
:
ESC[01mESC[K/usr/include/c++/5/bits/c++14_warning.h:32:2:ESC[mESC[K ESC[01;31mESC[Kerror: ESC[mESC[K#error This file requires compiler and library support for the forthcoming ISO C++ 2014 standard. This support is currently experimental, and must be enabled with the -std=c++1y or -std=gnu++1y compiler options.
#error This file requires compiler and library support for the forthcoming \
OSX 10.11 build/config.log
:
err: ESC[1m../test.cpp:7:22: ESC[0mESC[0;1;31merror: ESC[0mESC[1mno member named 'optional' in namespace 'std::experimental'ESC[0m
std::experimental::optional<int> a(std::experimental::nullopt);
ESC[0;1;32m ~~~~~~~~~~~~~~~~~~~^
/Applications/Xcode.app/Contents//Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/experimental/optional
contains
#if _LIBCPP_STD_VER > 11
which disables std::experimental::optional
despite I'm allowed to include the header.
Thus, I'll only use Boost.Optional.
Updated by Junxiao Shi over 8 years ago
- Status changed from In Progress to Code review
- % Done changed from 0 to 100
Updated by Junxiao Shi over 8 years ago
- Status changed from Code review to In Progress
- % Done changed from 100 to 50
https://gerrit.named-data.net/3126 patchset2 is not compiling on Ubuntu 14.04.
I only noticed difference in nullopt
and make_optional
when preparing that patchset.
There are more differences between Boost.Optional and C++17 std::optional
:
C++17 | Boost 1.54 | Boost 1.61 |
---|---|---|
nullopt |
none |
none |
in_place |
TypedInPlaceFactory | TypedInPlaceFactory |
has_value |
operator bool |
operator bool |
value |
get (w/assertion) |
value |
value_or |
get_value_or |
value_or |
Here are two choices:
- Implement
ndn::optional
class template according to C++17 spec. Make it implicitly convertible from and toboost::optional
. All calling code should use C++17 syntax. - Make
ndn::optional
an alias ofboost::optional
. All calling code should use Boost 1.54 syntax; this implies calling deprecatedget_value_or
in Boost 1.61 which could cause a warning.
Updated by Junxiao Shi over 8 years ago
- % Done changed from 50 to 80
20160823 NFD call decides to go with C++17 syntax. https://gerrit.named-data.net/3126 patchset3 implements so.
The following are in C++17 spec but I couldn't get them to work so they are not in current implementation:
- construct or emplace with
std::initializer_list
- compare with
nullopt
or plain value - move constructor
Updated by Alex Afanasyev over 8 years ago
This issue talk about backporting, but doesn't give any example on how you planning to use optional. I would have no opinion on the matter until then...
Updated by Davide Pesavento over 8 years ago
From http://en.cppreference.com/w/cpp/utility/optional :
A common use case for optional is the return value of a function that may fail. As opposed to other approaches, such as
std::pair<T, bool>
, optional handles expensive to construct objects well and is more readable, as the intent is expressed explicitly.
We could potentially replace every such usage of std::pair<T, bool>
with optional<T>
in our APIs.
Updated by Alex Afanasyev over 8 years ago
ok. Is it different much from using std::unique_ptr
?
Updated by Davide Pesavento over 8 years ago
std::unique_ptr
models a pointer (with exclusive ownership semantics), the pointed-to object has to be dynamically allocated somehow (by the user code). std::optional
models an object, no dynamic memory allocation ever takes place.
Updated by Alex Afanasyev over 8 years ago
Are you sure about no dynamic allocation? May be I'm misunderstanding the mechanism optional is implemented, but it seem that with make_optional
call there is somewhere inside a call for new
. No?
Updated by Davide Pesavento over 8 years ago
Yes I'm sure. optional
uses "placement new" to construct the contained object in place (as a member variable of the optional
object). make_optional
just perfectly forwards the arguments to optional
constructor.
[edit: I'm talking about a standard implementation, I haven't looked at how Junxiao implemented the backported version.]
Updated by Alex Afanasyev over 8 years ago
Got it.
As per note 1, the backported version is using only Boost.Optional, unless we allow C++17 syntax, which would require more changes in build scripts.
Updated by Davide Pesavento over 8 years ago
Alex Afanasyev wrote:
As per note 1, the backported version is using only Boost.Optional, unless we allow C++17 syntax, which would require more changes in build scripts.
Yeah I'm afraid that's the most viable option for now. We could use std::experimental::optional
with gcc-6 and later (e.g. in upcoming Ubuntu 16.10), once #3076 is implemented.
Updated by Junxiao Shi over 8 years ago
- Status changed from In Progress to Closed
- % Done changed from 80 to 100
Updated by Junxiao Shi over 6 years ago
- Status changed from Closed to Resolved
I notice optional::reset
is missing and it's added in https://gerrit.named-data.net/4669
Updated by Junxiao Shi over 6 years ago
I don't see much value in this TBH, just use
foo = nullopt;
The backport has to match C++17 standard, with all differences noted in \file
Doxygen. I'm surprised when reset
is missing.
I can either add the missing function, or add it as a "difference" in \file
Doxygen, and I chose the former.
Updated by Davide Pesavento over 6 years ago
I don't see much value in this TBH, just use
foo = nullopt;
I said that because we will soon be able to rely on std::experimental::optional
directly, thus the boost-based backport will soon die.
The backport has to match C++17 standard, with all differences noted in
\file
Doxygen.
You just made this up.
Updated by Davide Pesavento over 6 years ago
- Status changed from Resolved to Closed