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

  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_concatref.h -- Concatenation support.

  Original Author: Andy Goodrich, Forte Design, Inc.

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

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

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

      Name, Affiliation, Date:
  Description of Modification:

  Andy Goodrich, Forte Design Systems, 17 Nov 2002
  Creation of sc_concatref class by merging the capabilities of
  sc_int_concref, sc_int_concref, sc_uint_concref, sc_uint_concref,
  and implementing the capabilities of sc_signed_concref, sc_signed_concref,
  sc_unsigned_concref, and sc_unsigned_concref. The resultant class allows
  mixed mode concatenations on the left and right sides of an assignment.

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

// $Log: sc_concatref.h,v $
// Revision 1.6  2011/08/24 22:05:48  acg
//  Torsten Maehne: initialization changes to remove warnings.
//
// Revision 1.5  2009/11/17 19:58:15  acg
//  Andy Goodrich: fix of shift rhs possibilities to include "int".
//
// Revision 1.4  2009/02/28 00:26:29  acg
//  Andy Goodrich: bug fixes.
//
// Revision 1.3  2008/04/29 20:23:55  acg
//  Andy Goodrich: fixed the code that assigns the value of a string to
//  an sc_concatref instance.
//
// Revision 1.2  2008/02/14 20:57:26  acg
//  Andy Goodrich: added casts to ~0 instances to keep MSVC compiler happy.
//
// Revision 1.1.1.1  2006/12/15 20:20:05  acg
// SystemC 2.3
//
// Revision 1.4  2006/10/23 19:36:59  acg
//  Andy Goodrich: changed casts for operations on concatenation values to
//  mirror those of sc_unsigned. For instance, an sc_unsigned minus a value
//  returns an sc_signed result, whereas an sc_concatref minus a value was
//  returning an sc_unsigned result. Now both sc_unsigned and sc_concatref
//  minus a value return an sc_signed result.
//
// Revision 1.3  2006/01/13 18:54:01  acg
// Andy Goodrich: added $Log command so that CVS comments are reproduced in
// the source.
//

#ifndef __SYSTEMC_EXT_DT_MISC_SC_CONCATREF_HH__
#define __SYSTEMC_EXT_DT_MISC_SC_CONCATREF_HH__

#include <iostream>

#include "../bit/sc_bv.hh"
#include "../bit/sc_lv.hh"
#include "../int/sc_int_base.hh"
#include "../int/sc_signed.hh"
#include "../int/sc_uint_base.hh"
#include "../int/sc_unsigned.hh"
#include "../sc_temporary.hh"
#include "sc_value_base.hh"

namespace sc_dt
{

// classes defined in this module
class sc_concatref;
class sc_concat_bool;

} // namespace sc_dt

namespace sc_core
{

extern sc_byte_heap sc_temp_heap; // Temporary storage.

// explicit template instantiations
extern template class sc_vpool<sc_dt::sc_concatref>;
extern template class sc_vpool<sc_dt::sc_concat_bool>;

} // namespace sc_core

namespace sc_dt {

// ----------------------------------------------------------------------------
//  CLASS TEMPLATE : sc_concatref
//
//  Proxy class for sized bit concatenation.
// ----------------------------------------------------------------------------

class sc_concatref : public sc_generic_base<sc_concatref>, public sc_value_base
{
  public:
    friend class sc_core::sc_vpool<sc_concatref>;

    inline void
    initialize(sc_value_base &left, sc_value_base &right)
    {
        bool left_xz; // True if x's and/or z's found in left.
        bool right_xz; // True if x's and/or z's found in right.

        m_left_p = (sc_value_base *)&left;
        m_right_p = (sc_value_base *)&right;
        m_len_r = right.concat_length(&right_xz);
        m_len = left.concat_length(&left_xz) + m_len_r;
        m_flags = (left_xz || right_xz) ? cf_xz_present : cf_none;
    }


