// -*- C++ -*-
/***************************************************************************
 *
 * iomanip - Declarations of iostream manipulators
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you under  the Apache
 * License, Version  2.0 (the  "License"); you may  not use  this file
 * except in  compliance with the License.   You may obtain  a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the  License is distributed on an  "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
 * implied.   See  the License  for  the  specific language  governing
 * permissions and limitations under the License.
 *
 * Copyright 1994-2005 Rogue Wave Software.
 * 
 **************************************************************************/

#ifndef _RWSTD_IOMANIP_INCLUDED
#define _RWSTD_IOMANIP_INCLUDED

#include <iosfwd>

#include <rw/_iosbase.h>
#include <rw/_defs.h>


_RWSTD_NAMESPACE (__rw) {


// resetiosflags implementation
struct __rw_resetiosflags
{
    void operator() (_STD::ios_base           &__strm,
                     _STD::ios_base::fmtflags  __mask) const {
        __strm.setf (_STD::ios_base::fmtflags (0), __mask);
    }
};


// setiosflags implementation
struct __rw_setiosflags
{
    void operator() (_STD::ios_base           &__strm,
                     _STD::ios_base::fmtflags  __mask) const {
        __strm.setf (__mask);
    }
};


// setbase implementation
struct __rw_setbase
{
    void operator() (_STD::ios_base &__strm, int __base) const {

#ifndef _RWSTD_NO_EXT_SETBASE

        if (__base < 0 || __base > 36)
            __base = 0;

#else   // if defined (_RWSTD_NO_EXT_SETBASE)

        switch (__base) {
        case 0: case 8: case 10: case 16: break;

#  ifndef _RWSTD_NO_EXT_BIN_IO

        case 2: break;

#  endif   // _RWSTD_NO_EXT_BIN_IO

        default: __base = 0;
        }

#endif   // _RWSTD_NO_EXT_SETBASE

        const unsigned __ifl =
              __strm.flags () & ~_STD::ios_base::basefield
            & ~(_RWSTD_IOS_BASEMASK << _RWSTD_IOS_BASEOFF)
            | __base << _RWSTD_IOS_BASEOFF;

        __strm.flags (_STD::ios_base::fmtflags (__ifl));
    }
};


// setfill implementation
template <class _CharT>
struct __rw_setfill
{
    template <class _Traits>
    void operator() (_STD::basic_ios<_CharT, _Traits> &__strm,
                     _CharT                            __ch) const {
        __strm.fill (__ch);
    }
};


// setprecision implementation
struct __rw_setprecision
{
    void operator() (_STD::ios_base &__strm, int __prec) const {
        __strm.precision (_RWSTD_STATIC_CAST (_RWSTD_STREAMSIZE, __prec));
    }
};


// setw implementation
struct __rw_setw
{
    void operator() (_STD::ios_base &__strm, int __width) const {
        __strm.width (_RWSTD_STATIC_CAST (_RWSTD_STREAMSIZE, __width));
    }
};


}   // namespace __rw
 

_RWSTD_NAMESPACE (std) { 

  
// manipulator implementation
template <class _Functor, class _TypeT>
struct __rw_smanip
{
    _EXPLICIT
    __rw_smanip (_TypeT __arg)
        : _C_fun (), _C_arg (__arg) { /* empty */ }

    __rw_smanip (_Functor __fun, _TypeT __arg)
        : _C_fun (__fun), _C_arg (__arg) { /* empty */ }
      
    _Functor _C_fun;
    _TypeT   _C_arg;
};
 

// 27.6.3, p3
inline __rw_smanip<_RW::__rw_resetiosflags, ios_base::fmtflags>
resetiosflags (ios_base::fmtflags __mask)
{
    return __rw_smanip<_RW::__rw_resetiosflags, ios_base::fmtflags>(__mask);
}
 

// 27.6.3, p4
inline __rw_smanip<_RW::__rw_setiosflags, ios_base::fmtflags>
setiosflags (ios_base::fmtflags __mask)
{
    return __rw_smanip<_RW::__rw_setiosflags, ios_base::fmtflags>(__mask);
}


// 27.6.3, p5
inline __rw_smanip<_RW::__rw_setbase, int>
setbase (int __base)
{
    return __rw_smanip<_RW::__rw_setbase, int>(__base);
}


// 27.6.3, p6
template <class _CharT>
inline __rw_smanip<_RW::__rw_setfill<_CharT>, _CharT>
setfill (_CharT __ch)
{
    return __rw_smanip<_RW::__rw_setfill<_CharT>, _CharT>(__ch);
}


// 27.6.3, p7
inline __rw_smanip<_RW::__rw_setprecision, int>
setprecision (int __prec)
{
    return __rw_smanip<_RW::__rw_setprecision, int>(__prec);
}


// 27.6.3, p8
inline __rw_smanip<_RW::__rw_setw, int>
setw (int __width)
{
    return __rw_smanip<_RW::__rw_setw, int>(__width);
}


// implementation of manipulator extractor
template <class _CharT, class _Traits, class _Functor, class _TypeT>
inline basic_istream<_CharT, _Traits>&
operator>> (basic_istream<_CharT, _Traits>      &__strm,
            const __rw_smanip<_Functor, _TypeT> &__man)
{
    _TRY {
        __man._C_fun (__strm, __man._C_arg);
    }
    _CATCH (...) {
        __strm.setstate (ios_base::badbit);
    }
  
    return __strm;
}


// implementation of manipulator inserter
template <class _CharT, class _Traits, class _Functor, class _TypeT>
inline basic_ostream<_CharT, _Traits>&
operator<< (basic_ostream<_CharT, _Traits>      &__strm,
            const __rw_smanip<_Functor, _TypeT> &__man)
{
    _TRY {
        __man._C_fun (__strm, __man._C_arg);
    }
    _CATCH (...) {
        __strm.setstate (ios_base::badbit);
    }

    return __strm;
}

}   // namespace std


#endif   // _RWSTD_IOMANIP_INCLUDED
