Re: [boost] feature request for optional

Fernando wrote:
[...] But when i store values where the type has an inline NaT value (for example NULL pointers) i cannot and need not use optional.
Can you explain why you cannot use optional<>? I definitely see that you don't need it, but for the sake of genericity I just wouldn't mind the fact that some types do have an identifiable null value and use optional<> all along.
Well i could use it but i do not want to. The space complexity is linear as i have to store it for every entry and a perfect hash could grow alot even for a small number of entries. Further arguments: The interface change would be backward compatible as you add a template parameter which has a default value (indicating the old behaviour). With the change i would have both the more optimal solution and the genericity. My problem is that the implementation of optional is not as trivial as it seems and i cannot wrap the class so i would have to copy and modify the source. And i guess using optional in containers and having both types of values (pointers are a good example for the inline NaT case) is not such a far fetched scenario. In the special case of pointers it would make sense not to have a static member indicating the null value but a Discriminate template parameter having the special value 'class NullPtrTag { };'. Another solution would be to make a detail::generic_optional with all the operator foo and let optional inherit from it. That would be infinitesimal backward-incompatible ;)

Sascha Krissler wrote:
Fernando wrote:
[...] But when i store values where the type has an inline NaT value (for example NULL pointers) i cannot and need not use optional.
Can you explain why you cannot use optional<>? I definitely see that you don't need it, but for the sake of genericity I just wouldn't mind the fact that some types do have an identifiable null value and use optional<> all along.
Well i could use it but i do not want to. The space complexity is linear as i have to store it for every entry and a perfect hash could grow alot even for a small number of entries.
So your problem boils down to sizeof(optional<T>)=sizeof(T)+sizeof(bool)? I'm not sure I like your proposal from a semantic POV, so it might help if you could give more detail that just "optional is bigger than I want". Can you show me a _concrete_ example for the iniline NaT case? Along with an example of a non inline case? TIA Fernando Cacciola

On Mon, Aug 07, 2006 at 10:25:08AM -0300, Fernando Cacciola wrote:
Sascha Krissler wrote:
Fernando wrote:
[...] But when i store values where the type has an inline NaT value (for example NULL pointers) i cannot and need not use optional.
Can you explain why you cannot use optional<>? I definitely see that you don't need it, but for the sake of genericity I just wouldn't mind the fact that some types do have an identifiable null value and use optional<> all along.
Well i could use it but i do not want to. The space complexity is linear as i have to store it for every entry and a perfect hash could grow alot even for a small number of entries.
So your problem boils down to sizeof(optional<T>)=sizeof(T)+sizeof(bool)?
Yes, thats my main problem.
I'm not sure I like your proposal from a semantic POV, so it might help if you could give more detail that just "optional is bigger than I want".
As i intend to optimize the inline NaT case my first problem is gone. The next problem is *i* have to handle the special case though some template specializations. If the whole source was under my control i would change optional<> In the end i intend to use it as an interface concept to handle the handling of optional values.
Can you show me a _concrete_ example for the iniline NaT case? Along with an example of a non inline case?
I am hashing std::type_info *, which cannot be NULL for a valid type. The (pefect) hash map should be usable for any other type too (no concrete example available). See http://archives.free.net.ph/message/20060806.164337.843542fc.en.html for the relationship between hash maps and NaT

Sascha Krissler <boost-dev@k.datenfreihafen.de> writes:
Another solution would be to make a detail::generic_optional with all the operator foo and let optional inherit from it. That would be infinitesimal backward-incompatible ;)
I would use a simple metafunction to transform a type T into a type with a null value: template <class T> struct nullable { typedef boost::optional<T> type; }; template <class T> struct nullable<T*> { typedef T* type; }; // other specializations for types with built-in NULL values This way you're really not incurring any overhead for types that are already nullable. Use free functions to smooth out any messy interface differences due to the optional<T> wrapper on some types. HTH, Dave -- Dave Abrahams Boost Consulting www.boost-consulting.com

On Mon, Aug 07, 2006 at 10:20:37AM -0400, David Abrahams wrote:
Sascha Krissler <boost-dev@k.datenfreihafen.de> writes:
Another solution would be to make a detail::generic_optional with all the operator foo and let optional inherit from it. That would be infinitesimal backward-incompatible ;)
I would use a simple metafunction to transform a type T into a type with a null value:
template <class T> struct nullable { typedef boost::optional<T> type; };
template <class T> struct nullable<T*> { typedef T* type; };
// other specializations for types with built-in NULL values
This way you're really not incurring any overhead for types that are already nullable. Use free functions to smooth out any messy interface differences due to the optional<T> wrapper on some types.
That's what i am doing right now. The messy interface differences could be smoothed out by optional<>. If i had to implement all the interface of OptionalPointee again that would be a lot of duplication whether changing optional would be a couple of mpl::if_. Well i will not wait for a new release of boost to solve my poblem anyway it is a suggestion to improve the genericity of the lib.

Sascha Krissler <boost-dev@k.datenfreihafen.de> writes:
That's what i am doing right now. The messy interface differences could be smoothed out by optional<>.
It's not optional's job to make that decision. 0 is a valid pointer value, and it's not the same thing as "no pointer value."
If i had to implement all the interface of OptionalPointee again that would be a lot of duplication whether changing optional would be a couple of mpl::if_. Well i will not wait for a new release of boost to solve my poblem anyway it is a suggestion to improve the genericity of the lib.
Unfortunately, it would reduce genericity. Suddenly some types have special values that can't be represented distinctly from an empty optional. -- Dave Abrahams Boost Consulting www.boost-consulting.com

On Mon, Aug 07, 2006 at 10:11:53PM -0400, David Abrahams wrote:
Sascha Krissler <boost-dev@k.datenfreihafen.de> writes:
That's what i am doing right now. The messy interface differences could be smoothed out by optional<>.
It's not optional's job to make that decision. 0 is a valid pointer value, and it's not the same thing as "no pointer value."
The difference is that in optional<foo *> NULL is a valid pointer value In struct my_discriminator { }; optional<foo *, my_discriminator> optional<foo *, my_discriminator>::null_value = NULL; // static member NULL is not a valid pointer value (useful for std::type_info *, for example, or for a -1 integer return to indicate error)
If i had to implement all the interface of OptionalPointee again that would be a lot of duplication whether changing optional would be a couple of mpl::if_. Well i will not wait for a new release of boost to solve my poblem anyway it is a suggestion to improve the genericity of the lib.
Unfortunately, it would reduce genericity. Suddenly some types have special values that can't be represented distinctly from an empty optional.
with increased genericity i mean: make optional a concept, rather than (or in addition to) a class
participants (3)
-
David Abrahams
-
Fernando Cacciola
-
Sascha Krissler