template <class T>
class optional
{
public :
    typedef T         value_type ;
    typedef T &       reference_type ;
    typedef T const&  reference_const_type ;
    typedef T &&      rval_reference_type ;
    typedef T *       pointer_type ;
    typedef T const*  pointer_const_type ;
    optional () noexcept ;  optional ( none_t ) noexcept ;
    optional ( none_t ) noexcept ;  optional ( T const& v ) ;
    optional ( T const& v ) ;  optional ( T&& v ) ;
    optional ( T&& v ) ;  optional ( bool condition, T const& v ) ;
    optional ( bool condition, T const& v ) ;  optional ( optional const& rhs ) ;
    optional ( optional const& rhs ) ;  optional ( optional&& rhs ) noexcept(see below) ;
    optional ( optional&& rhs ) noexcept(see below) ;  template<class U> explicit optional ( optional<U> const& rhs ) ;
    template<class U> explicit optional ( optional<U> const& rhs ) ;  template<class U> explicit optional ( optional<U>&& rhs ) ;
    template<class U> explicit optional ( optional<U>&& rhs ) ;  template<class... Args> explicit optional ( in_place_init_t, Args&&... args ) ;
    template<class... Args> explicit optional ( in_place_init_t, Args&&... args ) ;  template<class... Args> explicit optional ( in_place_init_if_t, bool condition, Args&&... args ) ;
    template<class... Args> explicit optional ( in_place_init_if_t, bool condition, Args&&... args ) ;  template<class InPlaceFactory> explicit optional ( InPlaceFactory const& f ) ;
    template<class InPlaceFactory> explicit optional ( InPlaceFactory const& f ) ;  template<class TypedInPlaceFactory> explicit optional ( TypedInPlaceFactory const& f ) ;
    template<class TypedInPlaceFactory> explicit optional ( TypedInPlaceFactory const& f ) ;  optional& operator = ( none_t ) noexcept ;
    optional& operator = ( none_t ) noexcept ;  optional& operator = ( T const& v ) ;
    optional& operator = ( T const& v ) ;  optional& operator = ( T&& v ) ;
    optional& operator = ( T&& v ) ;  optional& operator = ( optional const& rhs ) ;
    optional& operator = ( optional const& rhs ) ;  optional& operator = ( optional&& rhs ) noexcept(see below) ;
    optional& operator = ( optional&& rhs ) noexcept(see below) ;  template<class U> optional& operator = ( optional<U> const& rhs ) ;
    template<class U> optional& operator = ( optional<U> const& rhs ) ;  template<class U> optional& operator = ( optional<U>&& rhs ) ;
    template<class U> optional& operator = ( optional<U>&& rhs ) ;  template<class... Args> void emplace ( Args&&... args ) ;
    template<class... Args> void emplace ( Args&&... args ) ;  template<class InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ;
    template<class InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ;  template<class TypedInPlaceFactory> optional& operator = ( TypedInPlaceFactory const& f ) ;
    template<class TypedInPlaceFactory> optional& operator = ( TypedInPlaceFactory const& f ) ;  T const& get() const ;
    T const& get() const ;  T&       get() ;
    T&       get() ;  T const* operator ->() const ;
    T const* operator ->() const ;  T*       operator ->() ;
    T*       operator ->() ;  T const& operator *() const& ;
    T const& operator *() const& ;  T&       operator *() & ;
    T&       operator *() & ;  T&&      operator *() && ;
    T&&      operator *() && ;  T const& value() const& ;
    T const& value() const& ;  T&       value() & ;
    T&       value() & ;  T&&      value() && ;
    T&&      value() && ;  template<class U> T value_or( U && v ) const& ;
    template<class U> T value_or( U && v ) const& ;  template<class U> T value_or( U && v ) && ;
    template<class U> T value_or( U && v ) && ;  template<class F> T value_or_eval( F f ) const& ;
    template<class F> T value_or_eval( F f ) const& ;  template<class F> T value_or_eval( F f ) && ;
    template<class F> T value_or_eval( F f ) && ;  template<class F> auto map( F f ) const& -> see below;
    template<class F> auto map( F f ) const& -> see below;  template<class F> auto map( F f ) & -> see below;
    template<class F> auto map( F f ) & -> see below;  template<class F> auto map( F f ) && -> see below;
    template<class F> auto map( F f ) && -> see below;  template<class F> auto flat_map( F f ) const& -> see below;
    template<class F> auto flat_map( F f ) const& -> see below;  template<class F> auto flat_map( F f ) & -> see below;
    template<class F> auto flat_map( F f ) & -> see below;  template<class F> auto flat_map( F f ) && -> see below;
    template<class F> auto flat_map( F f ) && -> see below;  T const* get_ptr() const ;
    T const* get_ptr() const ;  T*       get_ptr() ;
    T*       get_ptr() ;  bool has_value() const noexcept ;
    bool has_value() const noexcept ;  explicit operator bool() const noexcept ;
    explicit operator bool() const noexcept ;  bool operator!() const noexcept ;
    bool operator!() const noexcept ;  void reset() noexcept ;
    void reset() noexcept ;  void reset ( T const& ) ;
    
    
    void reset ( T const& ) ;  bool is_initialized() const ;
    
    bool is_initialized() const ;  T const& get_value_or( T const& default ) const ;
    
    T const& get_value_or( T const& default ) const ;  };
};