template <class T>
class optional<T&> 
{
public :
    typedef T& value_type;
    typedef T& reference_type;
    typedef T& reference_const_type; 
    typedef T& rval_reference_type;
    typedef T* pointer_type;
    typedef T* pointer_const_type;   
    optional () noexcept ;  optional ( none_t ) noexcept ;
    optional ( none_t ) noexcept ;  template<class R> optional(R&& r) noexcept ;
    template<class R> optional(R&& r) noexcept ;   template <class R> optional(bool cond, R&& r) noexcept ;
    template <class R> optional(bool cond, R&& r) noexcept ;  optional ( optional const& rhs ) noexcept ;
    optional ( optional const& rhs ) noexcept ;  template<class U> explicit optional ( optional<U&> const& rhs ) noexcept ;
    template<class U> explicit optional ( optional<U&> const& rhs ) noexcept ;  optional& operator = ( none_t ) noexcept ;
    optional& operator = ( none_t ) noexcept ;  optional& operator = ( optional const& rhs ) noexcept;
    optional& operator = ( optional const& rhs ) noexcept;  template<class U> optional& operator = ( optional<U&> const& rhs ) noexcept ;
    template<class U> optional& operator = ( optional<U&> const& rhs ) noexcept ;  template<class R> optional& operator = (R&& r) noexcept ;
    template<class R> optional& operator = (R&& r) noexcept ;  template<class R> void emplace ( R&& r ) noexcept ;
    template<class R> void emplace ( R&& r ) noexcept ;  T& get() const ;
    T& get() const ;  T& operator *() const ;
    T& operator *() const ;  T* operator ->() const ;
    T* operator ->() const ;  T& value() const& ;
    T& value() const& ;  template<class R> T& value_or( R && r ) const noexcept ;
    template<class R> T& value_or( R && r ) const noexcept ;  template<class F> T& value_or_eval( F f ) const ;
    template<class F> T& value_or_eval( F f ) const ;  template<class F> auto map( F f ) const -> see below;
    template<class F> auto 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 ) const -> see below;  T* get_ptr() const noexcept ;
    T* get_ptr() const noexcept ;  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 ;  template<class R> void reset ( R && r ) noexcept ;
    
    
    template<class R> void reset ( R && r ) noexcept ;  bool is_initialized() const noexcept ;
    
    bool is_initialized() const noexcept ;  template<class R> T& get_value_or( R && r ) constnoexcept;
    
    template<class R> T& get_value_or( R && r ) constnoexcept;  private:
    T* ref; 
};
private:
    T* ref; 
};