New Library Proposal: dual_state

This is my first post to the Boost distribution list, so please feel free to speak up if you find any part of this message to be outside the normal decorum. I am curious if there is support for what I'm calling a "dual_state" template class. Anyone familiar with Perl will instantly recognize the parallel. The idea is to attach a "statedness" value to arbitrary objects, allowing us to consider them defined or undefined. Newly constructed dual_state objects are undefined. For example, // -- begin template < class T > class dual_state { ... }; dual_state<int> a; a.defined(); // FALSE defined(a); // same thing // -- end We can "define" a dual_state object by assigning a value to it, either as a base type, T, or as another dual_state object: // -- begin // assign an int to a a = 5; a.defined() // TRUE // assign another dual_state<int> to a dual_state<int> b; b = a; b.defined(); // TRUE // -- end We can undefine a defined dual_state object: // -- begin a.undefine(); undefine(b); // -- end In addition, we can utilize an instance of another class, the "undefined_object", to interrogate or set the defined property of a dual_state object: // -- begin const class undefined_object {} undef; a = undef; a.defined(); // FALSE a == undef; // same thing // -- end The dual_state class provides a conversion to T. This conversion will, for an undefined dual_state object, return default T objects generated using the expression "T()". As an aside, it seems Boost.value_init may provide a more general solution that is worth considering. There is no conversion to T& because some compilers are utterly confused by such conversions. To make dual_state compatible with large or uncopyable objects, two explicit conversions are provided: // --begin template < class T > class dual_state { ... const T& value() const; T& define(); }; // -- end The value() member is straightforward. As for define(), it is necessary to first define the dual_state object before assigning it a value. The operator= member normally takes care of this step, but when dealing with the T reference directly we must explicitly use define(). An example using define() is shown below: // -- begin dual_state<int> x; cin >> x.define(); // -- end In Perl, the defined/undefined concept is tremendously useful, so I would expect similar utility in C++. I have not given any thought to what a dual_state<bool> is or how it is related to Boost.tribool. Thanks to everyone who took the time to read this whole post. I am open to all suggestions, including a better name -- "dual_state" is quite incongruent, but I can't think of anything better. Here are some additional poor suggestions: bistate, managed, switched, stated, definable. -- Andrew M. Jost

On Sat, 9 Jul 2005 18:50:30 -0700, Jost, Andrew wrote
This is my first post to the Boost distribution list, so please feel free to speak up if you find any part of this message to be outside the normal decorum.
I am curious if there is support for what I'm calling a "dual_state" template class. Anyone familiar with Perl will instantly recognize the parallel. The idea is to attach a "statedness" value to arbitrary objects, allowing us to consider them defined or undefined.
I believe you are looking for boost.optional http://www.boost.org/libs/optional/doc/optional.html Jeff

Jost, Andrew wrote:
This is my first post to the Boost distribution list, so please feel free to speak up if you find any part of this message to be outside the normal decorum.
I am curious if there is support for what I'm calling a "dual_state" template class. Anyone familiar with Perl will instantly recognize the parallel. The idea is to attach a "statedness" value to arbitrary objects, allowing us to consider them defined or undefined. Newly constructed dual_state objects are undefined. For example,
It sounds like the functionality you want is provided by Boost.Optional: http://www.boost.org/libs/optional/doc/optional.html (And yes, it is extremely useful ;-) ) Jonathan

"Jost, Andrew" <Andrew_Jost@mentor.com> writes:
This is my first post to the Boost distribution list, so please feel free to speak up if you find any part of this message to be outside the normal decorum.
I am curious if there is support for what I'm calling a "dual_state" template class. Anyone familiar with Perl will instantly recognize the parallel. The idea is to attach a "statedness" value to arbitrary objects, allowing us to consider them defined or undefined. Newly constructed dual_state objects are undefined. For example,
Have you looked at Boost.Optional? http://www.boost.org/libs/optional/doc/optional.html -- Dave Abrahams Boost Consulting www.boost-consulting.com

On Sunday 10 July 2005 03:50, Jost, Andrew wrote:
I am curious if there is support for what I'm calling a "dual_state" template class. Anyone familiar with Perl will instantly recognize the parallel. The idea is to attach a "statedness" value to arbitrary objects, allowing us to consider them defined or undefined. [ snipped rest ]
I have one big concern that wasn't voiced in the whole thread yet: const correctness. What I mean is, how does a const (ref to a) dual_state object behave? What if I retrieve the value from such an object, will it modify that object? Also, even for a non const object, I would be surprised if I just retrieved the value and thereby changed the object. In general, I wonder if you tried this already. I wouldn't be surprised if using it turned out to be a bad or a good idea, but I don't think you can determine the usefulness completely in the laboratory (i.e. on this ML). Many concerns have been voiced already, in particular that it hides too much and that it doesn't help writing correct code.
I have not given any thought to what a dual_state<bool> is or how it is related to Boost.tribool.
dual_state<bool> x = ...; if(x == true) { ... } if(x == false) { ... } if(x == undefined) { ... } Problems here: 'x == true', how should that be evaluated? You can't first perform a conversion of x to a bool, because then you would have to decide whether that should be true or false. So, operator== needs to be overloaded (among others) like this: template<typename T> bool operator==( dual_state<T> const& lhs, T const& rhs) { return lhs.defined() ? (lhs.get() == rhs) : false; } template<typename T> bool operator==( dual_state<T> const& lhs, undefined_type const& rhs) { return !lhs.defined(); } I haven't looked at tribool too much, but it might be a good replacement - there, too, the third state is not separate from the other states as it is for boost::optional. Uli
participants (6)
-
David Abrahams
-
Eelis van der Weegen
-
Jeff Garland
-
Jonathan Turkanis
-
Jost, Andrew
-
Ulrich Eckhardt