/*****************************************************************************

  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
  more contributor license agreements.  See the NOTICE file distributed
  with this work for additional information regarding copyright ownership.
  Accellera 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.

 *****************************************************************************/

/*****************************************************************************

  sc_int_base.h -- A signed integer whose length is less than 64 bit.

              Unlike arbitrary precision, arithmetic and bitwise operations
              are performed using the native types (hence capped at 64 bits).
              The sc_int integer is useful when the user does not need
              arbitrary precision and the performance is superior to
              sc_bigint/sc_biguint.

  Original Author: Amit Rao, Synopsys, Inc.

 *****************************************************************************/

/*****************************************************************************

  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
  changes you are making here.

      Name, Affiliation, Date: Ali Dasdan, Synopsys, Inc.
  Description of Modification: - Resolved ambiguity with sc_(un)signed.
                               - Merged the code for 64- and 32-bit versions
                                 via the constants in sc_nbdefs.h.
                               - Eliminated redundant file inclusions.

      Name, Affiliation, Date:
  Description of Modification:

 *****************************************************************************/

// $Log: sc_int_base.h,v $
// Revision 1.3  2011/08/24 22:05:45  acg
//  Torsten Maehne: initialization changes to remove warnings.
//
// Revision 1.2  2011/02/18 20:19:15  acg
//  Andy Goodrich: updating Copyright notice.
//
// Revision 1.1.1.1  2006/12/15 20:20:05  acg
// SystemC 2.3
//
// Revision 1.4  2006/05/08 17:50:01  acg
//   Andy Goodrich: Added David Long's declarations for friend operators,
//   functions, and methods, to keep the Microsoft compiler happy.
//
// Revision 1.3  2006/01/13 18:49:31  acg
// Added $Log command so that CVS check in comments are reproduced in the
// source.
//

#ifndef __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__
#define __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__

#include <iostream>

#include "../misc/sc_value_base.hh"
#include "../sc_temporary.hh"
#include "sc_length_param.hh"
#include "sc_nbdefs.hh"
#include "sc_uint_base.hh"

namespace sc_dt
{

class sc_concatref;

// classes defined in this module
class sc_int_bitref_r;
class sc_int_bitref;
class sc_int_subref_r;
class sc_int_subref;
class sc_int_base;
class sc_signed_subref_r;
class sc_unsigned_subref_r;

// forward class declarations
class sc_bv_base;
class sc_lv_base;
class sc_signed;
class sc_unsigned;
class sc_fxval;
class sc_fxval_fast;
class sc_fxnum;
class sc_fxnum_fast;

} // namespace sc_dt

// extern template instantiations
namespace sc_core
{

extern template class sc_vpool<sc_dt::sc_int_bitref>;
extern template class sc_vpool<sc_dt::sc_int_subref>;

} // namespace sc_core

namespace sc_dt
{

extern const uint_type mask_int[SC_INTWIDTH][SC_INTWIDTH];

// friend operator declarations

// relational operators

inline bool operator == (const sc_int_base &a, const sc_int_base &b);
inline bool operator != (const sc_int_base &a, const sc_int_base &b);
inline bool operator <  (const sc_int_base &a, const sc_int_base &b);
inline bool operator <= (const sc_int_base &a, const sc_int_base &b);
inline bool operator >  (const sc_int_base &a, const sc_int_base &b);
inline bool operator >= (const sc_int_base &a, const sc_int_base &b);


// ----------------------------------------------------------------------------
//  CLASS : sc_int_bitref_r
//
//  Proxy class for sc_int bit selection (r-value only).
// ----------------------------------------------------------------------------

class sc_int_bitref_r : public sc_value_base
{
    friend class sc_int_base;

  protected:
    // constructor
    sc_int_bitref_r() : sc_value_base(), m_index(), m_obj_p() {}

    // initializer for sc_core::sc_vpool:
    void initialize(const sc_int_base *obj_p, int index_)
    {
        m_obj_p = (sc_int_base *)obj_p;
        m_index = index_;
    }

  public:
    // copy constructor
    sc_int_bitref_r(const sc_int_bitref_r &a) :
        sc_value_base(a), m_index(a.m_index), m_obj_p(a.m_obj_p)
    {}

    // destructor
    virtual ~sc_int_bitref_r() {}

    // capacity
    int length() const { return 1; }

#ifdef SC_DT_DEPRECATED
    int bitwidth() const { return length(); }
#endif

    // concatenation support
    virtual int
    concat_length(bool *xz_present_p) const
    {
        if (xz_present_p)
            *xz_present_p = false;
        return 1;
    }
    virtual bool
    concat_get_ctrl(sc_digit *dst_p, int low_i) const
    {
        int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
        int word_i = low_i / BITS_PER_DIGIT;

        dst_p[word_i] &= ~bit_mask;
        return false;
    }
    virtual bool
    concat_get_data(sc_digit *dst_p, int low_i) const
    {
        bool non_zero;
        int bit_mask = 1 << (low_i % BITS_PER_DIGIT);
        int word_i = low_i / BITS_PER_DIGIT;

        if (operator uint64()) {
            dst_p[word_i] |= bit_mask;
            non_zero = true;
        } else {
            dst_p[word_i] &= ~bit_mask;
            non_zero = false;
        }
        return non_zero;
    }
    virtual uint64
    concat_get_uint64() const
    {
        return operator uint64();
    }


    // implicit conversions
    operator uint64 () const;
    bool operator ! () const;
    bool operator ~ () const;


    // explicit conversions
    uint64 value() const { return operator uint64(); }

    bool to_bool() const { return operator uint64(); }


    // other methods
    void print(::std::ostream& os=::std::cout) const { os << to_bool(); }

  protected:
    int m_index;
    sc_int_base *m_obj_p;

  private:
    // Disabled
    sc_int_bitref_r &operator = (const sc_int_bitref_r &);
};


inline ::std::ostream &operator << (::std::ostream &, const sc_int_bitref_r &);


// ----------------------------------------------------------------------------
//  CLASS : sc_int_bitref
//
//  Proxy class for sc_int bit selection (r-value and l-value).
// ----------------------------------------------------------------------------

class sc_int_bitref : public sc_int_bitref_r
{
    friend class sc_int_base;
    friend class sc_core::sc_vpool<sc_int_bitref>;

    // constructor
    sc_int_bitref() : sc_int_bitref_r() {}

  public:
    // copy constructor
    sc_int_bitref(const sc_int_bitref &a) : sc_int_bitref_r(a) {}

    // assignment operators
    sc_int_bitref &operator = (const sc_int_bitref_r &b);
    sc_int_bitref &operator = (const sc_int_bitref &b);
    sc_int_bitref &operator = (bool b);

    sc_int_bitref &operator &= (bool b);
    sc_int_bitref &operator |= (bool b);
    sc_int_bitref &operator ^= (bool b);

    // concatenation methods
    virtual void concat_set(int64 src, int low_i);
    virtual void concat_set(const sc_signed &src, int low_i);
    virtual void concat_set(const sc_unsigned &src, int low_i);
    virtual void concat_set(uint64 src, int low_i);

    // other methods
    void scan(::std::istream &is=::std::cin);

  public:
    static sc_core::sc_vpool<sc_int_bitref> m_pool;
};



inline ::std::istream &operator >> (::std::istream &, sc_int_bitref &);


// ----------------------------------------------------------------------------
//  CLASS : sc_int_subref_r
//
//  Proxy class for sc_int part selection (r-value only).
// ----------------------------------------------------------------------------

class sc_int_subref_r : public sc_value_base
{
    friend class sc_int_base;
    friend class sc_int_signal;
    friend class sc_int_subref;

  protected:
    // constructor
    sc_int_subref_r() : sc_value_base(), m_left(0), m_obj_p(0), m_right(0) {}

    // initializer for sc_core::sc_vpool:
    void initialize( const sc_int_base *obj_p, int left_i, int right_i)
    {
        m_obj_p = (sc_int_base *)obj_p;
        m_left = left_i;
        m_right = right_i;
    }

  public:
    // copy constructor
    sc_int_subref_r(const sc_int_subref_r &a) :
        sc_value_base(a), m_left(a.m_left), m_obj_p(a.m_obj_p),
        m_right(a.m_right)
    {}

    // destructor
    virtual ~sc_int_subref_r() {}

    // capacity
    int length() const { return (m_left - m_right + 1); }

    // concatenation support
    virtual int
    concat_length(bool *xz_present_p) const
    {
        if (xz_present_p)
            *xz_present_p = false;
        return length();
    }
    virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
    virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
    virtual uint64
    concat_get_uint64() const
    {
        int len = length();
        uint64 val = operator uint_type();
        if (len < 64)
            return (uint64)(val & ~((uint_type)-1 << len));
        else
            return (uint64)val;
    }

    // reduce methods
    bool and_reduce() const;
    bool nand_reduce() const { return !and_reduce(); }
    bool or_reduce() const;
    bool nor_reduce() const { return or_reduce(); }
    bool xor_reduce() const;
    bool xnor_reduce() const { return xor_reduce(); }

    // implicit conversion to uint_type
    operator uint_type () const;

    // explicit conversions
    uint_type value() const { return operator uint_type(); }


    int to_int() const;
    unsigned int to_uint() const;
    long to_long() const;
    unsigned long to_ulong() const;
    int64 to_int64() const;
    uint64 to_uint64() const;
    double to_double() const;

    // explicit conversion to character string
    const std::string to_string(sc_numrep numrep=SC_DEC) const;
    const std::string to_string(sc_numrep numrep, bool w_prefix) const;

    // other methods
    void
    print(::std::ostream &os=::std::cout) const
    {
        os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
    }

  protected:
    int m_left;
    sc_int_base *m_obj_p;
    int m_right;

  private:
    const sc_int_subref_r &operator = (const sc_int_subref_r &);
};

inline ::std::ostream &operator << (::std::ostream &, const sc_int_subref_r &);


// ----------------------------------------------------------------------------
//  CLASS : sc_int_subref
//
//  Proxy class for sc_int part selection (r-value and l-value).
// ----------------------------------------------------------------------------

class sc_int_subref : public sc_int_subref_r
{
    friend class sc_int_base;
    friend class sc_core::sc_vpool<sc_int_subref>;

  protected:
    // constructor
    sc_int_subref() : sc_int_subref_r() {}

  public:
    // copy constructor
    sc_int_subref(const sc_int_subref &a) : sc_int_subref_r(a) {}

    // assignment operators
    sc_int_subref &operator = (int_type v);
    sc_int_subref &operator = (const sc_int_base &a);

    sc_int_subref &
    operator = (const sc_int_subref_r &a)
    {
        return operator = (a.operator uint_type());
    }

    sc_int_subref &
    operator = (const sc_int_subref &a)
    {
        return operator = (a.operator uint_type());
    }

    template< class T >
    sc_int_subref &
    operator = (const sc_generic_base<T> &a)
    {
        return operator = (a->to_int64());
    }

    sc_int_subref &operator = (const char *a);

    sc_int_subref &
    operator = (unsigned long a)
    {
        return operator = ((int_type)a);
    }

    sc_int_subref &
    operator = (long a)
    {
        return operator = ((int_type)a);
    }

    sc_int_subref &
    operator = (unsigned int a)
    {
        return operator = ((int_type)a);
    }

    sc_int_subref &
    operator = (int a)
    {
        return operator = ((int_type)a);
    }

    sc_int_subref &
    operator = (uint64 a)
    {
        return operator = ((int_type)a);
    }

    sc_int_subref &
    operator = (double a)
    {
        return operator = ((int_type)a);
    }

    sc_int_subref &operator = (const sc_signed &);
    sc_int_subref &operator = (const sc_unsigned &);
    sc_int_subref &operator = (const sc_bv_base &);
    sc_int_subref &operator = (const sc_lv_base &);

    // concatenation methods
    virtual void concat_set(int64 src, int low_i);
    virtual void concat_set(const sc_signed &src, int low_i);
    virtual void concat_set(const sc_unsigned &src, int low_i);
    virtual void concat_set(uint64 src, int low_i);

    // other methods
    void scan(::std::istream &is=::std::cin);

  public:
    static sc_core::sc_vpool<sc_int_subref> m_pool;
};


inline ::std::istream &operator >> (::std::istream &, sc_int_subref &);


// ----------------------------------------------------------------------------
//  CLASS : sc_int_base
//
//  Base class for sc_int.
// ----------------------------------------------------------------------------

class sc_int_base : public sc_value_base
{
    friend class sc_int_bitref_r;
    friend class sc_int_bitref;
    friend class sc_int_subref_r;
    friend class sc_int_subref;


    // support methods
    void invalid_length() const;
    void invalid_index(int i) const;
    void invalid_range(int l, int r) const;

    void
    check_length() const
    {
        if (m_len <= 0 || m_len > SC_INTWIDTH) {
            invalid_length();
        }
    }

    void
    check_index(int i) const
    {
        if (i < 0 || i >= m_len) {
            invalid_index(i);
        }
    }

    void
    check_range(int l, int r) const
    {
        if (r < 0 || l >= m_len || l < r) {
            invalid_range(l, r);
        }
    }

    void check_value() const;

    void
    extend_sign()
    {
#ifdef DEBUG_SYSTEMC
        check_value();
#endif
        m_val = (m_val << m_ulen >> m_ulen);
    }

public:

    // constructors
    explicit sc_int_base(int w=sc_length_param().len()) :
            m_val(0), m_len(w), m_ulen(SC_INTWIDTH - m_len)
    {
        check_length();
    }

    sc_int_base(int_type v, int w) :
        m_val(v), m_len(w), m_ulen(SC_INTWIDTH - m_len)
    {
        check_length();
        extend_sign();
    }

    sc_int_base(const sc_int_base &a) :
            sc_value_base(a), m_val(a.m_val), m_len(a.m_len), m_ulen(a.m_ulen)
    {}

    explicit sc_int_base(const sc_int_subref_r &a) :
        m_val(a), m_len(a.length()), m_ulen(SC_INTWIDTH - m_len)
    {
        extend_sign();
    }

    template< class T >
    explicit sc_int_base(const sc_generic_base<T> &a) :
        m_val(a->to_int64()), m_len(a->length()), m_ulen(SC_INTWIDTH - m_len)
    {
        check_length();
        extend_sign();
    }

    explicit sc_int_base(const sc_signed &a);
    explicit sc_int_base(const sc_unsigned &a);
    explicit sc_int_base(const sc_bv_base &v);
    explicit sc_int_base(const sc_lv_base &v);
    explicit sc_int_base(const sc_uint_subref_r &v);
    explicit sc_int_base(const sc_signed_subref_r &v);
    explicit sc_int_base(const sc_unsigned_subref_r &v);


    // destructor
    virtual ~sc_int_base() {}

