[optional] using name boost::in_place -- need your opinion/advice
Hi Everyone, I have stumbled upon a problem that I do not know how to address. I would like to seek an advice from the people in this list. I am trying to make boost::optional resemble std::optional (where it is reasonably easy to achieve). std::optional has this nice and useful "placement" constructor: std::optionalstd::mutex m {std::in_place}; std::in_place is a tag type, that instructs std::optional to create an object using placement-new syntax, from the provided arguments (zero in the example), without incurring any move construction. I cannot easily copy 1-to-1 this solution, because in namespace boost name in_place is reserved for the in-place factories: http://www.boost.org/doc/libs/1_61_0/libs/utility/in_place_factories.html I could simply go with a different name for a tag, but something tells me it would introduce an unnecessary complications for users that want to migrate from one optional to another. I could hack in-place factories so that they can also be used as a tag, although, I am not sure it is doable in a type-safe manner, and if it would not confuse people to have this boost::in_place do a number of different things. I could use a different namespace, but again, this might look surprising.I am a bit torn. I wonder if anyone here needed to face a similar problem, and if you can think of an elegant solution. Thanks, &rzej
On Monday, 30 May 2016 12:13:04 MSK Andrzej Krzemienski wrote:
Hi Everyone, I have stumbled upon a problem that I do not know how to address. I would like to seek an advice from the people in this list.
I am trying to make boost::optional resemble std::optional (where it is reasonably easy to achieve). std::optional has this nice and useful "placement" constructor:
std::optionalstd::mutex m {std::in_place};
std::in_place is a tag type, that instructs std::optional to create an object using placement-new syntax, from the provided arguments (zero in the example), without incurring any move construction.
I cannot easily copy 1-to-1 this solution, because in namespace boost name in_place is reserved for the in-place factories: http://www.boost.org/doc/libs/1_61_0/libs/utility/in_place_factories.html
If not the typed in-place factories, you could transform in_place to be a namespace scope function object and use it as a tag in the optional constructor. The typed in-place factories ruin the solution though, even if not used by optional.
I could simply go with a different name for a tag, but something tells me it would introduce an unnecessary complications for users that want to migrate from one optional to another. I could hack in-place factories so that they can also be used as a tag, although, I am not sure it is doable in a type-safe manner, and if it would not confuse people to have this boost::in_place do a number of different things.
I could use a different namespace, but again, this might look surprising.I am a bit torn.
I think that would be the best solution. Additionally, I would suggest moving the whole library to its own namespace (e.g. optionals). Then the tag in the library namespace would look more natural. For backward compatibility you could import the optional class template into boost namespace.
2016-05-30 11:29 GMT+02:00 Andrey Semashev
Hi Everyone, I have stumbled upon a problem that I do not know how to address. I would like to seek an advice from the people in this list.
I am trying to make boost::optional resemble std::optional (where it is reasonably easy to achieve). std::optional has this nice and useful "placement" constructor:
std::optionalstd::mutex m {std::in_place};
std::in_place is a tag type, that instructs std::optional to create an object using placement-new syntax, from the provided arguments (zero in
On Monday, 30 May 2016 12:13:04 MSK Andrzej Krzemienski wrote: the
example), without incurring any move construction.
I cannot easily copy 1-to-1 this solution, because in namespace boost name in_place is reserved for the in-place factories:
http://www.boost.org/doc/libs/1_61_0/libs/utility/in_place_factories.html
If not the typed in-place factories, you could transform in_place to be a namespace scope function object and use it as a tag in the optional constructor.
+1
The typed in-place factories ruin the solution though, even if not used by optional.
How so?
I could simply go with a different name for a tag, but something tells me it would introduce an unnecessary complications for users that want to migrate from one optional to another. I could hack in-place factories so that they can also be used as a tag, although, I am not sure it is doable in a type-safe manner, and if it would not confuse people to have this boost::in_place do a number of different things.
I could use a different namespace, but again, this might look surprising.I am a bit torn.
I think that would be the best solution. Additionally, I would suggest moving the whole library to its own namespace (e.g. optionals). Then the tag in the library namespace would look more natural. For backward compatibility you could import the optional class template into boost namespace.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
2016-05-30 11:29 GMT+02:00 Andrey Semashev
: The typed in-place factories ruin the solution though, even if not used by
On Monday, 30 May 2016 13:45:28 MSK Krzysztof Czainski wrote: optional.
How so?
Typed in-place factory requires an explicit template parameter to be specified, which is not achievable if in_place is an object.
2016-05-30 12:46 GMT+02:00 Andrey Semashev
2016-05-30 11:29 GMT+02:00 Andrey Semashev
: The typed in-place factories ruin the solution though, even if not used by
On Monday, 30 May 2016 13:45:28 MSK Krzysztof Czainski wrote: optional.
How so?
Typed in-place factory requires an explicit template parameter to be specified, which is not achievable if in_place is an object.
Oh yeah. Too bad a variable template cannot be "overloaded" with the non-template function object.
2016-05-30 13:21 GMT+02:00 Krzysztof Czainski <1czajnik@gmail.com>:
2016-05-30 12:46 GMT+02:00 Andrey Semashev
: 2016-05-30 11:29 GMT+02:00 Andrey Semashev
: The typed in-place factories ruin the solution though, even if not used by
On Monday, 30 May 2016 13:45:28 MSK Krzysztof Czainski wrote: optional.
How so?
Typed in-place factory requires an explicit template parameter to be specified, which is not achievable if in_place is an object.
Oh yeah. Too bad a variable template cannot be "overloaded" with the non-template function object.
Maybe in_place can be hacked as is without changing it to a function
object? Here's a proof of concept. It compiles [1], so it seems 'in_place'
can be used as a tag with the current implementation of boost::in_place()
overloads.
[1] http://ideone.com/zzbwq4
1. struct in_place_factory0 {};
2.
3. in_place_factory0 in_place() {}
4. template <class T> void in_place(T) {}
5. template
2016-05-30 11:29 GMT+02:00 Andrey Semashev
Hi Everyone, I have stumbled upon a problem that I do not know how to address. I would like to seek an advice from the people in this list.
I am trying to make boost::optional resemble std::optional (where it is reasonably easy to achieve). std::optional has this nice and useful "placement" constructor:
std::optionalstd::mutex m {std::in_place};
std::in_place is a tag type, that instructs std::optional to create an object using placement-new syntax, from the provided arguments (zero in
On Monday, 30 May 2016 12:13:04 MSK Andrzej Krzemienski wrote: the
example), without incurring any move construction.
I cannot easily copy 1-to-1 this solution, because in namespace boost name in_place is reserved for the in-place factories:
http://www.boost.org/doc/libs/1_61_0/libs/utility/in_place_factories.html
If not the typed in-place factories, you could transform in_place to be a namespace scope function object and use it as a tag in the optional constructor. The typed in-place factories ruin the solution though, even if not used by optional.
I could simply go with a different name for a tag, but something tells me it would introduce an unnecessary complications for users that want to migrate from one optional to another. I could hack in-place factories so that they can also be used as a tag, although, I am not sure it is doable in a type-safe manner, and if it would not confuse people to have this boost::in_place do a number of different things.
I could use a different namespace, but again, this might look surprising.I am a bit torn.
I think that would be the best solution. Additionally, I would suggest moving the whole library to its own namespace (e.g. optionals). Then the tag in the library namespace would look more natural. For backward compatibility you could import the optional class template into boost namespace.
Hmm. Moving optional to a nested namespace has other benefits also: disabling unintended ADL. But I can't see how I can be made to work for a tag like in_place. If I put it also into a nested namespace and then do a: namespace boost{ using nested::in_place } It will still collide with the current in-place factories. Or did I misunderstand your suggestion? Regards, &rzej
On Monday, 30 May 2016 13:52:20 MSK Andrzej Krzemienski wrote:
2016-05-30 11:29 GMT+02:00 Andrey Semashev
: I think that would be the best solution. Additionally, I would suggest moving the whole library to its own namespace (e.g. optionals). Then the tag in the library namespace would look more natural. For backward compatibility you could import the optional class template into boost namespace.
Hmm. Moving optional to a nested namespace has other benefits also: disabling unintended ADL.
Exactly.
But I can't see how I can be made to work for a tag like in_place.
If I put it also into a nested namespace and then do a:
namespace boost{ using nested::in_place }
It will still collide with the current in-place factories. Or did I misunderstand your suggestion?
No, I wasn't suggesting importing boost::optionals::in_place into boost. Only import what is currently considered API (i.e. the optional template; I don't think anything else qualifies as such). Also document the change and deprecate the imports so that people start porting to the nested namespace. You can remove the imports when you feel it's safe. This could also be done for boost::none as well for good measure.
2016-05-30 12:57 GMT+02:00 Andrey Semashev
2016-05-30 11:29 GMT+02:00 Andrey Semashev
: I think that would be the best solution. Additionally, I would suggest moving the whole library to its own namespace (e.g. optionals). Then the tag in the
namespace would look more natural. For backward compatibility you could import
On Monday, 30 May 2016 13:52:20 MSK Andrzej Krzemienski wrote: library the
optional class template into boost namespace.
Hmm. Moving optional to a nested namespace has other benefits also: disabling unintended ADL.
Exactly.
But I can't see how I can be made to work for a tag like in_place.
If I put it also into a nested namespace and then do a:
namespace boost{ using nested::in_place }
It will still collide with the current in-place factories. Or did I misunderstand your suggestion?
No, I wasn't suggesting importing boost::optionals::in_place into boost. Only import what is currently considered API (i.e. the optional template; I don't think anything else qualifies as such). Also document the change and deprecate the imports so that people start porting to the nested namespace. You can remove the imports when you feel it's safe.
This could also be done for boost::none as well for good measure.
But wouldn't that be a bit of an inconvenience that a "vocabulary type" as common as Optional should be used with additional long namespace prefix (or users required to type a using declaration themselves everywhere)? Regards, &rzej
On Monday, 30 May 2016 14:14:02 MSK Andrzej Krzemienski wrote:
2016-05-30 12:57 GMT+02:00 Andrey Semashev
: No, I wasn't suggesting importing boost::optionals::in_place into boost. Only import what is currently considered API (i.e. the optional template; I don't think anything else qualifies as such). Also document the change and deprecate the imports so that people start porting to the nested namespace. You can remove the imports when you feel it's safe.
This could also be done for boost::none as well for good measure.
But wouldn't that be a bit of an inconvenience that a "vocabulary type" as common as Optional should be used with additional long namespace prefix (or users required to type a using declaration themselves everywhere)?
I don't find that inconvenient. I would rather have every Boost library in its own namespace. Name clashes pose much much more inconvenience IMO.
Andrzej, On 2016-05-30 17:47, Andrzej Krzemienski wrote:
... I am trying to make boost::optional resemble std::optional (where it is reasonably easy to achieve). std::optional has this nice and useful "placement" constructor:
std::optionalstd::mutex m {std::in_place};
std::in_place is a tag type, that instructs std::optional to create an object using placement-new syntax, from the provided arguments (zero in the example), without incurring any move construction. ...
To me the situation sounds quite concerning as I'd expect boost libs to extend std counterparts, i.e. I suspect many people would expect boost::foo = std::foo + something-else-useful functionally-wise. That is, I'd personally expect the migration from boost::foo to std::foo to be a simple renaming matter (if I did not use extra boost functionality). The situation with in-place factories sounds like a diversion and you seem to suggest (if I've got it right) to move even further. Would not it be long-term proper to align boost::optional with std::optional? If that requires renaming boost in-place factories, then that might be a better long-term solution. If, say, that additional functionality is later scheduled for std inclusion.
2016-05-30 12:04 GMT+02:00 Vladimir Batov
Andrzej,
On 2016-05-30 17:47, Andrzej Krzemienski wrote:
... I am trying to make boost::optional resemble std::optional (where it is reasonably easy to achieve). std::optional has this nice and useful "placement" constructor:
std::optionalstd::mutex m {std::in_place};
std::in_place is a tag type, that instructs std::optional to create an object using placement-new syntax, from the provided arguments (zero in the example), without incurring any move construction. ...
To me the situation sounds quite concerning as I'd expect boost libs to extend std counterparts, i.e. I suspect many people would expect boost::foo = std::foo + something-else-useful functionally-wise. That is, I'd personally expect the migration from boost::foo to std::foo to be a simple renaming matter (if I did not use extra boost functionality).
The situation with in-place factories sounds like a diversion and you seem to suggest (if I've got it right) to move even further.
There seems to be some misunderstanding here. Indeed, there is currently a gap between std::optional and boost::optional: we have a name std::in_place, which is a tag, and we have a name boost::in_place, which is something different. More, boost::in_place is not part of Boost.Optional library: it is in Boost Utility Library. I am exploring the possibility of closing the gap between two optionals, I just don't see how to do it without breaking the backwards compatibility for Boost users.
Would not it be long-term proper to align boost::optional with std::optional? If that requires renaming boost in-place factories, then that might be a better long-term solution.
I read your suggestion as "rename current in-place factories form boost::in_place to something else". Is that right?
If, say, that additional functionality is later scheduled for std inclusion.
I am not sure what you mean here. I am pretty sure the in-place factories will never be standardized, as we have a superior solution in C++11: tags and perfect-forwarding of functions. Regards, &rzej
On 05/30/2016 08:46 PM, Andrzej Krzemienski wrote:
2016-05-30 12:04 GMT+02:00 Vladimir Batov:
Would not it be long-term proper to align boost::optional with std::optional? If that requires renaming boost in-place factories, then that might be a better long-term solution. I read your suggestion as "rename current in-place factories form boost::in_place to something else". Is that right?
I suspect that might be an unpleasant, unfortunate but essential move as Boost (or any other lib) IMO cannot possibly be changing, re-interpreting, re-implementing std concepts. The std lib is the center of C++ universe so to speak. Everything else are the ripples. If the "ripples" clash with std, they need to adjust. If boost::in_place is renamed to, say, in_place_factory, then the user inconvenience will be minimal with global rename. IMO. I understand that that might be beyond your boost::optional task/framework but I feel that'd be the right thing to do for the Boost ecosystem as a whole.
... I am pretty sure the in-place factories will never be standardized, as we have a superior solution in C++11: tags and perfect-forwarding of functions.
More reasons to do the right thing, i.e. to restore the std conformance.
participants (4)
-
Andrey Semashev
-
Andrzej Krzemienski
-
Krzysztof Czainski
-
Vladimir Batov