    inline void
    initialize(const sc_value_base &left, const sc_value_base &right)
    {
        bool left_xz;   // True if x's and/or z's found in left.
        bool right_xz;  // True if x's and/or z's found in right.

        m_left_p = (sc_value_base *)&left;
        m_right_p = (sc_value_base *)&right;
        m_len_r = right.concat_length(&right_xz);
        m_len = left.concat_length(&left_xz) + m_len_r;
        m_flags = (left_xz || right_xz) ? cf_xz_present : cf_none;
    }

    // destructor
    virtual ~sc_concatref() {}

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

    // concatenation
    virtual int
    concat_length(bool *xz_present_p) const
    {
        if (xz_present_p)
            *xz_present_p = m_flags & cf_xz_present ? true : false;
        return m_len;
    }

    virtual void
    concat_clear_data(bool to_ones)
    {
        m_left_p->concat_clear_data(to_ones);
        m_right_p->concat_clear_data(to_ones);
    }

    virtual bool
    concat_get_ctrl(sc_digit *dst_p, int low_i) const
    {
        bool rnz = m_right_p->concat_get_ctrl(dst_p, low_i);
        bool lnz = m_left_p->concat_get_ctrl(dst_p, low_i + m_len_r);
        return rnz || lnz;
    }

    virtual bool
    concat_get_data(sc_digit *dst_p, int low_i) const
    {
        bool rnz = m_right_p->concat_get_data(dst_p, low_i);
        bool lnz = m_left_p->concat_get_data(dst_p, low_i + m_len_r);
        return rnz || lnz;
    }

    virtual uint64
    concat_get_uint64() const
    {
        if (m_len_r >= 64) {
            return m_right_p->concat_get_uint64();
        } else {
            return (m_left_p->concat_get_uint64() << m_len_r) |
                m_right_p->concat_get_uint64();
        }
    }

    virtual void
    concat_set(int64 src, int low_i)
    {
        m_right_p->concat_set(src, low_i);
        m_left_p->concat_set(src, low_i + m_len_r);
    }

    virtual void
    concat_set(const sc_signed &src, int low_i)
    {
        m_right_p->concat_set(src, low_i);
        m_left_p->concat_set(src, low_i + m_len_r);
    }

    virtual void
    concat_set(const sc_unsigned &src, int low_i)
    {
        m_right_p->concat_set(src, low_i);
        m_left_p->concat_set(src, low_i + m_len_r);
    }

    virtual void
    concat_set(uint64 src, int low_i)
    {
        m_right_p->concat_set(src, low_i);
        m_left_p->concat_set(src, low_i + m_len_r);
    }

    // explicit conversions
    uint64
    to_uint64() const
    {
        uint64 mask;
        uint64 result;

        result = m_right_p->concat_get_uint64();
        if (m_len_r < 64) {
            mask = (uint64)~0;
            result = (m_left_p->concat_get_uint64() << m_len_r) |
                        (result & ~(mask << m_len_r));
        }
        if (m_len < 64) {
            mask = (uint64)~0;
            result = result & ~(mask << m_len);
        }
        return result;
    }

    const sc_unsigned &
    value() const
    {
        bool left_non_zero;
        sc_unsigned *result_p = sc_unsigned::m_pool.allocate();
        bool right_non_zero;

        result_p->nbits = result_p->num_bits(m_len);
        result_p->ndigits = DIV_CEIL(result_p->nbits);
        result_p->digit = (sc_digit *)sc_core::sc_temp_heap.allocate(
            sizeof(sc_digit) * result_p->ndigits);
        result_p->digit[result_p->ndigits - 1] = 0;
        right_non_zero = m_right_p->concat_get_data(result_p->digit, 0);
        left_non_zero = m_left_p->concat_get_data(result_p->digit, m_len_r);
        if (left_non_zero || right_non_zero)
            result_p->sgn = SC_POS;
        else
            result_p->sgn = SC_ZERO;
        return *result_p;
    }

    int64 to_int64() const { return (int64)to_uint64(); }
    int to_int() const { return (int)to_int64(); }
    unsigned int to_uint() const { return (unsigned int)to_uint64(); }
    long to_long() const { return (long)to_int64(); }
    unsigned long to_ulong() const { return (unsigned long)to_uint64(); }
    double to_double() const { return value().to_double(); }

