// -*- C++ -*-
/***************************************************************************
 *
 * time - Declarations for the Standard Library time facets
 *
 ***************************************************************************
 *    
 *  Copyright 2000 Compaq Computer Corporation
 *
 *  COMPAQ Registered in U.S. Patent and Trademark Office.
 *
 *  Confidential computer software. Valid license from Compaq required for
 *  possession, use or copying. Consistent with FAR 12.211 and 12.212,
 *  Commercial Computer Software, Computer Software Documentation, and
 *  Technical Data for Commercial Items are licensed to the U.S. Government
 *  under vendor's standard commercial license.
 *
 ****************************************************************************
 *
 * (c) Copyright 1994, 1998 Rogue Wave Software, Inc.
 * ALL RIGHTS RESERVED
 *
 * The software and information contained herein are proprietary to, and
 * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
 * intends to preserve as trade secrets such software and information.
 * This software is furnished pursuant to a written license agreement and
 * may be used, copied, transmitted, and stored only in accordance with
 * the terms of such license and with the inclusion of the above copyright
 * notice.  This software and information or any other copies thereof may
 * not be provided or otherwise made available to any other person.
 *
 * Notwithstanding any other lease or license that may pertain to, or
 * accompany the delivery of, this computer software and information, the
 * rights of the Government regarding its use, reproduction and disclosure
 * are as set forth in Section 52.227-19 of the FARS Computer
 * Software-Restricted Rights clause.
 * 
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
 * Technical Data and Computer Software clause at DFARS 252.227-7013.
 * Contractor/Manufacturer is Rogue Wave Software, Inc.,
 * P.O. Box 2328, Corvallis, Oregon 97339.
 *
 * This computer software and information is distributed with "restricted
 * rights."  Use, duplication or disclosure is subject to restrictions as
 * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
 * Computer Software-Restricted Rights (April 1985)."  If the Clause at
 * 18-52.227-74 "Rights in Data General" is specified in the contract,
 * then the "Alternate III" clause applies.
 *
 **************************************************************************/

#ifndef __STD_TIME__
#define __STD_TIME__

#ifndef __STD_RWLOCALE__
#include <rwlocale>
#endif

#ifndef __STD_RW_LOCNUMRW
#include <numbrw>
#endif

#ifndef __STD_RW_LOCHELP__
#include <lochelp>
#endif


#if defined(__DECCXX)
#   ifdef __PRAGMA_ENVIRONMENT
#      pragma __environment __save
#      pragma __environment __header_defaults
#   endif
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1158)
#pragma __extern_prefix __save
#pragma __extern_prefix "CXXL$" 
#endif

