Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r49165 - sandbox/SOC/2008/graphs/trunk/boost
From: asutton_at_[hidden]
Date: 2008-10-07 10:54:19


Author: asutton
Date: 2008-10-07 10:54:18 EDT (Tue, 07 Oct 2008)
New Revision: 49165
URL: http://svn.boost.org/trac/boost/changeset/49165

Log:
Implemented a new optional_value class that allows the parameterization
of absent values - actual values that can be used to indicate the absence
of a value.

Added:
   sandbox/SOC/2008/graphs/trunk/boost/optional_value.hpp (contents, props changed)

Added: sandbox/SOC/2008/graphs/trunk/boost/optional_value.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2008/graphs/trunk/boost/optional_value.hpp 2008-10-07 10:54:18 EDT (Tue, 07 Oct 2008)
@@ -0,0 +1,168 @@
+
+#ifndef BOOST_OPTIONAL_VALUE_HPP
+#define BOOST_OPTIONAL_VALUE_HPP
+
+#include <algorithm>
+#include <limits>
+#include <stdexcept>
+
+namespace boost {
+
+// Forward declarations
+template <typename> class absent;
+
+/**
+ * An optional value is like an optional class, but designates a particular
+ * value as an indicator for the absence of value. A common example is to use
+ * -1u to indicate the absence of values or infinity for unsigned integers.
+ *
+ * Note that T must equality comparable in order to reason about the presence
+ * or absence of its value.
+ */
+template <typename T, typename Absent = absent<T>>
+class optional_value
+{
+ typedef optional_value<T, Absent> this_type;
+ typedef T this_type::* unspecified_bool_type;
+public:
+ typedef T value_type;
+
+ /** @name Constructors */
+ //@{
+ optional_value(T const& x = absent())
+ : _val(x)
+ { }
+
+ optional_value(optional_value const& x)
+ : _val(x._val)
+ { }
+
+ optional_value(optional_value&& x)
+ : _val(std::move(x._val))
+ { }
+ //@}
+
+ /** @name Operators */
+ //@{
+ inline optional_value& operator=(optional_value const& x)
+ { return swap(optional_value(x)); }
+
+ inline optional_value& operator=(optional_value&& x)
+ { return swap(x); }
+
+ inline bool operator==(optional_value const& x) const
+ { return _val == x._val; }
+
+ inline bool operator!=(optional_value const& x) const
+ { return !(*this == x); }
+
+ inline T& operator*()
+ { return get(); }
+
+ inline T const& operator*() const
+ { return get(); }
+
+ inline T* operator->()
+ { return &get(); }
+
+ inline T const* operator->() const
+ { return &get(); }
+
+ inline operator unspecified_bool_type() const
+ { return valid() ? &this_type::_val : 0; }
+ //@}
+
+ inline bool valid() const
+ { return _val != absent(); }
+
+ inline T& get()
+ {
+ if(!valid()) throw std::runtime_error("Invalid object");
+ return _val;
+ }
+
+ inline T const& get() const
+ {
+ if(!valid()) throw std::runtime_error("Invalid object");
+ return _val;
+ }
+
+ inline optional_value& swap(optional_value&& x)
+ {
+ using namespace std;
+ std::swap(_val, x._val);
+ return *this;
+ }
+
+ static T absent()
+ { return Absent::value(); }
+
+ T _val;
+};
+
+// Canned absentee values
+
+/** Use a type's minimum value as an absentee. */
+template <typename T>
+struct absent_min
+{
+ static T value()
+ { return std::numeric_limits<T>::min(); }
+};
+
+/** Use 0 as an absentee value. */
+template <typename T>
+struct absent_zero
+{
+ static T value()
+ { return T(0); }
+};
+
+/** Use a type's maximum value as an absentee. */
+template <typename T>
+struct absent_max
+{
+ static T value()
+ { return std::numeric_limits<T>::max(); }
+};
+
+/**
+ * Use positive infinity as an absentee value. Here, T is essentially required
+ * to be a float, double, or long double. If we had concepts and a generic
+ * infinity() function, the requirements could be easily reduced.
+ */
+template <typename T>
+struct absent_inf
+{
+ static T value()
+ { return std::numeric_limits<T>::infinity(); }
+};
+
+/** Use negative infinity as an absentee value. See absent_inf for comments. */
+template <typename T>
+struct absent_neg_inf
+{
+ static T value()
+ { return -std::numeric_limits<T>::infinity(); }
+};
+
+/**
+ * The absent structure is used to provide default absent values for the
+ * optional_value template. There are two ways to extend this functionality.
+ * The first is to specialize this structure over your type and the second
+ * is to simply define a new one and use it as the Absent parameter for the
+ * optional_value class. This class provides a number of default specializations.
+ *
+ * Note that the default values of these simply inherit specific canned
+ * instances absent values.
+ */
+template <typename T> struct absent { static T value(); };
+template <typename T> struct absent<T*> : absent_zero<T*> { };
+template <> struct absent<int> : absent_max<int> { };
+template <> struct absent<unsigned int> : absent_max<unsigned int> { };
+template <> struct absent<float> : absent_inf<float> { };
+template <> struct absent<double> : absent_inf<double> { };
+
+} /* namespace boost */
+
+#endif
\ No newline at end of file


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk