1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_lv_base.h -- Arbitrary size logic vector class.
23
24  Original Author: Gene Bushuyev, Synopsys, Inc.
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35        Andy Goodrich, Forte Design Systems
36          Fixed bug in clean_tail for sizes that are modulo 32, which caused
37          zeroing of values.
38
39 *****************************************************************************/
40
41// $Log: sc_lv_base.h,v $
42// Revision 1.4  2011/08/26 22:32:00  acg
43//  Torsten Maehne: added parentheses to make opearator ordering more obvious.
44//
45// Revision 1.3  2010/01/27 19:41:29  acg
46//  Andy Goodrich: fix 8 instances of sc_concref constructor invocations
47//  that failed to indicate that their arguments should be freed when the
48//  object was freed.
49//
50// Revision 1.2  2009/02/28 00:26:14  acg
51//  Andy Goodrich: bug fixes.
52//
53// Revision 1.2  2007/03/14 17:47:49  acg
54//  Andy Goodrich: Formatting.
55//
56// Revision 1.1.1.1  2006/12/15 20:31:36  acg
57// SystemC 2.2
58//
59// Revision 1.3  2006/01/13 18:53:53  acg
60// Andy Goodrich: added $Log command so that CVS comments are reproduced in
61// the source.
62//
63
64#ifndef __SYSTEMC_EXT_DT_BIT_SC_LV_BASE_HH__
65#define __SYSTEMC_EXT_DT_BIT_SC_LV_BASE_HH__
66
67#include "../int/sc_length_param.hh"
68#include "sc_bv_base.hh"
69#include "sc_logic.hh"
70
71namespace sc_dt
72{
73
74// classes defined in this module
75class sc_lv_base;
76
77
78// ----------------------------------------------------------------------------
79//  CLASS : sc_lv_base
80//
81//  Arbitrary size logic vector base class.
82// ----------------------------------------------------------------------------
83
84class sc_lv_base : public sc_proxy<sc_lv_base>
85{
86    friend class sc_bv_base;
87
88    void init(int length_, const sc_logic &init_value=SC_LOGIC_X);
89    void assign_from_string(const std::string &);
90
91  public:
92    // typedefs
93    typedef sc_proxy<sc_lv_base> base_type;
94    typedef base_type::value_type value_type;
95
96    // constructors
97    explicit sc_lv_base(int length_=sc_length_param().len()) :
98        m_len(0), m_size(0), m_data(0), m_ctrl(0)
99    {
100        init(length_);
101    }
102
103    explicit sc_lv_base(
104            const sc_logic &a, int length_=sc_length_param().len()) :
105        m_len(0), m_size(0), m_data(0), m_ctrl(0)
106    {
107        init(length_, a);
108    }
109
110    sc_lv_base(const char *a);
111    sc_lv_base(const char *a, int length_);
112
113    template <class X>
114    sc_lv_base(const sc_proxy<X> &a) :
115        m_len(0), m_size(0), m_data(0), m_ctrl(0)
116    {
117        init(a.back_cast().length());
118        base_type::assign_(a);
119    }
120
121    sc_lv_base(const sc_lv_base &a);
122
123    // destructor
124    virtual ~sc_lv_base() { delete [] m_data; }
125
126    // assignment operators
127    template <class X>
128    sc_lv_base &
129    operator = (const sc_proxy<X> &a)
130    {
131        assign_p_(*this, a);
132        return *this;
133    }
134
135    sc_lv_base &
136    operator = (const sc_lv_base &a)
137    {
138        assign_p_(*this, a);
139        return *this;
140    }
141
142    sc_lv_base &operator = (const char *a);
143
144    sc_lv_base &
145    operator = (const bool *a)
146    {
147        base_type::assign_(a);
148        return *this;
149    }
150
151    sc_lv_base &
152    operator = (const sc_logic *a)
153    {
154        base_type::assign_(a);
155        return *this;
156    }
157
158    sc_lv_base &
159    operator = (const sc_unsigned &a)
160    {
161        base_type::assign_(a);
162        return *this;
163    }
164
165    sc_lv_base &
166    operator = (const sc_signed &a)
167    {
168        base_type::assign_(a);
169        return *this;
170    }
171
172    sc_lv_base &
173    operator = (const sc_uint_base &a)
174    {
175        base_type::assign_(a);
176        return *this;
177    }
178
179    sc_lv_base &
180    operator = (const sc_int_base &a)
181    {
182        base_type::assign_(a);
183        return *this;
184    }
185
186    sc_lv_base &
187    operator = (unsigned long a)
188    {
189        base_type::assign_(a);
190        return *this;
191    }
192
193    sc_lv_base &
194    operator = (long a)
195    {
196        base_type::assign_(a);
197        return *this;
198    }
199
200    sc_lv_base &
201    operator = (unsigned int a)
202    {
203        base_type::assign_(a);
204        return *this;
205    }
206
207    sc_lv_base &
208    operator = (int a)
209    {
210        base_type::assign_(a);
211        return *this;
212    }
213
214    sc_lv_base &
215    operator = (uint64 a)
216    {
217        base_type::assign_(a);
218        return *this;
219    }
220
221    sc_lv_base &
222    operator = (int64 a)
223    {
224        base_type::assign_(a);
225        return *this;
226    }
227
228    // common methods
229    int length() const { return m_len; }
230    int size() const { return m_size; }
231
232    value_type get_bit(int i) const;
233    void set_bit(int i, value_type value);
234
235    sc_digit get_word(int wi) const { return m_data[wi]; }
236
237    // note the test for out of range access here. this is necessary
238    // because of the hair-brained way concatenations are set up.
239    // an extend_sign on a concatenation uses the whole length of
240    // the concatenation to determine how many words to set.
241    void
242    set_word(int wi, sc_digit w)
243    {
244        sc_assert(wi < m_size);
245        m_data[wi] = w;
246    }
247
248    sc_digit get_cword(int wi) const { return m_ctrl[wi]; }
249
250    void
251    set_cword(int wi, sc_digit w)
252    {
253        sc_assert(wi < m_size);
254        m_ctrl[wi] = w;
255    }
256    void clean_tail();
257
258    // other methods
259    bool is_01() const;
260
261  protected:
262    int m_len; // length in bits
263    int m_size; // size of the data array
264    sc_digit *m_data; // data array
265    sc_digit *m_ctrl; // dito (control part)
266};
267
268// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
269
270inline sc_lv_base::value_type
271sc_lv_base::get_bit(int i) const
272{
273    int wi = i / SC_DIGIT_SIZE;
274    int bi = i % SC_DIGIT_SIZE;
275    return value_type(((m_data[wi] >> bi) & SC_DIGIT_ONE) |
276                      (((m_ctrl[wi] >> bi) << 1) & SC_DIGIT_TWO));
277}
278
279inline void
280sc_lv_base::set_bit(int i, value_type value)
281{
282    int wi = i / SC_DIGIT_SIZE; // word index
283    int bi = i % SC_DIGIT_SIZE; // bit index
284    sc_digit mask = SC_DIGIT_ONE << bi;
285    m_data[wi] |= mask; // set bit to 1
286    m_ctrl[wi] |= mask; // set bit to 1
287    m_data[wi] &= value << bi | ~mask;
288    m_ctrl[wi] &= value >> 1 << bi | ~mask;
289}
290
291inline void
292sc_lv_base::clean_tail()
293{
294    int wi = m_size - 1;
295    int bi = m_len % SC_DIGIT_SIZE;
296    sc_digit mask = ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi);
297    if (mask) {
298        m_data[wi] &= mask;
299        m_ctrl[wi] &= mask;
300    }
301}
302
303
304// ----------------------------------------------------------------------------
305//  CLASS TEMPLATE : sc_proxy
306//
307//  Base class template for bit/logic vector classes.
308//  (Barton/Nackmann implementation)
309// ----------------------------------------------------------------------------
310
311// bitwise operators and functions
312
313// bitwise complement
314template <class X>
315inline const sc_lv_base
316sc_proxy<X>::operator ~ () const
317{
318    sc_lv_base a(back_cast());
319    return a.b_not();
320}
321
322// bitwise and
323template <class X, class Y>
324inline X &
325operator &= (sc_proxy<X> &px, const sc_proxy<Y> &py)
326{
327    X &x = px.back_cast();
328    sc_lv_base a(x.length());
329    a = py.back_cast();
330    return b_and_assign_(x, a);
331}
332
333#define DEFN_BITWISE_AND_ASN_OP_T(tp) \
334template <class X> \
335inline X & \
336sc_proxy<X>::operator &= (tp b) \
337{ \
338    X &x = back_cast(); \
339    sc_lv_base a(x.length()); \
340    a = b; \
341    return b_and_assign_(x, a); \
342}
343
344DEFN_BITWISE_AND_ASN_OP_T(const char *)
345DEFN_BITWISE_AND_ASN_OP_T(const bool *)
346DEFN_BITWISE_AND_ASN_OP_T(const sc_logic *)
347DEFN_BITWISE_AND_ASN_OP_T(const sc_unsigned &)
348DEFN_BITWISE_AND_ASN_OP_T(const sc_signed &)
349DEFN_BITWISE_AND_ASN_OP_T(unsigned long)
350DEFN_BITWISE_AND_ASN_OP_T(long)
351DEFN_BITWISE_AND_ASN_OP_T(uint64)
352DEFN_BITWISE_AND_ASN_OP_T(int64)
353
354#undef DEFN_BITWISE_AND_ASN_OP_T
355
356template <class X, class Y>
357inline const sc_lv_base
358operator & (const sc_proxy<X> &px, const sc_proxy<Y> &py)
359{
360    sc_lv_base a(px.back_cast());
361    return (a &= py.back_cast());
362}
363
364#define DEFN_BITWISE_AND_OP_T_A(tp) \
365template <class X> \
366inline const sc_lv_base \
367sc_proxy<X>::operator & (tp b) const \
368{ \
369    sc_lv_base a(back_cast()); \
370    return (a &= b); \
371}
372
373DEFN_BITWISE_AND_OP_T_A(const char *)
374DEFN_BITWISE_AND_OP_T_A(const bool *)
375DEFN_BITWISE_AND_OP_T_A(const sc_logic *)
376DEFN_BITWISE_AND_OP_T_A(const sc_unsigned &)
377DEFN_BITWISE_AND_OP_T_A(const sc_signed &)
378DEFN_BITWISE_AND_OP_T_A(const sc_uint_base &)
379DEFN_BITWISE_AND_OP_T_A(const sc_int_base &)
380DEFN_BITWISE_AND_OP_T_A(unsigned long)
381DEFN_BITWISE_AND_OP_T_A(long)
382DEFN_BITWISE_AND_OP_T_A(unsigned int)
383DEFN_BITWISE_AND_OP_T_A(int)
384DEFN_BITWISE_AND_OP_T_A(uint64)
385DEFN_BITWISE_AND_OP_T_A(int64)
386
387#undef DEFN_BITWISE_AND_OP_T_A
388
389#define DEFN_BITWISE_AND_OP_T_B(tp) \
390template <class X> \
391inline const sc_lv_base \
392operator & (tp b, const sc_proxy<X> &px) \
393{ \
394    return (px & b); \
395}
396
397DEFN_BITWISE_AND_OP_T_B(const char *)
398DEFN_BITWISE_AND_OP_T_B(const bool *)
399DEFN_BITWISE_AND_OP_T_B(const sc_logic *)
400DEFN_BITWISE_AND_OP_T_B(const sc_unsigned &)
401DEFN_BITWISE_AND_OP_T_B(const sc_signed &)
402DEFN_BITWISE_AND_OP_T_B(const sc_uint_base &)
403DEFN_BITWISE_AND_OP_T_B(const sc_int_base &)
404DEFN_BITWISE_AND_OP_T_B(unsigned long)
405DEFN_BITWISE_AND_OP_T_B(long)
406DEFN_BITWISE_AND_OP_T_B(unsigned int)
407DEFN_BITWISE_AND_OP_T_B(int)
408DEFN_BITWISE_AND_OP_T_B(uint64)
409DEFN_BITWISE_AND_OP_T_B(int64)
410
411#undef DEFN_BITWISE_AND_OP_T_B
412
413// bitwise or
414template <class X, class Y>
415inline X &
416operator |= (sc_proxy<X> &px, const sc_proxy<Y> &py)
417{
418    X &x = px.back_cast();
419    sc_lv_base a(x.length());
420    a = py.back_cast();
421    return b_or_assign_(x, a);
422}
423
424#define DEFN_BITWISE_OR_ASN_OP_T(tp) \
425template <class X> \
426inline X & \
427sc_proxy<X>::operator |= (tp b) \
428{ \
429    X &x = back_cast(); \
430    sc_lv_base a(x.length()); \
431    a = b; \
432    return b_or_assign_(x, a); \
433}
434
435DEFN_BITWISE_OR_ASN_OP_T(const char *)
436DEFN_BITWISE_OR_ASN_OP_T(const bool *)
437DEFN_BITWISE_OR_ASN_OP_T(const sc_logic *)
438DEFN_BITWISE_OR_ASN_OP_T(const sc_unsigned &)
439DEFN_BITWISE_OR_ASN_OP_T(const sc_signed &)
440DEFN_BITWISE_OR_ASN_OP_T(unsigned long)
441DEFN_BITWISE_OR_ASN_OP_T(long)
442DEFN_BITWISE_OR_ASN_OP_T(uint64)
443DEFN_BITWISE_OR_ASN_OP_T(int64)
444
445#undef DEFN_BITWISE_OR_ASN_OP_T
446
447template <class X, class Y>
448inline const sc_lv_base
449operator | (const sc_proxy<X> &px, const sc_proxy<Y> &py)
450{
451    sc_lv_base a(px.back_cast());
452    return (a |= py.back_cast());
453}
454
455#define DEFN_BITWISE_OR_OP_T_A(tp) \
456template <class X> \
457inline const sc_lv_base \
458sc_proxy<X>::operator | (tp b) const \
459{ \
460    sc_lv_base a(back_cast()); \
461    return (a |= b); \
462}
463
464DEFN_BITWISE_OR_OP_T_A(const char *)
465DEFN_BITWISE_OR_OP_T_A(const bool *)
466DEFN_BITWISE_OR_OP_T_A(const sc_logic *)
467DEFN_BITWISE_OR_OP_T_A(const sc_unsigned &)
468DEFN_BITWISE_OR_OP_T_A(const sc_signed &)
469DEFN_BITWISE_OR_OP_T_A(const sc_uint_base &)
470DEFN_BITWISE_OR_OP_T_A(const sc_int_base &)
471DEFN_BITWISE_OR_OP_T_A(unsigned long)
472DEFN_BITWISE_OR_OP_T_A(long)
473DEFN_BITWISE_OR_OP_T_A(unsigned int)
474DEFN_BITWISE_OR_OP_T_A(int)
475DEFN_BITWISE_OR_OP_T_A(uint64)
476DEFN_BITWISE_OR_OP_T_A(int64)
477
478#undef DEFN_BITWISE_OR_OP_T_A
479
480#define DEFN_BITWISE_OR_OP_T_B(tp) \
481template <class X> \
482inline const sc_lv_base \
483operator | (tp b, const sc_proxy<X> &px) \
484{ \
485    return (px | b); \
486}
487
488DEFN_BITWISE_OR_OP_T_B(const char *)
489DEFN_BITWISE_OR_OP_T_B(const bool *)
490DEFN_BITWISE_OR_OP_T_B(const sc_logic *)
491DEFN_BITWISE_OR_OP_T_B(const sc_unsigned &)
492DEFN_BITWISE_OR_OP_T_B(const sc_signed &)
493DEFN_BITWISE_OR_OP_T_B(const sc_uint_base &)
494DEFN_BITWISE_OR_OP_T_B(const sc_int_base &)
495DEFN_BITWISE_OR_OP_T_B(unsigned long)
496DEFN_BITWISE_OR_OP_T_B(long)
497DEFN_BITWISE_OR_OP_T_B(unsigned int)
498DEFN_BITWISE_OR_OP_T_B(int)
499DEFN_BITWISE_OR_OP_T_B(uint64)
500DEFN_BITWISE_OR_OP_T_B(int64)
501
502#undef DEFN_BITWISE_OR_OP_T_B
503
504// bitwise xor
505template <class X, class Y>
506inline X &
507operator ^= (sc_proxy<X> &px, const sc_proxy<Y> &py)
508{
509    X &x = px.back_cast();
510    sc_lv_base a(x.length());
511    a = py.back_cast();
512    return b_xor_assign_(x, a);
513}
514
515#define DEFN_BITWISE_XOR_ASN_OP_T(tp) \
516template <class X> \
517inline X & \
518sc_proxy<X>::operator ^= (tp b) \
519{ \
520    X &x = back_cast(); \
521    sc_lv_base a(x.length()); \
522    a = b; \
523    return b_xor_assign_(x, a); \
524}
525
526DEFN_BITWISE_XOR_ASN_OP_T(const char *)
527DEFN_BITWISE_XOR_ASN_OP_T(const bool *)
528DEFN_BITWISE_XOR_ASN_OP_T(const sc_logic *)
529DEFN_BITWISE_XOR_ASN_OP_T(const sc_unsigned &)
530DEFN_BITWISE_XOR_ASN_OP_T(const sc_signed &)
531DEFN_BITWISE_XOR_ASN_OP_T(unsigned long)
532DEFN_BITWISE_XOR_ASN_OP_T(long)
533DEFN_BITWISE_XOR_ASN_OP_T(uint64)
534DEFN_BITWISE_XOR_ASN_OP_T(int64)
535
536#undef DEFN_BITWISE_XOR_ASN_OP_T
537
538template <class X, class Y>
539inline const sc_lv_base
540operator ^ (const sc_proxy<X> &px, const sc_proxy<Y> &py)
541{
542    sc_lv_base a(px.back_cast());
543    return (a ^= py.back_cast());
544}
545
546#define DEFN_BITWISE_XOR_OP_T_A(tp) \
547template <class X> \
548inline const sc_lv_base \
549sc_proxy<X>::operator ^ (tp b) const \
550{ \
551    sc_lv_base a(back_cast()); \
552    return (a ^= b); \
553}
554
555DEFN_BITWISE_XOR_OP_T_A(const char *)
556DEFN_BITWISE_XOR_OP_T_A(const bool *)
557DEFN_BITWISE_XOR_OP_T_A(const sc_logic *)
558DEFN_BITWISE_XOR_OP_T_A(const sc_unsigned &)
559DEFN_BITWISE_XOR_OP_T_A(const sc_signed &)
560DEFN_BITWISE_XOR_OP_T_A(const sc_uint_base &)
561DEFN_BITWISE_XOR_OP_T_A(const sc_int_base &)
562DEFN_BITWISE_XOR_OP_T_A(unsigned long)
563DEFN_BITWISE_XOR_OP_T_A(long)
564DEFN_BITWISE_XOR_OP_T_A(unsigned int)
565DEFN_BITWISE_XOR_OP_T_A(int)
566DEFN_BITWISE_XOR_OP_T_A(uint64)
567DEFN_BITWISE_XOR_OP_T_A(int64)
568
569#undef DEFN_BITWISE_XOR_OP_T_A
570
571#define DEFN_BITWISE_XOR_OP_T_B(tp) \
572template <class X> \
573inline const sc_lv_base \
574operator ^ (tp b, const sc_proxy<X> &px) \
575{ \
576    return (px ^ b); \
577}
578
579DEFN_BITWISE_XOR_OP_T_B(const char *)
580DEFN_BITWISE_XOR_OP_T_B(const bool *)
581DEFN_BITWISE_XOR_OP_T_B(const sc_logic *)
582DEFN_BITWISE_XOR_OP_T_B(const sc_unsigned &)
583DEFN_BITWISE_XOR_OP_T_B(const sc_signed &)
584DEFN_BITWISE_XOR_OP_T_B(const sc_uint_base &)
585DEFN_BITWISE_XOR_OP_T_B(const sc_int_base &)
586DEFN_BITWISE_XOR_OP_T_B(unsigned long)
587DEFN_BITWISE_XOR_OP_T_B(long)
588DEFN_BITWISE_XOR_OP_T_B(unsigned int)
589DEFN_BITWISE_XOR_OP_T_B(int)
590DEFN_BITWISE_XOR_OP_T_B(uint64)
591DEFN_BITWISE_XOR_OP_T_B(int64)
592
593#undef DEFN_BITWISE_XOR_OP_T_B
594
595// bitwise left shift
596template <class X>
597inline const sc_lv_base
598sc_proxy<X>::operator << (int n) const
599{
600    sc_lv_base a(back_cast().length() + n);
601    a = back_cast();
602    return (a <<= n);
603}
604
605// bitwise right shift
606template <class X>
607inline const sc_lv_base
608sc_proxy<X>::operator >> (int n) const
609{
610    sc_lv_base a(back_cast());
611    return (a >>= n);
612}
613
614// bitwise left rotate
615template <class X>
616inline X &
617sc_proxy<X>::lrotate(int n)
618{
619    X &x = back_cast();
620    if (n < 0) {
621        sc_proxy_out_of_bounds("left rotate operation is only allowed with "
622                               "positive rotate values, rotate value = ", n);
623        return x;
624    }
625    int len = x.length();
626    n %= len;
627    // x = (x << n) | (x >> (len - n));
628    sc_lv_base a(x << n);
629    sc_lv_base b(x >> (len - n));
630    int sz = x.size();
631    for (int i = 0; i < sz; ++i) {
632        x.set_word(i, a.get_word(i) | b.get_word(i));
633        x.set_cword(i, a.get_cword(i) | b.get_cword(i));
634    }
635    x.clean_tail();
636    return x;
637}
638
639template <class X>
640inline const sc_lv_base
641lrotate(const sc_proxy<X> &x, int n)
642{
643    sc_lv_base a(x.back_cast());
644    return a.lrotate(n);
645}
646
647// bitwise right rotate
648template <class X>
649inline X &
650sc_proxy<X>::rrotate(int n)
651{
652    X &x = back_cast();
653    if (n < 0 ) {
654        sc_proxy_out_of_bounds("right rotate operation is only allowed with "
655                               "positive rotate values, rotate value = ", n);
656        return x;
657    }
658    int len = x.length();
659    n %= len;
660    // x = (x >> n) | (x << (len - n));
661    sc_lv_base a(x >> n);
662    sc_lv_base b(x << (len - n));
663    int sz = x.size();
664    for (int i = 0; i < sz; ++i) {
665        x.set_word(i, a.get_word(i) | b.get_word(i));
666        x.set_cword(i, a.get_cword(i) | b.get_cword(i));
667    }
668    x.clean_tail();
669    return x;
670}
671
672template <class X>
673inline const sc_lv_base
674rrotate(const sc_proxy<X> &x, int n)
675{
676    sc_lv_base a(x.back_cast());
677    return a.rrotate(n);
678}
679
680// bitwise reverse
681template <class X>
682inline const sc_lv_base
683reverse(const sc_proxy<X> &x)
684{
685    sc_lv_base a(x.back_cast());
686    return a.reverse();
687}
688
689// relational operators
690template <class X, class Y>
691inline bool
692operator == (const sc_proxy<X> &px, const sc_proxy<Y> &py)
693{
694    const X &x = px.back_cast();
695    const Y &y = py.back_cast();
696    int x_len = x.length();
697    int y_len = y.length();
698    if (x_len != y_len) {
699        return false;
700    }
701    int sz = x.size();
702    for (int i = 0; i < sz; ++i) {
703        if (x.get_word(i) != y.get_word(i) ||
704            x.get_cword(i) != y.get_cword(i)) {
705            return false;
706        }
707    }
708    return true;
709}
710
711#define DEFN_REL_OP_T(tp) \
712template <class X> \
713inline bool \
714sc_proxy<X>::operator == (tp b) const \
715{ \
716    const X &x = back_cast(); \
717    sc_lv_base y(x.length()); \
718    y = b; \
719    return (x == y); \
720}
721
722DEFN_REL_OP_T(const char *)
723DEFN_REL_OP_T(const bool *)
724DEFN_REL_OP_T(const sc_logic *)
725DEFN_REL_OP_T(const sc_unsigned &)
726DEFN_REL_OP_T(const sc_signed &)
727DEFN_REL_OP_T(const sc_uint_base &)
728DEFN_REL_OP_T(const sc_int_base &)
729DEFN_REL_OP_T(unsigned long)
730DEFN_REL_OP_T(long)
731DEFN_REL_OP_T(unsigned int)
732DEFN_REL_OP_T(int)
733DEFN_REL_OP_T(uint64)
734DEFN_REL_OP_T(int64)
735
736#undef DEFN_REL_OP_T
737
738
739// ----------------------------------------------------------------------------
740//  CLASS TEMPLATE : sc_bitref_r<X>
741//
742//  Proxy class for sc_proxy bit selection (r-value only).
743// ----------------------------------------------------------------------------
744
745// r-value concatenation operators and functions
746
747template <class T>
748inline sc_concref_r<sc_bitref_r<T>, sc_lv_base>
749operator , (sc_bitref_r<T> a, const char *b)
750{
751    return sc_concref_r<sc_bitref_r<T>, sc_lv_base>(
752            *a.clone(), *new sc_lv_base(b), 3);
753}
754
755template <class T>
756inline sc_concref_r<sc_lv_base, sc_bitref_r<T> >
757operator , (const char *a, sc_bitref_r<T> b)
758{
759    return sc_concref_r<sc_lv_base, sc_bitref_r<T> >(
760            *new sc_lv_base(a), *b.clone(), 3);
761}
762
763template <class T>
764inline sc_concref_r<sc_bitref_r<T>, sc_lv_base>
765operator , (sc_bitref_r<T> a, const sc_logic &b)
766{
767    return sc_concref_r<sc_bitref_r<T>, sc_lv_base>(
768            *a.clone(), *new sc_lv_base(b, 1), 3);
769}
770
771template <class T>
772inline sc_concref_r<sc_lv_base, sc_bitref_r<T> >
773operator , (const sc_logic &a, sc_bitref_r<T> b)
774{
775    return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
776            *new sc_lv_base(a, 1), *b.clone(), 3);
777}
778
779template <class T>
780inline sc_concref_r<sc_bitref_r<T>, sc_bv_base>
781operator , (sc_bitref_r<T> a, bool b)
782{
783    return sc_concref_r<sc_bitref_r<T>, sc_bv_base>(
784            *a.clone(), *new sc_bv_base(b, 1), 3);
785}
786
787template <class T>
788inline sc_concref_r<sc_bv_base, sc_bitref_r<T> >
789operator , (bool a, sc_bitref_r<T> b)
790{
791    return sc_concref_r<sc_bv_base, sc_bitref_r<T> >(
792            *new sc_bv_base(a, 1), *b.clone(), 3);
793}
794
795template <class T>
796inline sc_concref_r<sc_bitref_r<T>, sc_lv_base>
797concat(sc_bitref_r<T> a, const char *b)
798{
799    return sc_concref_r<sc_bitref_r<T>, sc_lv_base>(
800            *a.clone(), *new sc_lv_base(b), 3);
801}
802
803template <class T>
804inline sc_concref_r<sc_lv_base, sc_bitref_r<T> >
805concat(const char *a, sc_bitref_r<T> b)
806{
807    return sc_concref_r<sc_lv_base, sc_bitref_r<T> >(
808            *new sc_lv_base(a), *b.clone(), 3);
809}
810
811template <class T>
812inline sc_concref_r<sc_bitref_r<T>, sc_lv_base>
813concat(sc_bitref_r<T> a, const sc_logic &b)
814{
815    return sc_concref_r<sc_bitref_r<T>, sc_lv_base>(
816            *a.clone(), *new sc_lv_base(b, 1), 3);
817}
818
819template <class T>
820inline sc_concref_r<sc_lv_base, sc_bitref_r<T> >
821concat(const sc_logic &a, sc_bitref_r<T> b)
822{
823    return sc_concref_r<sc_lv_base, sc_bitref_r<T> >(
824            *new sc_lv_base(a, 1), *b.clone(), 3);
825}
826
827template <class T>
828inline sc_concref_r<sc_bitref_r<T>, sc_bv_base>
829concat(sc_bitref_r<T> a, bool b)
830{
831    return sc_concref_r<sc_bitref_r<T>, sc_bv_base>(
832            *a.clone(), *new sc_bv_base(b, 1), 3);
833}
834
835template <class T>
836inline sc_concref_r<sc_bv_base, sc_bitref_r<T> >
837concat(bool a, sc_bitref_r<T> b)
838{
839    return sc_concref_r<sc_bv_base, sc_bitref_r<T> >(
840            *new sc_bv_base(a, 1), *b.clone(), 3);
841}
842
843
844template <class T>
845inline sc_concref_r<sc_bitref_r<T>, sc_lv_base>
846operator , (sc_bitref<T> a, const char *b)
847{
848    return sc_concref_r<sc_bitref_r<T>, sc_lv_base>(
849            *a.clone(), *new sc_lv_base(b), 3);
850}
851
852template <class T>
853inline sc_concref_r<sc_lv_base, sc_bitref_r<T> >
854operator , (const char *a, sc_bitref<T> b)
855{
856    return sc_concref_r<sc_lv_base, sc_bitref_r<T> >(
857            *new sc_lv_base(a), *b.clone(), 3);
858}
859
860template <class T>
861inline sc_concref_r<sc_bitref_r<T>, sc_lv_base>
862operator , (sc_bitref<T> a, const sc_logic &b)
863{
864    return sc_concref_r<sc_bitref_r<T>, sc_lv_base>(
865            *a.clone(), *new sc_lv_base(b, 1), 3);
866}
867
868template <class T>
869inline sc_concref_r<sc_lv_base, sc_bitref_r<T> >
870operator , (const sc_logic &a, sc_bitref<T> b)
871{
872    return sc_concref_r<sc_lv_base, sc_bitref_r<T> >(
873            *new sc_lv_base(a, 1), *b.clone(), 3);
874}
875
876template <class T>
877inline sc_concref_r<sc_bitref_r<T>, sc_bv_base>
878operator , (sc_bitref<T> a, bool b)
879{
880    return sc_concref_r<sc_bitref_r<T>, sc_bv_base>(
881            *a.clone(), *new sc_bv_base(b, 1), 3);
882}
883
884template <class T>
885inline sc_concref_r<sc_bv_base, sc_bitref_r<T> >
886operator , (bool a, sc_bitref<T> b)
887{
888    return sc_concref_r<sc_bv_base, sc_bitref_r<T> > (
889            *new sc_bv_base(a, 1), *b.clone(), 3);
890}
891
892template <class T>
893inline sc_concref_r<sc_bitref_r<T>, sc_lv_base>
894concat(sc_bitref<T> a, const char *b)
895{
896    return sc_concref_r<sc_bitref_r<T>, sc_lv_base>(
897            *a.clone(), *new sc_lv_base(b), 3);
898}
899
900template <class T>
901inline sc_concref_r<sc_lv_base, sc_bitref_r<T> >
902concat(const char *a, sc_bitref<T> b)
903{
904    return sc_concref_r<sc_lv_base, sc_bitref_r<T> >(
905            *new sc_lv_base(a), *b.clone(), 3);
906}
907
908template <class T>
909inline sc_concref_r<sc_bitref_r<T>, sc_lv_base>
910concat(sc_bitref<T> a, const sc_logic &b)
911{
912    return sc_concref_r<sc_bitref_r<T>, sc_lv_base>(
913            *a.clone(), *new sc_lv_base(b, 1), 3);
914}
915
916template <class T>
917inline sc_concref_r<sc_lv_base, sc_bitref_r<T> >
918concat(const sc_logic &a, sc_bitref<T> b)
919{
920    return sc_concref_r<sc_lv_base, sc_bitref_r<T> >(
921            *new sc_lv_base(a, 1), *b.clone(), 3);
922}
923
924template <class T>
925inline sc_concref_r<sc_bitref_r<T>, sc_bv_base>
926concat(sc_bitref<T> a, bool b)
927{
928    return sc_concref_r<sc_bitref_r<T>, sc_bv_base>(
929            *a.clone(), *new sc_bv_base(b, 1), 3);
930}
931
932template <class T>
933inline sc_concref_r<sc_bv_base, sc_bitref_r<T> >
934concat(bool a, sc_bitref<T> b)
935{
936    return sc_concref_r<sc_bv_base, sc_bitref_r<T> >(
937            *new sc_bv_base(a, 1), *b.clone(), 3);
938}
939
940
941// ----------------------------------------------------------------------------
942//  CLASS TEMPLATE : sc_subref_r<X>
943//
944//  Proxy class for sc_proxy part selection (r-value only).
945// ----------------------------------------------------------------------------
946
947// r-value concatenation operators and functions
948template <class T>
949inline sc_concref_r<sc_subref_r<T>, sc_lv_base>
950operator , (sc_subref_r<T> a, const char *b)
951{
952    return sc_concref_r<sc_subref_r<T>, sc_lv_base>(
953            *a.clone(), *new sc_lv_base(b), 3);
954}
955
956template <class T>
957inline sc_concref_r<sc_lv_base, sc_subref_r<T> >
958operator , (const char *a, sc_subref_r<T> b)
959{
960    return sc_concref_r<sc_lv_base, sc_subref_r<T> >(
961            *new sc_lv_base(a), *b.clone(), 3);
962}
963
964template <class T>
965inline sc_concref_r<sc_subref_r<T>, sc_lv_base>
966operator , (sc_subref_r<T> a, const sc_logic &b)
967{
968    return sc_concref_r<sc_subref_r<T>, sc_lv_base>(
969            *a.clone(), *new sc_lv_base(b, 1), 3);
970}
971
972template <class T>
973inline sc_concref_r<sc_lv_base, sc_subref_r<T> >
974operator , (const sc_logic &a, sc_subref_r<T> b)
975{
976    return sc_concref_r<sc_lv_base, sc_subref_r<T> >(
977            *new sc_lv_base(a, 1), *b.clone(), 3);
978}
979
980template <class T>
981inline sc_concref_r<sc_subref_r<T>, sc_bv_base>
982operator , (sc_subref_r<T> a, bool b)
983{
984    return sc_concref_r<sc_subref_r<T>, sc_bv_base>(
985            *a.clone(), *new sc_bv_base(b, 1), 3);
986}
987
988template <class T>
989inline sc_concref_r<sc_bv_base, sc_subref_r<T> >
990operator , (bool a, sc_subref_r<T> b)
991{
992    return sc_concref_r<sc_bv_base, sc_subref_r<T> >(
993            *new sc_bv_base(a, 1), *b.clone(), 3);
994}
995
996template <class T>
997inline sc_concref_r<sc_subref_r<T>, sc_lv_base>
998concat(sc_subref_r<T> a, const char *b)
999{
1000    return sc_concref_r<sc_subref_r<T>, sc_lv_base>(
1001            *a.clone(), *new sc_lv_base(b), 3);
1002}
1003
1004template <class T>
1005inline sc_concref_r<sc_lv_base, sc_subref_r<T> >
1006concat(const char *a, sc_subref_r<T> b)
1007{
1008    return sc_concref_r<sc_lv_base, sc_subref_r<T> >(
1009            *new sc_lv_base(a), *b.clone(), 3);
1010}
1011
1012template <class T>
1013inline sc_concref_r<sc_subref_r<T>, sc_lv_base>
1014concat(sc_subref_r<T> a, const sc_logic &b)
1015{
1016    return sc_concref_r<sc_subref_r<T>, sc_lv_base>(
1017            *a.clone(), *new sc_lv_base(b, 1), 3);
1018}
1019
1020template <class T>
1021inline sc_concref_r<sc_lv_base, sc_subref_r<T> >
1022concat(const sc_logic &a, sc_subref_r<T> b)
1023{
1024    return sc_concref_r<sc_lv_base, sc_subref_r<T> >(
1025            *new sc_lv_base(a, 1), *b.clone(), 3);
1026}
1027
1028template <class T>
1029inline sc_concref_r<sc_subref_r<T>, sc_bv_base>
1030concat(sc_subref_r<T> a, bool b)
1031{
1032    return sc_concref_r<sc_subref_r<T>, sc_bv_base>(
1033            *a.clone(), *new sc_bv_base(b, 1), 3);
1034}
1035
1036template <class T>
1037inline sc_concref_r<sc_bv_base, sc_subref_r<T> >
1038concat(bool a, sc_subref_r<T> b)
1039{
1040    return sc_concref_r<sc_bv_base, sc_subref_r<T> >(
1041            *new sc_bv_base(a, 1), *b.clone(), 3);
1042}
1043
1044
1045template <class T>
1046inline sc_concref_r<sc_subref_r<T>, sc_lv_base>
1047operator , (sc_subref<T> a, const char *b)
1048{
1049    return sc_concref_r<sc_subref_r<T>, sc_lv_base>(
1050            *a.clone(), *new sc_lv_base(b), 3);
1051}
1052
1053template <class T>
1054inline sc_concref_r<sc_lv_base, sc_subref_r<T> >
1055operator , (const char *a, sc_subref<T> b)
1056{
1057    return sc_concref_r<sc_lv_base, sc_subref_r<T> >(
1058            *new sc_lv_base(a), *b.clone(), 3);
1059}
1060
1061template <class T>
1062inline sc_concref_r<sc_subref_r<T>, sc_lv_base>
1063operator , (sc_subref<T> a, const sc_logic &b)
1064{
1065    return sc_concref_r<sc_subref_r<T>, sc_lv_base>(
1066            *a.clone(), *new sc_lv_base(b, 1), 3);
1067}
1068
1069template <class T>
1070inline sc_concref_r<sc_lv_base, sc_subref_r<T> >
1071operator , (const sc_logic &a, sc_subref<T> b)
1072{
1073    return sc_concref_r<sc_lv_base, sc_subref_r<T> >(
1074            *new sc_lv_base(a, 1), *b.clone(), 3);
1075}
1076
1077template <class T>
1078inline sc_concref_r<sc_subref_r<T>, sc_bv_base>
1079operator , (sc_subref<T> a, bool b)
1080{
1081    return sc_concref_r<sc_subref_r<T>, sc_bv_base>(
1082            *a.clone(), *new sc_bv_base(b, 1), 3);
1083}
1084
1085template <class T>
1086inline sc_concref_r<sc_bv_base, sc_subref_r<T> >
1087operator , (bool a, sc_subref<T> b)
1088{
1089    return sc_concref_r<sc_bv_base, sc_subref_r<T> >(
1090            *new sc_bv_base(a, 1), *b.clone(), 3);
1091}
1092
1093
1094template <class T>
1095inline sc_concref_r<sc_subref_r<T>, sc_lv_base>
1096concat(sc_subref<T> a, const char *b)
1097{
1098    return sc_concref_r<sc_subref_r<T>, sc_lv_base>(
1099            *a.clone(), *new sc_lv_base(b), 3);
1100}
1101
1102template <class T>
1103inline sc_concref_r<sc_lv_base, sc_subref_r<T> >
1104concat(const char *a, sc_subref<T> b)
1105{
1106    return sc_concref_r<sc_lv_base, sc_subref_r<T> >(
1107            *new sc_lv_base(a), *b.clone(), 3);
1108}
1109
1110template <class T>
1111inline sc_concref_r<sc_subref_r<T>, sc_lv_base>
1112concat(sc_subref<T> a, const sc_logic &b)
1113{
1114    return sc_concref_r<sc_subref_r<T>, sc_lv_base>(
1115            *a.clone(), *new sc_lv_base(b, 1), 3);
1116}
1117
1118template <class T>
1119inline sc_concref_r<sc_lv_base, sc_subref_r<T> >
1120concat(const sc_logic &a, sc_subref<T> b)
1121{
1122    return sc_concref_r<sc_lv_base, sc_subref_r<T> >(
1123            *new sc_lv_base(a, 1), *b.clone(), 3);
1124}
1125
1126template <class T>
1127inline sc_concref_r<sc_subref_r<T>, sc_bv_base>
1128concat(sc_subref<T> a, bool b)
1129{
1130    return sc_concref_r<sc_subref_r<T>, sc_bv_base>(
1131            *a.clone(), *new sc_bv_base(b, 1), 3);
1132}
1133
1134template <class T>
1135inline sc_concref_r<sc_bv_base, sc_subref_r<T> >
1136concat(bool a, sc_subref<T> b)
1137{
1138    return sc_concref_r<sc_bv_base, sc_subref_r<T> >(
1139            *new sc_bv_base(a, 1), *b.clone(), 3);
1140}
1141
1142
1143// ----------------------------------------------------------------------------
1144//  CLASS TEMPLATE : sc_subref<X>
1145//
1146//  Proxy class for sc_proxy part selection (r-value and l-value).
1147// ----------------------------------------------------------------------------
1148
1149template <class X>
1150inline sc_subref<X> &
1151sc_subref<X>::operator = (const sc_subref_r<X> &b)
1152{
1153    sc_lv_base t(b); // (partial) self assignment protection
1154    int len = sc_min(this->length(), t.length());
1155    if (!this->reversed()) {
1156        for (int i = len - 1; i >= 0; --i) {
1157            this->m_obj.set_bit(this->m_lo + i, t[i].value());
1158        }
1159    } else {
1160        for (int i = len - 1; i >= 0; --i) {
1161            this->m_obj.set_bit(this->m_lo - i, t[i].value());
1162        }
1163    }
1164    return *this;
1165}
1166
1167template <class X>
1168inline sc_subref<X> &
1169sc_subref<X>::operator = (const sc_subref<X> &b)
1170{
1171    sc_lv_base t(b); // (partial) self assignment protection
1172    int len = sc_min(this->length(), t.length());
1173    if (!this->reversed()) {
1174        for (int i = len - 1; i >= 0; --i) {
1175            this->m_obj.set_bit(this->m_lo + i, t[i].value());
1176        }
1177    } else {
1178        for (int i = len - 1; i >= 0; --i) {
1179            this->m_obj.set_bit(this->m_lo - i, t[i].value());
1180        }
1181    }
1182    return *this;
1183}
1184
1185
1186// ----------------------------------------------------------------------------
1187//  CLASS TEMPLATE : sc_concref_r<X,Y>
1188//
1189//  Proxy class for sc_proxy concatenation (r-value only).
1190// ----------------------------------------------------------------------------
1191
1192// r-value concatenation operators and functions
1193
1194template <class T1, class T2>
1195inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>
1196operator , (sc_concref_r<T1, T2> a, const char *b)
1197{
1198    return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>(
1199            *a.clone(), *new sc_lv_base(b), 3);
1200}
1201
1202template <class T1, class T2>
1203inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >
1204operator , (const char *a, sc_concref_r<T1, T2> b)
1205{
1206    return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >(
1207            *new sc_lv_base(a), *b.clone(), 3);
1208}
1209
1210template <class T1, class T2>
1211inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>
1212operator , (sc_concref_r<T1, T2> a, const sc_logic &b)
1213{
1214    return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>(
1215            *a.clone(), *new sc_lv_base(b, 1), 3);
1216}
1217
1218template <class T1, class T2>
1219inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >
1220operator , (const sc_logic &a, sc_concref_r<T1, T2> b)
1221{
1222    return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >(
1223            *new sc_lv_base(a, 1), *b.clone(), 3);
1224}
1225
1226template <class T1, class T2>
1227inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>
1228operator , (sc_concref_r<T1, T2> a, bool b)
1229{
1230    return sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>(
1231            *a.clone(), *new sc_bv_base(b, 1), 3);
1232}
1233
1234template <class T1, class T2>
1235inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >
1236operator , (bool a, sc_concref_r<T1, T2> b)
1237{
1238    return sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >(
1239            *new sc_bv_base(a, 1), *b.clone(), 3);
1240}
1241
1242template <class T1, class T2>
1243inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>
1244concat(sc_concref_r<T1, T2> a, const char *b)
1245{
1246    return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>(
1247            *a.clone(), *new sc_lv_base(b), 3);
1248}
1249
1250template <class T1, class T2>
1251inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >
1252concat(const char *a, sc_concref_r<T1, T2> b)
1253{
1254    return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >(
1255            *new sc_lv_base(a), *b.clone(), 3);
1256}
1257
1258template <class T1, class T2>
1259inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>
1260concat(sc_concref_r<T1, T2> a, const sc_logic &b)
1261{
1262    return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>(
1263            *a.clone(), *new sc_lv_base(b, 1), 3);
1264}
1265
1266template <class T1, class T2>
1267inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >
1268concat(const sc_logic &a, sc_concref_r<T1, T2> b)
1269{
1270    return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >(
1271            *new sc_lv_base(a, 1), *b.clone(), 3);
1272}
1273
1274template <class T1, class T2>
1275inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>
1276concat(sc_concref_r<T1, T2> a, bool b)
1277{
1278    return sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>(
1279            *a.clone(), *new sc_bv_base(b, 1), 3);
1280}
1281
1282template <class T1, class T2>
1283inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >
1284concat(bool a, sc_concref_r<T1, T2> b)
1285{
1286    return sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >(
1287            *new sc_bv_base(a, 1), *b.clone(), 3);
1288}
1289
1290
1291template <class T1, class T2>
1292inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>
1293operator , (sc_concref<T1, T2> a, const char *b)
1294{
1295    return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>(
1296            *a.clone(), *new sc_lv_base(b), 3);
1297}
1298
1299template <class T1, class T2>
1300inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >
1301operator , (const char *a, sc_concref<T1, T2> b)
1302{
1303    return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >(
1304            *new sc_lv_base(a), *b.clone(), 3);
1305}
1306
1307template <class T1, class T2>
1308inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>
1309operator , (sc_concref<T1, T2> a, const sc_logic &b)
1310{
1311    return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>(
1312            *a.clone(), *new sc_lv_base(b, 1), 3);
1313}
1314
1315template <class T1, class T2>
1316inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >
1317operator , (const sc_logic &a, sc_concref<T1, T2> b)
1318{
1319    return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >(
1320            *new sc_lv_base(a, 1), *b.clone(), 3);
1321}
1322
1323template <class T1, class T2>
1324inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>
1325operator , (sc_concref<T1, T2> a, bool b)
1326{
1327    return sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>(
1328            *a.clone(), *new sc_bv_base(b, 1), 3);
1329}
1330
1331template <class T1, class T2>
1332inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >
1333operator , (bool a, sc_concref<T1, T2> b)
1334{
1335    return sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >(
1336            *new sc_bv_base(a, 1), *b.clone(), 3);
1337}
1338
1339template <class T1, class T2>
1340inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>
1341concat(sc_concref<T1, T2> a, const char *b)
1342{
1343    return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>(
1344            *a.clone(), *new sc_lv_base(b), 3);
1345}
1346
1347template <class T1, class T2>
1348inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >
1349concat(const char *a, sc_concref<T1, T2> b)
1350{
1351    return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >(
1352            *new sc_lv_base(a), *b.clone(), 3);
1353}
1354
1355template <class T1, class T2>
1356inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>
1357concat(sc_concref<T1, T2> a, const sc_logic &b)
1358{
1359    return sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base>(
1360            *a.clone(), *new sc_lv_base(b, 1), 3);
1361}
1362
1363template <class T1, class T2>
1364inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >
1365concat(const sc_logic &a, sc_concref<T1, T2> b)
1366{
1367    return sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> >(
1368            *new sc_lv_base(a, 1), *b.clone(), 3);
1369}
1370
1371template <class T1, class T2>
1372inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>
1373concat(sc_concref<T1, T2> a, bool b)
1374{
1375    return sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base>(
1376            *a.clone(), *new sc_bv_base(b, 1), 3);
1377}
1378
1379template <class T1, class T2>
1380inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >
1381concat(bool a, sc_concref<T1, T2> b)
1382{
1383    return sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> >(
1384            *new sc_bv_base(a, 1), *b.clone(), 3);
1385}
1386
1387
1388// ----------------------------------------------------------------------------
1389//  CLASS TEMPLATE : sc_proxy<T>
1390//
1391//  Base class template for bit/logic vector classes.
1392//  (Barton/Nackmann implementation)
1393// ----------------------------------------------------------------------------
1394
1395// r-value concatenation operators and functions
1396
1397template <class T>
1398inline sc_concref_r<T, sc_lv_base>
1399operator , (const sc_proxy<T> &a, const char *b)
1400{
1401    return sc_concref_r<T, sc_lv_base>(a.back_cast(), *new sc_lv_base(b), 2);
1402}
1403
1404template <class T>
1405inline sc_concref_r<sc_lv_base, T>
1406operator , (const char *a, const sc_proxy<T> &b)
1407{
1408    return sc_concref_r<sc_lv_base, T>(*new sc_lv_base(a), b.back_cast(), 1);
1409}
1410
1411template <class T>
1412inline sc_concref_r<T, sc_lv_base>
1413operator , (const sc_proxy<T> &a, const sc_logic &b)
1414{
1415    return sc_concref_r<T, sc_lv_base>(
1416            a.back_cast(), *new sc_lv_base(b, 1), 2);
1417}
1418
1419template <class T>
1420inline sc_concref_r<sc_lv_base, T>
1421operator , (const sc_logic &a, const sc_proxy<T> &b)
1422{
1423    return sc_concref_r<sc_lv_base, T>(
1424            *new sc_lv_base(a, 1), b.back_cast(), 1);
1425}
1426
1427template <class T>
1428inline sc_concref_r<T, sc_bv_base>
1429operator , (const sc_proxy<T> &a, bool b)
1430{
1431    return sc_concref_r<T, sc_bv_base>(
1432            a.back_cast(), *new sc_bv_base(b, 1), 2);
1433}
1434
1435template <class T>
1436inline sc_concref_r<sc_bv_base, T>
1437operator , (bool a, const sc_proxy<T> &b)
1438{
1439    return sc_concref_r<sc_bv_base, T>(
1440            *new sc_bv_base(a, 1), b.back_cast(), 1);
1441}
1442
1443template <class T>
1444inline sc_concref_r<T, sc_lv_base>
1445concat(const sc_proxy<T> &a, const char *b)
1446{
1447    return sc_concref_r<T, sc_lv_base>(a.back_cast(), *new sc_lv_base(b), 2);
1448}
1449
1450template <class T>
1451inline sc_concref_r<sc_lv_base, T>
1452concat(const char *a, const sc_proxy<T> &b)
1453{
1454    return sc_concref_r<sc_lv_base, T>(*new sc_lv_base(a), b.back_cast(), 1);
1455}
1456
1457template <class T>
1458inline sc_concref_r<T, sc_lv_base>
1459concat(const sc_proxy<T> &a, const sc_logic &b)
1460{
1461    return sc_concref_r<T, sc_lv_base>(
1462            a.back_cast(), *new sc_lv_base(b, 1), 2);
1463}
1464
1465template <class T>
1466inline sc_concref_r<sc_lv_base, T>
1467concat(const sc_logic &a, const sc_proxy<T> &b)
1468{
1469    return sc_concref_r<sc_lv_base, T>(
1470            *new sc_lv_base(a, 1), b.back_cast(), 1);
1471}
1472
1473template <class T>
1474inline sc_concref_r<T, sc_bv_base>
1475concat(const sc_proxy<T> &a, bool b)
1476{
1477    return sc_concref_r<T, sc_bv_base>(
1478            a.back_cast(), *new sc_bv_base(b, 1), 2);
1479}
1480
1481template <class T>
1482inline sc_concref_r<sc_bv_base, T>
1483concat(bool a, const sc_proxy<T> &b)
1484{
1485    return sc_concref_r<sc_bv_base, T>(
1486            *new sc_bv_base(a, 1), b.back_cast(), 1);
1487}
1488
1489
1490template <class T>
1491inline sc_concref_r<T, sc_lv_base>
1492operator , (sc_proxy<T> &a, const char *b)
1493{
1494    return sc_concref_r<T, sc_lv_base>(a.back_cast(), *new sc_lv_base(b), 2);
1495}
1496
1497template <class T>
1498inline sc_concref_r<sc_lv_base, T>
1499operator , (const char *a, sc_proxy<T> &b)
1500{
1501    return sc_concref_r<sc_lv_base, T>(*new sc_lv_base(a), b.back_cast(), 1);
1502}
1503
1504template <class T>
1505inline sc_concref_r<T, sc_lv_base>
1506operator , (sc_proxy<T> &a, const sc_logic &b)
1507{
1508    return sc_concref_r<T, sc_lv_base>(
1509            a.back_cast(), *new sc_lv_base(b, 1), 2);
1510}
1511
1512template <class T>
1513inline sc_concref_r<sc_lv_base, T>
1514operator , (const sc_logic &a, sc_proxy<T> &b)
1515{
1516    return sc_concref_r<sc_lv_base, T>(
1517            *new sc_lv_base(a, 1), b.back_cast(), 1);
1518}
1519
1520template <class T>
1521inline sc_concref_r<T, sc_bv_base>
1522operator , (sc_proxy<T> &a, bool b)
1523{
1524    return sc_concref_r<T, sc_bv_base>(
1525            a.back_cast(), *new sc_bv_base(b, 1), 2);
1526}
1527
1528template <class T>
1529inline sc_concref_r<sc_bv_base, T>
1530operator , (bool a, sc_proxy<T> &b)
1531{
1532    return sc_concref_r<sc_bv_base, T>(
1533            *new sc_bv_base(a, 1), b.back_cast(), 1);
1534}
1535
1536
1537template <class T>
1538inline sc_concref_r<T, sc_lv_base>
1539concat(sc_proxy<T> &a, const char *b)
1540{
1541    return sc_concref_r<T, sc_lv_base>(a.back_cast(), *new sc_lv_base(b), 2);
1542}
1543
1544template <class T>
1545inline sc_concref_r<sc_lv_base, T>
1546concat(const char *a, sc_proxy<T> &b)
1547{
1548    return sc_concref_r<sc_lv_base, T>(*new sc_lv_base(a), b.back_cast(), 1);
1549}
1550
1551template <class T>
1552inline sc_concref_r<T, sc_lv_base>
1553concat(sc_proxy<T> &a, const sc_logic &b)
1554{
1555    return sc_concref_r<T, sc_lv_base>(
1556            a.back_cast(), *new sc_lv_base(b, 1), 2);
1557}
1558
1559template <class T>
1560inline sc_concref_r<sc_lv_base, T>
1561concat(const sc_logic &a, sc_proxy<T> &b)
1562{
1563    return sc_concref_r<sc_lv_base, T>(
1564            *new sc_lv_base(a, 1), b.back_cast(), 1);
1565}
1566
1567template <class T>
1568inline sc_concref_r<T, sc_bv_base>
1569concat(sc_proxy<T> &a, bool b)
1570{
1571    return sc_concref_r<T, sc_bv_base>(
1572            a.back_cast(), *new sc_bv_base(b, 1), 2);
1573}
1574
1575template <class T>
1576inline sc_concref_r<sc_bv_base, T>
1577concat(bool a, sc_proxy<T> &b)
1578{
1579    return sc_concref_r<sc_bv_base, T>(
1580            *new sc_bv_base(a, 1), b.back_cast(), 1);
1581}
1582
1583// extern template instantiations
1584extern template class sc_proxy<sc_lv_base>;
1585extern template class sc_proxy<sc_bv_base>;
1586
1587} // namespace sc_dt
1588
1589#endif // __SYSTEMC_EXT_DT_BIT_SC_LV_BASE_HH__
1590