summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/datatypes/misc/sc_concatref.h
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/datatypes/misc/sc_concatref.h')
-rw-r--r--ext/systemc/src/sysc/datatypes/misc/sc_concatref.h855
1 files changed, 855 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/datatypes/misc/sc_concatref.h b/ext/systemc/src/sysc/datatypes/misc/sc_concatref.h
new file mode 100644
index 000000000..92dcc18ec
--- /dev/null
+++ b/ext/systemc/src/sysc/datatypes/misc/sc_concatref.h
@@ -0,0 +1,855 @@
+/*****************************************************************************
+
+ 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 SC_CONCATREF_H
+#define SC_CONCATREF_H
+
+#include "sysc/kernel/sc_object.h"
+#include "sysc/datatypes/misc/sc_value_base.h"
+#include "sysc/utils/sc_temporary.h"
+#include "sysc/datatypes/bit/sc_bv.h"
+#include "sysc/datatypes/bit/sc_lv.h"
+#include "sysc/datatypes/int/sc_int_base.h"
+#include "sysc/datatypes/int/sc_uint_base.h"
+#include "sysc/datatypes/int/sc_signed.h"
+#include "sysc/datatypes/int/sc_unsigned.h"
+
+namespace sc_core {
+ extern sc_byte_heap sc_temp_heap; // Temporary storage.
+} // 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; }
+
+#ifdef SC_DT_DEPRECATED
+ int bitwidth() const
+ { return length(); }
+#endif
+
+ // 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 );
+#if defined(_MSC_VER)
+ // workaround spurious initialisation issue on MS Visual C++
+ memset( result_p->digit, 0, sizeof(sc_digit)*result_p->ndigits );
+#else
+ result_p->digit[result_p->ndigits-1] = 0;
+#endif
+ 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:
+ static sc_core::sc_vpool<sc_concatref> m_pool; // Pool of temporary objects.
+
+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 // SC_CONCATREF_H
+