    void to_sc_signed(sc_signed &target) const { target = value(); }

    void to_sc_unsigned(sc_unsigned &target) const { target = value(); }

    // implicit conversions:
    operator uint64 () const { return to_uint64(); }

    operator const sc_unsigned & () const { return value(); }

    // unary operators:
    sc_unsigned operator + () const { return value(); }

    sc_signed operator - () const { return -value(); }

    sc_unsigned operator ~ () const { return ~value(); }

    // explicit conversion to character string
    const std::string
    to_string(sc_numrep numrep=SC_DEC) const
    {
        return value().to_string(numrep);
    }

    const std::string
    to_string(sc_numrep numrep, bool w_prefix) const
    {
        return value().to_string(numrep,w_prefix);
    }

    // assignments
    inline const sc_concatref &
    operator = (int v)
    {
        m_right_p->concat_set((int64)v, 0);
        m_left_p->concat_set((int64)v, m_len_r);
        return *this;
    }

    inline const sc_concatref &
    operator = (long v)
    {
        m_right_p->concat_set((int64)v, 0);
        m_left_p->concat_set((int64)v, m_len_r);
        return *this;
    }

    inline const sc_concatref &
    operator = (int64 v)
    {
        m_right_p->concat_set(v, 0);
        m_left_p->concat_set(v, m_len_r);
        return *this;
    }

    inline const sc_concatref &
    operator = (unsigned int v)
    {
        m_right_p->concat_set((uint64)v, 0);
        m_left_p->concat_set((uint64)v, m_len_r);
        return *this;
    }

    inline const sc_concatref &
    operator = (unsigned long v)
    {
        m_right_p->concat_set((uint64)v, 0);
        m_left_p->concat_set((uint64)v, m_len_r);
        return *this;
    }

    inline const sc_concatref &
    operator = (uint64 v)
    {
        m_right_p->concat_set(v, 0);
        m_left_p->concat_set(v, m_len_r);
        return *this;
    }

    const sc_concatref &
    operator = (const sc_concatref &v)
    {
        sc_unsigned temp(v.length());
        temp = v.value();
        m_right_p->concat_set(temp, 0);
        m_left_p->concat_set(temp, m_len_r);
        return *this;
    }

    const sc_concatref &
    operator = (const sc_signed &v)
    {
        m_right_p->concat_set(v, 0);
        m_left_p->concat_set(v, m_len_r);
        return *this;
    }

    const sc_concatref &
    operator = (const sc_unsigned &v)
    {
        m_right_p->concat_set(v, 0);
        m_left_p->concat_set(v, m_len_r);
        return *this;
    }

    const sc_concatref &
    operator = (const char *v_p)
    {
        sc_unsigned v(m_len);
        v = v_p;
        m_right_p->concat_set(v, 0);
        m_left_p->concat_set(v, m_len_r);
        return *this;
    }

    const sc_concatref &
    operator = (const sc_bv_base &v)
    {
        sc_unsigned temp(v.length());
        temp = v;
        m_right_p->concat_set(temp, 0);
        m_left_p->concat_set(temp, m_len_r);
        return *this;
    }

    const sc_concatref &
    operator = (const sc_lv_base &v)
    {
        sc_unsigned data(v.length());
        data = v;
        m_right_p->concat_set(data, 0);
        m_left_p->concat_set(data, m_len_r);
        return *this;
    }

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

    // other methods
    void print(::std::ostream &os=::std::cout) const { os << this->value(); }

    void
    scan(::std::istream &is)
    {
        std::string s;
        is >> s;
        *this = s.c_str();
    }

  public:
    // Pool of temporary objects.
    static sc_core::sc_vpool<sc_concatref> m_pool;

  public:
    enum concat_flags {
        cf_none = 0,        // Normal value.
        cf_xz_present = 1   // X and/or Z values present.
    };

  protected:
    sc_value_base *m_left_p;  // Left hand operand of concatenation.
    sc_value_base *m_right_p; // Right hand operand of concatenation.
    int m_len;                // Length of concatenation.
    int m_len_r;              // Length of m_rightt_p.
    concat_flags m_flags;     // Value is read only.

  private:
    sc_concatref(const sc_concatref &);
    sc_concatref() : m_left_p(0), m_right_p(0), m_len(0), m_len_r(0), m_flags()
    {}
};

// functional notation for the reduce methods
inline bool and_reduce(const sc_concatref &a) { return a.and_reduce(); }
inline bool nand_reduce(const sc_concatref &a) { return a.nand_reduce(); }
inline bool or_reduce(const sc_concatref &a) { return a.or_reduce(); }
inline bool nor_reduce(const sc_concatref &a) { return a.nor_reduce(); }
inline bool xor_reduce(const sc_concatref &a) { return a.xor_reduce(); }
inline bool xnor_reduce(const sc_concatref &a) { return a.xnor_reduce(); }

// SHIFT OPERATORS FOR sc_concatref OBJECT INSTANCES:
//
// Because sc_concatref has implicit casts to both uint64 and sc_unsigned
// it is necessary to disambiguate the use of the shift operators. We do
// this in favor of sc_unsigned so that precision is not lost. To get an
// integer-based result use a cast to uint64 before performing the shift.

inline const sc_unsigned
operator << (const sc_concatref &target, uint64 shift)
{
    return target.value() << (int)shift;
}

inline const sc_unsigned
operator << (const sc_concatref &target, int64 shift)
{
    return target.value() << (int)shift;
}

inline const sc_unsigned
operator << (const sc_concatref &target, unsigned long shift)
{
    return target.value() << (int)shift;
}

inline const sc_unsigned
operator << (const sc_concatref &target, int shift)
{
    return target.value() << shift;
}

inline const sc_unsigned
operator << (const sc_concatref &target, unsigned int shift)
{
    return target.value() << (int)shift;
}

inline const sc_unsigned
operator << (const sc_concatref &target, long shift)
{
    return target.value() << (int)shift;
}

inline const sc_unsigned
operator >> (const sc_concatref &target, uint64 shift)
{
    return target.value() >> (int)shift;
}

inline const sc_unsigned
operator >> (const sc_concatref &target, int64 shift)
{
    return target.value() >> (int)shift;
}

inline const sc_unsigned
operator >> (const sc_concatref &target, unsigned long shift)
{
    return target.value() >> (int)shift;
}

inline const sc_unsigned
operator >> (const sc_concatref &target, int shift)
{
    return target.value() >> shift;
}

inline const sc_unsigned
operator >> (const sc_concatref &target, unsigned int shift)
{
    return target.value() >> (int)shift;
}

inline const sc_unsigned
operator >> (const sc_concatref &target, long shift)
{
    return target.value() >> (int)shift;
}

// STREAM OPERATORS FOR sc_concatref OBJECT INSTANCES:
inline ::std::ostream &
operator << (::std::ostream &os, const sc_concatref &v)
{
    return os << v.value();
}

inline ::std::istream &
operator >> (::std::istream &is, sc_concatref &a)
{
    sc_unsigned temp(a.concat_length(0));
    temp.scan(is);
    a = temp;
    return is;
}


// ----------------------------------------------------------------------------
//  CLASS TEMPLATE : sc_concat_bool
//
//  Proxy class for read-only boolean values in concatenations.
// ----------------------------------------------------------------------------

class sc_concat_bool : public sc_value_base
{
  protected:
    static sc_core::sc_vpool<sc_concat_bool> m_pool; // Temporaries pool.
    bool m_value;                                    // Value for this obj.

  public:
    // constructor:
    sc_concat_bool() : sc_value_base(), m_value() {}

    // destructor:
    virtual ~sc_concat_bool() { }

    // allocation of temporary object:
    static inline sc_concat_bool *
    allocate(bool v)
    {
        sc_concat_bool *result_p = m_pool.allocate();
        result_p->m_value = v;
        return result_p;
    }

    // concatenation:
    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 = 1 << (low_i % BITS_PER_DIGIT);
        int word_i = low_i / BITS_PER_DIGIT;
        dst_p[word_i] &= ~bit;
        return false;
    }

    virtual bool
    concat_get_data(sc_digit *dst_p, int low_i) const
    {
        int bit = 1 << (low_i % BITS_PER_DIGIT);
        int word_i = low_i / BITS_PER_DIGIT;
        if (m_value)
            dst_p[word_i] |= bit;
        else
            dst_p[word_i] &= ~bit;
        return m_value;
    }

    virtual uint64
    concat_get_uint64() const
    {
        return m_value ? 1 : 0;
    }
};


// ----------------------------------------------------------------------------
// ARITHMETIC AND LOGIC OPERATORS FOR sc_concatref
// ----------------------------------------------------------------------------

#define SC_CONCAT_OP_TYPE(RESULT, OP, OTHER_TYPE) \
    inline RESULT \
    operator OP (const sc_concatref &a, OTHER_TYPE b) \
    { \
        return a.value() OP b; \
    } \
    inline RESULT \
    operator OP (OTHER_TYPE a, const sc_concatref &b) \
    { \
        return a OP b.value(); \
    }


#define SC_CONCAT_OP(RESULT, OP) \
    inline RESULT \
    operator OP (const sc_concatref &a, const sc_concatref &b) \
    { \
        return a.value() OP b.value(); \
    }  \
    SC_CONCAT_OP_TYPE(const sc_signed, OP, int) \
    SC_CONCAT_OP_TYPE(const sc_signed, OP, long) \
    SC_CONCAT_OP_TYPE(const sc_signed, OP, int64) \
    SC_CONCAT_OP_TYPE(RESULT, OP, unsigned int) \
    SC_CONCAT_OP_TYPE(RESULT, OP, unsigned long) \
    SC_CONCAT_OP_TYPE(RESULT, OP, uint64) \
    SC_CONCAT_OP_TYPE(const sc_signed, OP, const sc_int_base &) \
    SC_CONCAT_OP_TYPE(RESULT, OP, const sc_uint_base &) \
    SC_CONCAT_OP_TYPE(const sc_signed, OP, const sc_signed &) \
    SC_CONCAT_OP_TYPE(RESULT, OP, const sc_unsigned &) \
    inline RESULT \
    operator OP (const sc_concatref &a, bool b) \
    { \
        return a.value() OP (int)b; \
    } \
    inline RESULT \
    operator OP (bool a, const sc_concatref &b) \
    { \
        return (int)a OP b.value(); \
    }

#define SC_CONCAT_BOOL_OP(OP) \
    inline bool \
    operator OP (const sc_concatref &a, const sc_concatref &b) \
    { \
        return a.value() OP b.value(); \
    }  \
    SC_CONCAT_OP_TYPE(bool, OP, int) \
    SC_CONCAT_OP_TYPE(bool, OP, long) \
    SC_CONCAT_OP_TYPE(bool, OP, int64) \
    SC_CONCAT_OP_TYPE(bool, OP, unsigned int) \
    SC_CONCAT_OP_TYPE(bool, OP, unsigned long) \
    SC_CONCAT_OP_TYPE(bool, OP, uint64) \
    SC_CONCAT_OP_TYPE(bool, OP, const sc_int_base &) \
    SC_CONCAT_OP_TYPE(bool, OP, const sc_uint_base &) \
    SC_CONCAT_OP_TYPE(bool, OP, const sc_signed &) \
    SC_CONCAT_OP_TYPE(bool, OP, const sc_unsigned &) \
    inline bool \
    operator OP (const sc_concatref &a, bool b) \
    { \
        return a.value() OP (int)b; \
    } \
    inline bool \
    operator OP (bool a, const sc_concatref &b) \
    { \
        return (int)a OP b.value(); \
    }