#ifndef _RWSTD_NO_NAMESPACE
namespace std {
#endif

struct _RWSTDExport time_base {
   enum dateorder { no_order, dmy, mdy, ymd, ydm };
};

#ifndef _RWSTD_NO_NAMESPACE
} namespace _RWrwstd {
#endif

#if !defined (_RWSTD_NO_NEW_HEADER) && !defined (_RWSTD_NO_NAMESPACE)
  using std::tm;
#endif

// ------------------------------------------------------------------
// Implementation class template -- time_reader<charT,InputIterator>.
// ------------------------------------------------------------------

template <class charT,class InputIterator>
class _RWSTDExportTemplate time_reader :
    public digit_reader<charT,InputIterator>
{
 public:
  typedef _TYPENAME timepunct<charT>::string_type string_type;
  const timepunct<charT> &_RWtimp;

  time_reader (InputIterator& in,InputIterator& end,
      _RW_STD::ios_base& io, const timepunct<charT>& timepunct);

  bool get_time_pattern (const string_type& pattern,tm *time);

  static const timepunct<charT>& _RWidiocy (_RW_STD::ios_base& io) {
    const _RW_STD::locale loc=io.getloc();
#ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
    return _RW_STD::use_facet<timepunct<charT> >(loc);
#else
    return _RW_STD::use_facet(loc,(timepunct<charT>*)0);
#endif //  _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE

  }
};

#ifndef _RWSTD_NO_NAMESPACE
} namespace std {
#endif

// ----------------------------------------------------------------------
// Standard time and date parsing facet -- time_get<charT,InputIterator>.
// ----------------------------------------------------------------------

template <class charT,class InputIterator>
class  time_get: public locale::facet, public time_base {
 public:
  typedef charT char_type;
  typedef InputIterator iter_type;

  _EXPLICIT time_get (size_t refs=0): locale::facet(refs,locale::time) 
  { ; }

  dateorder date_order() const { return do_date_order(); }
  iter_type get_time (iter_type start, iter_type end, ios_base& format,
      ios_base::iostate &err, tm* time) const
        { return do_get_time (start,end,format,err,time); }

  iter_type get_date (iter_type start, iter_type end, ios_base& format,
      ios_base::iostate &err, tm* time) const
        { return do_get_date(start,end,format,err,time); }

  iter_type get_weekday (iter_type start, iter_type end, ios_base& format,
      ios_base::iostate &err, tm* time) const
        { return do_get_weekday(start,end,format,err,time); }

  iter_type get_monthname (iter_type start, iter_type end, ios_base& format,
      ios_base::iostate &err, tm* time) const
        { return do_get_monthname(start,end,format,err,time); }

  iter_type get_year (iter_type start, iter_type end, ios_base& format,
      ios_base::iostate &err, tm* time) const
        { return do_get_year(start,end,format,err,time); }

  static locale::id id;

  // Implementation:
  enum { _RWfacet_cat = locale::time, _RWok_implicit = 1 };

 protected:
  virtual ~time_get();

  virtual dateorder do_date_order()  const;

  virtual iter_type do_get_time
            (iter_type, iter_type, ios_base&, ios_base::iostate&, tm*) const;
  virtual iter_type do_get_date
            (iter_type, iter_type, ios_base&, ios_base::iostate&, tm*) const;
  virtual iter_type do_get_weekday
            (iter_type, iter_type, ios_base&, ios_base::iostate&, tm*) const;
  virtual iter_type do_get_monthname
            (iter_type, iter_type, ios_base&, ios_base::iostate&, tm*) const;
  virtual iter_type do_get_year
            (iter_type, iter_type, ios_base&, ios_base::iostate&, tm*) const;

  // Implementation:

 protected:
  const __RWSTD::timepunct<charT>* _RWtimp;
  string _RWname;

 private:

#if defined(__DECCXX) && !defined(__DECFIXCXXL957)
  void _RWinitfacet (const locale* loc)
#else
  void _RWinit_facet (const locale* loc)
#endif
  { 
    __RWSTD::use_Clib_locale clocale(_RWname.c_str(),LC_TIME);    
  #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
    _RWtimp = &use_facet<__RWSTD::timepunct<charT> >(*loc);
  #else
    _RWtimp = &use_facet(*loc,(__RWSTD::timepunct<charT>*)0);
  #endif
  }

  #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  locale::id &_RWget_id (void) const { return id; }
  #endif
};

// --------------------------------------------------------------------------
// Standard time and date formatting facet -- time_put<charT,OutputIterator>.
// --------------------------------------------------------------------------

template <class charT,class OutputIterator>
class  time_put: public locale::facet {
 public:
  typedef charT char_type;
  typedef OutputIterator iter_type;

  _EXPLICIT time_put (size_t refs=0) : locale::facet(refs,locale::time)
  { ; }

  iter_type put (iter_type start, ios_base& format, char_type fill,
      const tm* time, const char_type *pattern, const char_type *pat_end) const;

  iter_type put (iter_type start, ios_base& format, char_type fill,
      const tm* time, char fmt, char modifier = 0) const
        { return do_put(start,format,fill,time,fmt,modifier); }

  static locale::id id;

  // Implementation:
  enum { _RWfacet_cat = locale::time, _RWok_implicit = 1 };

 protected:
  virtual ~time_put();

  virtual iter_type do_put (iter_type, ios_base&, char_type fill,
           const tm* time, char fmt, char modifier) const;

 protected:
  const __RWSTD::timepunct<charT>* _RWtimp;
  string _RWname;

 private:

#if defined(__DECCXX) && !defined(__DECFIXCXXL957)
  void _RWinitfacet (const locale* loc)
#else
  void _RWinit_facet (const locale* loc)
#endif
  { 
    __RWSTD::use_Clib_locale clocale(_RWname.c_str(),LC_TIME);    
  #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
    _RWtimp = &use_facet<__RWSTD::timepunct<charT> >(*loc);
  #else
    _RWtimp = &use_facet(*loc,(__RWSTD::timepunct<charT>*)0);
  #endif
  }
  #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  locale::id &_RWget_id (void) const { return id; }
  #endif
};



// -------------------------------------------------
// Standard derived facet -- time_get_byname<charT>.
// -------------------------------------------------

template <class charT, class InputIterator>
class  time_get_byname: public time_get<charT,InputIterator> {
 public:
  _EXPLICIT time_get_byname (const char*, size_t refs=0);

 protected:
  virtual ~time_get_byname();

// Virtual member functions inherited from time_get<charT,InputIterator>:
// virtual dateorder do_date_order()  const;
// virtual iter_type do_get_time (iter_type i, iter_type e, ios_base&,
//                                ios_base::iostate &err, tm* t) const;
// virtual iter_type do_get_date (iter_type i, iter_type e, ios_base&,
//                                ios_base::iostate &err, tm* t) const;
// virtual iter_type do_get_weekday (iter_type i, iter_type e, ios_base&,
//                                ios_base::iostate &err, tm* t) const;
// virtual iter_type do_get_monthname (iter_type i, iter_type e, ios_base&,
//                                ios_base::iostate &err, tm* t) const;
// virtual iter_type do_get_year (iter_type i, iter_type e, ios_base&,
//                                ios_base::iostate &err, tm* t) const;
};

// -------------------------------------------------
// Standard derived facet -- time_put_byname<charT>.
// -------------------------------------------------

template <class charT, class OutputIterator>
class  time_put_byname: public time_put<charT,OutputIterator> {
 public:
  _EXPLICIT time_put_byname (const char*, size_t refs=0); 

 protected:
  virtual ~time_put_byname();

// Virtual member functions inherited from time_put<charT,OutputIterator>:
// virtual iter_type do_put (iter_type s, ios_base&, char_type fill,
//                           const tm* t, char format, char modifier) const;
};


#ifndef _RWSTD_NO_NAMESPACE
} namespace _RWrwstd {
#endif

#ifndef _RWSTD_NO_FUNC_PARTIAL_SPEC

template <class charT, class InputIterator>
inline _RW_STD::time_get<charT,InputIterator>* create_named_facet
    (_RW_STD::time_get<charT,InputIterator>*,const char *name,size_t refs)
{ return new _RW_STD::time_get_byname<charT,InputIterator>(name,refs); }

template <class charT, class OutputIterator>
inline _RW_STD::time_put<charT,OutputIterator>* create_named_facet
    (_RW_STD::time_put<charT,OutputIterator>*,const char *name,size_t refs)
{ return new _RW_STD::time_put_byname<charT,OutputIterator>(name,refs); }


#else
_RWSTD_TEMPLATE 
inline _RW_STD::time_get<char,_RW_STD::istreambuf_iterator<char,_RW_STD::char_traits<char> > >* create_named_facet
    (_RW_STD::time_get<char,_RW_STD::istreambuf_iterator<char,_RW_STD::char_traits<char> > >*,const char *name,size_t refs)
{ return new _RW_STD::time_get_byname<char,_RW_STD::istreambuf_iterator<char,_RW_STD::char_traits<char> > >(name,refs); }

inline _RW_STD::time_put<char,_RW_STD::ostreambuf_iterator<char,_RW_STD::char_traits<char> > >* create_named_facet
    (_RW_STD::time_put<char,_RW_STD::ostreambuf_iterator<char,_RW_STD::char_traits<char> > >*,const char *name,size_t refs)
{ return new _RW_STD::time_put_byname<char,_RW_STD::ostreambuf_iterator<char,_RW_STD::char_traits<char> > >(name,refs); }

#ifndef _RWSTD_NO_WIDE_CHAR
_RWSTD_TEMPLATE
inline _RW_STD::time_get<wchar_t,_RW_STD::istreambuf_iterator<wchar_t,_RW_STD::char_traits<wchar_t> > >* create_named_facet
    (_RW_STD::time_get<wchar_t,_RW_STD::istreambuf_iterator<wchar_t,_RW_STD::char_traits<wchar_t> > >*,const char *name,size_t refs)
{ return new _RW_STD::time_get_byname<wchar_t,_RW_STD::istreambuf_iterator<wchar_t,_RW_STD::char_traits<wchar_t> > >(name,refs); }

inline _RW_STD::time_put<wchar_t,_RW_STD::ostreambuf_iterator<wchar_t,_RW_STD::char_traits<wchar_t> > >* create_named_facet
    (_RW_STD::time_put<wchar_t,_RW_STD::ostreambuf_iterator<wchar_t,_RW_STD::char_traits<wchar_t> > >*,const char *name,size_t refs)
{ return new _RW_STD::time_put_byname<wchar_t,_RW_STD::ostreambuf_iterator<wchar_t,_RW_STD::char_traits<wchar_t> > >(name,refs); }

#endif // _RWSTD_NO_WIDE_CHAR
#endif // _RWSTD_NO_FUNC_PARTIAL_SPEC


#ifndef _RWSTD_NO_NAMESPACE
} // namespace _RWrwstd
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1158)
#   pragma __extern_prefix __restore
#endif

#ifdef _RWSTD_COMPILE_INSTANTIATE
#include <time.cc>
#endif

#if defined(__DECCXX)
#   ifdef __PRAGMA_ENVIRONMENT
#      pragma __environment __restore
#   endif
#endif

#endif // __STD_TIME__
