Boost logo

Boost :

From: Hamish Mackenzie (hamish_at_[hidden])
Date: 2003-09-08 15:01:09


Here is a quick go at optional as a container that holds just one item.
I prefer it to the current boost::optional interface.

Any chance we could add something like it to boost (perhaps with a
different name).

Also I vote for implicit construction from value_type.

Hamish

template< typename Value_Type >
class optional
{
public:
  typedef Value_Type value_type;
    
  optional() {}
    
  optional( const optional & source )
    : boost_optional_( source.boost_optional_ ) {}
    
  optional( const value_type & value )
    : boost_optional_( value ) {}
    
  optional< value_type > & operator = ( const optional & source )
  {
    boost_optional_ = source.boost_optional_;
    return *this;
  }
    
  bool empty() const { return !boost_optional_; }
    
  void clear()
  {
    boost_optional_.reset();
  }
    
  const value_type & value() const
  {
    return *boost_optional_;
  }
    
  value_type & value()
  {
    return *boost_optional_;
  }

  void value( const value_type & v )
  {
    boost_optional_ = boost::optional< value_type >( v );
  }

  void swap( optional & value )
  {
    boost::swap( boost_optional_, value.boost_optional_ );
  }

private:
  boost::optional< value_type > boost_optional_;
};

template< typename Value_Type >
inline void swap( optional< Value_Type > & v1,
  optional< Value_Type > & v2 )
{
  v1.swap( v2 );
}

template< typename Value_Type >
inline bool operator == ( const optional< Value_Type > & v1,
  const optional< Value_Type > & v2 )
{
  return v1.empty() == v2.empty() &&
    (v1.empty() || v1.value() == v2.value());
}

template< typename Value_Type >
inline bool operator != ( const optional< Value_Type > & v1,
  const optional< Value_Type > & v2 )
{
  return !( v1 == v2 );
}

template< typename T >
inline bool empty( const T & a ) { return false; }

template< typename T >
inline bool empty( const optional< T > & a ) { return a.empty(); }

template< typename T >
inline const T & value( const T & a ) { return a; }

template< typename T >
inline const T & value( const optional< T > & a ) { return a.value(); }

// A couple of handy functions
template< typename Char_Type, typename Char_Traits >
inline optional< std::basic_string< Char_Type, Char_Traits > >
empty_string_to_empty_optional(
  const optional< std::basic_string< Char_Type, Char_Traits > > & s )
{
  if( s.empty() || s.value().empty() )
  {
    return optional< std::basic_string< Char_Type, Char_Traits > >();
  }
  else
  {
    return s;
  }
}

template< typename Char_Type, typename Char_Traits >
inline std::basic_string< Char_Type, Char_Traits >
empty_optional_to_empty_string(
  const optional< std::basic_string< Char_Type, Char_Traits > > & s )
{
  if( s.empty() )
  {
    return std::basic_string< Char_Type, Char_Traits >();
  }
  else
  {
    return s.value();
  }
}

-- 
Hamish Mackenzie <hamish_at_[hidden]>

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk