// -*- 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-2008 Rogue Wave Software, Inc.
 * 
 **************************************************************************/

#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_STATIC_CAST (unsigned, _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