SC_CONCAT_OP(const sc_unsigned, +)
SC_CONCAT_OP(const sc_signed, -)
SC_CONCAT_OP(const sc_unsigned, *)
SC_CONCAT_OP(const sc_unsigned, /)
SC_CONCAT_OP(const sc_unsigned, %)
SC_CONCAT_OP(const sc_unsigned, &)
SC_CONCAT_OP(const sc_unsigned, |)
SC_CONCAT_OP(const sc_unsigned, ^)
SC_CONCAT_BOOL_OP(==)
SC_CONCAT_BOOL_OP(<=)
SC_CONCAT_BOOL_OP(>=)
SC_CONCAT_BOOL_OP(!=)
SC_CONCAT_BOOL_OP(>)
SC_CONCAT_BOOL_OP(<)

#undef SC_CONCAT_OP
#undef SC_CONCAT_OP_TYPE


// ----------------------------------------------------------------------------
// CONCATENATION FUNCTION AND OPERATOR FOR STANDARD SYSTEM C DATA TYPES:
// ----------------------------------------------------------------------------

inline sc_dt::sc_concatref &
concat(sc_dt::sc_value_base &a, sc_dt::sc_value_base &b)
{
    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.

    result_p = sc_dt::sc_concatref::m_pool.allocate();
    result_p->initialize(a, b);
    return *result_p;
}

inline const sc_dt::sc_concatref &
concat(const sc_dt::sc_value_base &a, const sc_dt::sc_value_base &b)
{
    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.

    result_p = sc_dt::sc_concatref::m_pool.allocate();
    result_p->initialize(a, b);
    return *result_p;
}

inline const sc_dt::sc_concatref &
concat(const sc_dt::sc_value_base &a, bool b)
{
    const sc_dt::sc_concat_bool *b_p; // Proxy for boolean value.
    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.

    b_p = sc_dt::sc_concat_bool::allocate(b);
    result_p = sc_dt::sc_concatref::m_pool.allocate();
    result_p->initialize(a, *b_p);
    return *result_p;
}

inline const sc_dt::sc_concatref &
concat(bool a, const sc_dt::sc_value_base &b)
{
    const sc_dt::sc_concat_bool *a_p; // Proxy for boolean value.
    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.

    a_p = sc_dt::sc_concat_bool::allocate(a);
    result_p = sc_dt::sc_concatref::m_pool.allocate();
    result_p->initialize(*a_p, b);
    return *result_p;
}

inline sc_dt::sc_concatref &
operator , (sc_dt::sc_value_base &a, sc_dt::sc_value_base &b)
{
    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.

    result_p = sc_dt::sc_concatref::m_pool.allocate();
    result_p->initialize(a, b);
    return *result_p;
}

inline const sc_dt::sc_concatref &
operator , (const sc_dt::sc_value_base &a, const sc_dt::sc_value_base &b)
{
    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.

    result_p = sc_dt::sc_concatref::m_pool.allocate();
    result_p->initialize(a, b);
    return *result_p;
}

inline const sc_dt::sc_concatref &
operator , (const sc_dt::sc_value_base &a, bool b)
{
    const sc_dt::sc_concat_bool *b_p; // Proxy for boolean value.
    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.

    b_p = sc_dt::sc_concat_bool::allocate(b);
    result_p = sc_dt::sc_concatref::m_pool.allocate();
    result_p->initialize(a, *b_p);
    return *result_p;
}

inline const sc_dt::sc_concatref &
operator , (bool a, const sc_dt::sc_value_base &b)
{
    const sc_dt::sc_concat_bool *a_p; // Proxy for boolean value.
    sc_dt::sc_concatref *result_p; // Proxy for the concatenation.

    a_p = sc_dt::sc_concat_bool::allocate(a);
    result_p = sc_dt::sc_concatref::m_pool.allocate();
    result_p->initialize(*a_p, b);
    return *result_p;
}

} // namespace sc_dt

#endif //  __SYSTEMC_EXT_DT_MISC_SC_CONCATREF_HH__