    // assignment operators
    sc_int_base &
    operator = (int_type v)
    {
        m_val = v;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator = (const sc_int_base &a)
    {
        m_val = a.m_val;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator = (const sc_int_subref_r &a)
    {
        m_val = a;
        extend_sign();
        return *this;
    }

    template<class T>
    sc_int_base &
    operator = (const sc_generic_base<T> &a)
    {
        m_val = a->to_int64();
        extend_sign();
        return *this;
    }

    sc_int_base &operator = (const sc_signed &a);
    sc_int_base &operator = (const sc_unsigned &a);

    sc_int_base &operator = (const sc_fxval &a);
    sc_int_base &operator = (const sc_fxval_fast &a);
    sc_int_base &operator = (const sc_fxnum &a);
    sc_int_base &operator = (const sc_fxnum_fast &a);

    sc_int_base &operator = (const sc_bv_base &a);
    sc_int_base &operator = (const sc_lv_base &a);

    sc_int_base &operator = (const char *a);

    sc_int_base &
    operator = (unsigned long a)
    {
        m_val = a;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator = (long a)
    {
        m_val = a;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator = (unsigned int a)
    {
        m_val = a;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator = (int a)
    {
        m_val = a;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator = (uint64 a)
    {
        m_val = a;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator = (double a)
    {
        m_val = (int_type)a;
        extend_sign();
        return *this;
    }

    // arithmetic assignment operators
    sc_int_base &
    operator += (int_type v)
    {
        m_val += v;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator -= (int_type v)
    {
        m_val -= v;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator *= (int_type v)
    {
        m_val *= v;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator /= (int_type v)
    {
        m_val /= v;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator %= (int_type v)
    {
        m_val %= v;
        extend_sign();
        return *this;
    }


    // bitwise assignment operators
    sc_int_base &
    operator &= (int_type v)
    {
        m_val &= v;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator |= (int_type v)
    {
        m_val |= v;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator ^= (int_type v)
    {
        m_val ^= v;
        extend_sign();
        return *this;
    }


    sc_int_base &
    operator <<= (int_type v)
    {
        m_val <<= v;
        extend_sign();
        return *this;
    }

    sc_int_base &
    operator >>= (int_type v)
    {
        m_val >>= v;
        /* no sign extension needed */
        return *this;
    }


    // prefix and postfix increment and decrement operators
    sc_int_base &
    operator ++ () // prefix
    {
        ++m_val;
        extend_sign();
        return *this;
    }

    const sc_int_base
    operator ++ (int) // postfix
    {
        sc_int_base tmp(*this);
        ++m_val;
        extend_sign();
        return tmp;
    }

    sc_int_base &
    operator -- () // prefix
    {
        --m_val;
        extend_sign();
        return *this;
    }

    const sc_int_base
    operator -- ( int ) // postfix
    {
        sc_int_base tmp(*this);
        --m_val;
        extend_sign();
        return tmp;
    }


    // relational operators
    friend bool
    operator == (const sc_int_base &a, const sc_int_base &b)
    {
        return a.m_val == b.m_val;
    }

    friend bool
    operator != (const sc_int_base &a, const sc_int_base &b)
    {
        return a.m_val != b.m_val;
    }

    friend bool
    operator < (const sc_int_base &a, const sc_int_base &b)
    {
        return a.m_val < b.m_val;
    }

    friend bool
    operator <= (const sc_int_base &a, const sc_int_base &b)
    {
        return a.m_val <= b.m_val;
    }

    friend bool
    operator > (const sc_int_base &a, const sc_int_base &b)
    {
        return a.m_val > b.m_val;
    }

    friend bool
    operator >= (const sc_int_base &a, const sc_int_base &b)
    {
        return a.m_val >= b.m_val;
    }


    // bit selection
    sc_int_bitref &operator [] (int i);
    const sc_int_bitref_r &operator [] (int i) const;

    sc_int_bitref &bit(int i);
    const sc_int_bitref_r &bit(int i) const;


    // part selection
    sc_int_subref &operator () (int left, int right);
    const sc_int_subref_r &operator () (int left, int right) const;

    sc_int_subref &range(int left, int right);
    const sc_int_subref_r &range(int left, int right) const;


    // bit access, without bounds checking or sign extension
    bool test(int i) const { return (0 != (m_val & (UINT_ONE << i))); }

    void set(int i) { m_val |= (UINT_ONE << i); }

    void
    set(int i, bool v)
    {
        v ? m_val |= (UINT_ONE << i) : m_val &= ~(UINT_ONE << i);
    }

    // capacity
    int length() const { return m_len; }

    // concatenation support
    virtual int
    concat_length(bool* xz_present_p) const
    {
        if (xz_present_p)
            *xz_present_p = false;
        return length();
    }
    virtual bool concat_get_ctrl( sc_digit* dst_p, int low_i ) const;
    virtual bool concat_get_data( sc_digit* dst_p, int low_i ) const;
    virtual uint64
    concat_get_uint64() const
    {
        if (m_len < 64)
            return (uint64)(m_val & ~((uint_type) - 1 << m_len));
        else
            return (uint64)m_val;
    }
    virtual void concat_set(int64 src, int low_i);
    virtual void concat_set(const sc_signed &src, int low_i);
    virtual void concat_set(const sc_unsigned &src, int low_i);
    virtual void concat_set(uint64 src, int low_i);


    // reduce methods
    bool and_reduce() const;
    bool nand_reduce() const { return !and_reduce(); }
    bool or_reduce() const;
    bool nor_reduce() const { return !or_reduce(); }
    bool xor_reduce() const;
    bool xnor_reduce() const { return !xor_reduce(); }


    // implicit conversion to int_type
    operator int_type() const { return m_val; }


    // explicit conversions
    int_type value() const { return operator int_type(); }
    int to_int() const { return (int)m_val; }
    unsigned int to_uint() const { return (unsigned int)m_val; }
    long to_long() const { return (long)m_val; }
    unsigned long to_ulong() const { return (unsigned long)m_val; }
    int64 to_int64() const { return (int64)m_val; }
    uint64 to_uint64() const { return (uint64)m_val; }
    double to_double() const { return (double)m_val; }
    long long_low() const { return (long)(m_val & UINT64_32ONES); }
    long long_high() const { return (long)((m_val >> 32) & UINT64_32ONES); }


    // explicit conversion to character string
    const std::string to_string(sc_numrep numrep=SC_DEC) const;
    const std::string to_string(sc_numrep numrep, bool w_prefix) const;


    // other methods
    void
    print(::std::ostream &os=::std::cout) const
    {
        os << to_string(sc_io_base(os, SC_DEC), sc_io_show_base(os));
    }

    void scan(::std::istream &is=::std::cin);

  protected:
    int_type m_val; // value
    int m_len; // length
    int m_ulen; // unused length
};

inline ::std::ostream &operator << (::std::ostream &, const sc_int_base &);
inline ::std::istream &operator >> (::std::istream &, sc_int_base &);


// ----------------------------------------------------------------------------
//  CLASS : sc_int_bitref_r
//
//  Proxy class for sc_int bit selection (r-value only).
// ----------------------------------------------------------------------------

// implicit conversion to uint64

inline sc_int_bitref_r::operator uint64 () const
{
    return m_obj_p->test(m_index);
}

inline bool
sc_int_bitref_r::operator ! () const
{
    return ! m_obj_p->test(m_index);
}

inline bool
sc_int_bitref_r::operator ~ () const
{
    return !m_obj_p->test(m_index);
}


inline ::std::ostream &
operator << (::std::ostream &os, const sc_int_bitref_r &a)
{
    a.print(os);
    return os;
}


// ----------------------------------------------------------------------------
//  CLASS : sc_int_bitref
//
//  Proxy class for sc_int bit selection (r-value and l-value).
// ----------------------------------------------------------------------------

// assignment operators

inline sc_int_bitref &
sc_int_bitref::operator = (const sc_int_bitref_r &b)
{
    m_obj_p->set(m_index, (bool)b);
    m_obj_p->extend_sign();
    return *this;
}

inline sc_int_bitref &
sc_int_bitref::operator = (const sc_int_bitref &b)
{
    m_obj_p->set(m_index, (bool)b);
    m_obj_p->extend_sign();
    return *this;
}

inline sc_int_bitref &
sc_int_bitref::operator = (bool b)
{
    m_obj_p->set(m_index, b);
    m_obj_p->extend_sign();
    return *this;
}


inline sc_int_bitref &
sc_int_bitref::operator &= (bool b)
{
    if (!b) {
        m_obj_p->set(m_index, b);
        m_obj_p->extend_sign();
    }
    return *this;
}

inline sc_int_bitref &
sc_int_bitref::operator |= (bool b)
{
    if (b) {
        m_obj_p->set(m_index, b);
        m_obj_p->extend_sign();
    }
    return *this;
}

inline sc_int_bitref &
sc_int_bitref::operator ^= (bool b)
{
    if (b) {
        m_obj_p->m_val ^= (UINT_ONE << m_index);
        m_obj_p->extend_sign();
    }
    return *this;
}



inline ::std::istream &
operator >> (::std::istream &is, sc_int_bitref &a)
{
    a.scan(is);
    return is;
}


// ----------------------------------------------------------------------------
//  CLASS : sc_int_subref_r
//
//  Proxy class for sc_int part selection (r-value only).
// ----------------------------------------------------------------------------

// implicit conversion to int_type

inline sc_int_subref_r::operator uint_type() const
{
    uint_type /*int_type*/ val = m_obj_p->m_val;
    int uleft = SC_INTWIDTH - (m_left + 1);
    int uright = uleft + m_right;
    return (val << uleft >> uright);
}


// reduce methods

inline bool
sc_int_subref_r::and_reduce() const
{
    sc_int_base a(*this);
    return a.and_reduce();
}

inline bool
sc_int_subref_r::or_reduce() const
{
    sc_int_base a(*this);
    return a.or_reduce();
}

inline bool
sc_int_subref_r::xor_reduce() const
{
    sc_int_base a(*this);
    return a.xor_reduce();
}


// explicit conversions

inline int
sc_int_subref_r::to_int() const
{
    int result = static_cast<int>(operator uint_type());
    return result;
}

inline unsigned int
sc_int_subref_r::to_uint() const
{
    unsigned int result = static_cast<unsigned int>(operator uint_type());
    return result;
}

inline long
sc_int_subref_r::to_long() const
{
    long result = static_cast<long>(operator uint_type());
    return result;
}

inline unsigned long
sc_int_subref_r::to_ulong() const
{
    unsigned long result = static_cast<unsigned long>(operator uint_type());
    return result;
}

inline int64
sc_int_subref_r::to_int64() const
{
    int64 result = operator uint_type();
    return result;
}

inline uint64
sc_int_subref_r::to_uint64() const
{
    uint64 result = operator uint_type();
    return result;
}

inline double
sc_int_subref_r::to_double() const
{
    double result = static_cast<double>(operator uint_type());
    return result;
}


// explicit conversion to character string

inline const std::string
sc_int_subref_r::to_string(sc_numrep numrep) const
{
    sc_uint_base a(length());
    a = operator uint_type();
    return a.to_string(numrep);
}

inline const std::string
sc_int_subref_r::to_string(sc_numrep numrep, bool w_prefix) const
{
    sc_uint_base a(length());
    a = operator uint_type();
    return a.to_string(numrep, w_prefix);
}


// functional notation for the reduce methods

inline bool
and_reduce(const sc_int_subref_r &a)
{
    return a.and_reduce();
}

inline bool
nand_reduce(const sc_int_subref_r &a)
{
    return a.nand_reduce();
}

inline bool
or_reduce(const sc_int_subref_r &a)
{
    return a.or_reduce();
}

inline bool
nor_reduce(const sc_int_subref_r &a)
{
    return a.nor_reduce();
}

inline bool
xor_reduce(const sc_int_subref_r &a)
{
    return a.xor_reduce();
}

inline bool
xnor_reduce(const sc_int_subref_r &a)
{
    return a.xnor_reduce();
}



inline ::std::ostream &
operator << (::std::ostream &os, const sc_int_subref_r &a)
{
    a.print(os);
    return os;
}


// ----------------------------------------------------------------------------
//  CLASS : sc_int_subref
//
//  Proxy class for sc_int part selection (r-value and l-value).
// ----------------------------------------------------------------------------

// assignment operators

inline sc_int_subref &
sc_int_subref::operator = (const sc_int_base &a)
{
    return operator = (a.operator int_type());
}

inline sc_int_subref &
sc_int_subref::operator = (const char *a)
{
    sc_int_base aa(length());
    return (*this = aa = a);
}



inline ::std::istream &
operator >> (::std::istream &is, sc_int_subref &a)
{
    a.scan(is);
    return is;
}


// ----------------------------------------------------------------------------
//  CLASS : sc_int_base
//
//  Base class for sc_int.
// ----------------------------------------------------------------------------

// bit selection

inline sc_int_bitref &
sc_int_base::operator [] (int i)
{
    check_index(i);
    sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
    result_p->initialize(this, i);
    return *result_p;
}

inline const sc_int_bitref_r &
sc_int_base::operator [] (int i) const
{
    check_index(i);
    sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
    result_p->initialize(this, i);
    return *result_p;
}


inline sc_int_bitref &
sc_int_base::bit(int i)
{
    check_index(i);
    sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
    result_p->initialize(this, i);
    return *result_p;
}

inline const sc_int_bitref_r &
sc_int_base::bit(int i) const
{
    check_index(i);
    sc_int_bitref *result_p = sc_int_bitref::m_pool.allocate();
    result_p->initialize(this, i);
    return *result_p;
}


// part selection

inline sc_int_subref &
sc_int_base::operator () (int left, int right)
{
    check_range(left, right);
    sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
    result_p->initialize(this, left, right);
    return *result_p;
}

inline const sc_int_subref_r &
sc_int_base::operator () (int left, int right) const
{
    check_range(left, right);
    sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
    result_p->initialize(this, left, right);
    return *result_p;
}


inline sc_int_subref &
sc_int_base::range(int left, int right)
{
    check_range(left, right);
    sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
    result_p->initialize(this, left, right);
    return *result_p;
}

inline const sc_int_subref_r &
sc_int_base::range(int left, int right) const
{
    check_range(left, right);
    sc_int_subref *result_p = sc_int_subref::m_pool.allocate();
    result_p->initialize(this, left, right);
    return *result_p;
}


// functional notation for the reduce methods

inline bool
and_reduce(const sc_int_base &a)
{
    return a.and_reduce();
}

inline bool
nand_reduce(const sc_int_base &a)
{
    return a.nand_reduce();
}

inline bool
or_reduce(const sc_int_base &a)
{
    return a.or_reduce();
}

inline bool
nor_reduce(const sc_int_base &a)
{
    return a.nor_reduce();
}

inline bool
xor_reduce(const sc_int_base &a)
{
    return a.xor_reduce();
}

inline bool
xnor_reduce(const sc_int_base &a)
{
    return a.xnor_reduce();
}



inline ::std::ostream &
operator << (::std::ostream &os, const sc_int_base &a)
{
    a.print(os);
    return os;
}

inline ::std::istream &
operator >> (::std::istream &is, sc_int_base &a)
{
    a.scan(is);
    return is;
}

} // namespace sc_dt

#endif // __SYSTEMC_EXT_DT_INT_SC_INT_BASE_HH__
