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 SC_LV_BASE_H
65#define SC_LV_BASE_H
66
67
68#include "sysc/datatypes/bit/sc_bit_ids.h"
69#include "sysc/datatypes/bit/sc_bv_base.h"
70#include "sysc/datatypes/bit/sc_logic.h"
71#include "sysc/datatypes/int/sc_length_param.h"
72
73
74namespace sc_dt
75{
76
77// classes defined in this module
78class sc_lv_base;
79
80
81// ----------------------------------------------------------------------------
82//  CLASS : sc_lv_base
83//
84//  Arbitrary size logic vector base class.
85// ----------------------------------------------------------------------------
86
87class sc_lv_base
88    : public sc_proxy<sc_lv_base>
89{
90    friend class sc_bv_base;
91
92
93    void init( int length_, const sc_logic& init_value = SC_LOGIC_X );
94
95    void assign_from_string( const std::string& );
96
97public:
98
99    // typedefs
100
101    typedef sc_proxy<sc_lv_base> base_type;
102
103
104    // constructors
105
106    explicit sc_lv_base( int length_ = sc_length_param().len() )
107	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
108	{ init( length_ ); }
109
110    explicit sc_lv_base( const sc_logic& a,
111			 int length_ = sc_length_param().len()  )
112	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
113	{ init( length_, a ); }
114
115    sc_lv_base( const char* a );
116
117    sc_lv_base( const char* a, int length_ );
118
119    template <class X>
120    sc_lv_base( const sc_proxy<X>& a )
121	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
122	{ init( a.back_cast().length() ); base_type::assign_( a ); }
123
124    sc_lv_base( const sc_lv_base& a );
125
126#ifdef SC_DT_DEPRECATED
127
128    explicit sc_lv_base( const sc_unsigned& a )
129	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
130	{ init( a.length() ); base_type::assign_( a ); }
131
132    explicit sc_lv_base( const sc_signed& a )
133	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
134	{ init( a.length() ); base_type::assign_( a ); }
135
136    explicit sc_lv_base( const sc_uint_base& a )
137	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
138	{ init( a.length() ); base_type::assign_( a ); }
139
140    explicit sc_lv_base( const sc_int_base& a )
141	: m_len( 0 ), m_size( 0 ), m_data( 0 ), m_ctrl( 0 )
142	{ init( a.length() ); base_type::assign_( a ); }
143
144#endif
145
146
147    // destructor
148
149    virtual ~sc_lv_base()
150	{ delete [] m_data; }
151
152
153    // assignment operators
154
155    template <class X>
156    sc_lv_base& operator = ( const sc_proxy<X>& a )
157	{ assign_p_( *this, a ); return *this; }
158
159    sc_lv_base& operator = ( const sc_lv_base& a )
160	{ assign_p_( *this, a ); return *this; }
161
162    sc_lv_base& operator = ( const char* a );
163
164    sc_lv_base& operator = ( const bool* a )
165	{ base_type::assign_( a ); return *this; }
166
167    sc_lv_base& operator = ( const sc_logic* a )
168	{ base_type::assign_( a ); return *this; }
169
170    sc_lv_base& operator = ( const sc_unsigned& a )
171	{ base_type::assign_( a ); return *this; }
172
173    sc_lv_base& operator = ( const sc_signed& a )
174	{ base_type::assign_( a ); return *this; }
175
176    sc_lv_base& operator = ( const sc_uint_base& a )
177	{ base_type::assign_( a ); return *this; }
178
179    sc_lv_base& operator = ( const sc_int_base& a )
180	{ base_type::assign_( a ); return *this; }
181
182    sc_lv_base& operator = ( unsigned long a )
183	{ base_type::assign_( a ); return *this; }
184
185    sc_lv_base& operator = ( long a )
186	{ base_type::assign_( a ); return *this; }
187
188    sc_lv_base& operator = ( unsigned int a )
189	{ base_type::assign_( a ); return *this; }
190
191    sc_lv_base& operator = ( int a )
192	{ base_type::assign_( a ); return *this; }
193
194    sc_lv_base& operator = ( uint64 a )
195	{ base_type::assign_( a ); return *this; }
196
197    sc_lv_base& operator = ( int64 a )
198	{ base_type::assign_( a ); return *this; }
199
200
201#if 0
202
203    // bitwise complement
204
205    sc_lv_base& b_not()
206	{ return sc_proxy<sc_lv_base>::b_not(); }
207
208    const sc_lv_base operator ~ () const
209	{ sc_lv_base a( *this ); return a.b_not(); }
210
211
212    // bitwise left shift
213
214    sc_lv_base& operator <<= ( int n )
215	{ return sc_proxy<sc_lv_base>::operator <<= ( n ); }
216
217    const sc_lv_base operator << ( int n ) const
218	{ sc_lv_base a( *this ); return ( a <<= n ); }
219
220
221    // bitwise right shift
222
223    sc_lv_base& operator >>= ( int n )
224	{ return sc_proxy<sc_lv_base>::operator >>= ( n ); }
225
226    const sc_lv_base operator >> ( int n ) const
227	{ sc_lv_base a( *this ); return ( a >>= n ); }
228
229
230    // bitwise left rotate
231
232    sc_lv_base& lrotate( int n )
233	{ return sc_proxy<sc_lv_base>::lrotate( n ); }
234
235
236    // bitwise right rotate
237
238    sc_lv_base& rrotate( int n )
239	{ return sc_proxy<sc_lv_base>::rrotate( n ); }
240
241#endif
242
243
244    // common methods
245
246    int length() const
247	{ return m_len; }
248
249    int size() const
250	{ return m_size; }
251
252    sc_logic_value_t get_bit( int i ) const;
253    void set_bit( int i, sc_logic_value_t value );
254
255    sc_digit get_word( int wi ) const
256	{ return m_data[wi]; }
257
258	// note the test for out of range access here. this is necessary
259	// because of the hair-brained way concatenations are set up.
260	// an extend_sign on a concatenation uses the whole length of
261	// the concatenation to determine how many words to set.
262    void set_word( int wi, sc_digit w )
263	{ assert ( wi < m_size ); m_data[wi] = w; }
264
265
266    sc_digit get_cword( int wi ) const
267	{ return m_ctrl[wi]; }
268
269    void set_cword( int wi, sc_digit w )
270	{ assert ( wi < m_size ); m_ctrl[wi] = w; }
271
272    void clean_tail();
273
274
275    // other methods
276
277    bool is_01() const;
278
279protected:
280
281    int     m_len;   // length in bits
282    int     m_size;  // size of the data array
283    sc_digit* m_data;  // data array
284    sc_digit* m_ctrl;  // dito (control part)
285};
286
287
288// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
289
290#if 0
291
292// bitwise left rotate
293
294inline
295const sc_lv_base
296lrotate( const sc_lv_base& x, int n )
297{
298    sc_lv_base a( x );
299    return a.lrotate( n );
300}
301
302
303// bitwise right rotate
304
305inline
306const sc_lv_base
307rrotate( const sc_lv_base& x, int n )
308{
309    sc_lv_base a( x );
310    return a.rrotate( n );
311}
312
313#endif
314
315
316inline
317sc_logic_value_t
318sc_lv_base::get_bit( int i ) const
319{
320    int wi = i / SC_DIGIT_SIZE;
321    int bi = i % SC_DIGIT_SIZE;
322    return sc_logic_value_t( ((m_data[wi] >> bi) & SC_DIGIT_ONE) |
323			     (((m_ctrl[wi] >> bi) << 1) & SC_DIGIT_TWO) );
324}
325
326inline
327void
328sc_lv_base::set_bit( int i, sc_logic_value_t value )
329{
330    int wi = i / SC_DIGIT_SIZE; // word index
331    int bi = i % SC_DIGIT_SIZE; // bit index
332    sc_digit mask = SC_DIGIT_ONE << bi;
333    m_data[wi] |= mask; // set bit to 1
334    m_ctrl[wi] |= mask; // set bit to 1
335    m_data[wi] &= value << bi | ~mask;
336    m_ctrl[wi] &= value >> 1 << bi | ~mask;
337}
338
339
340inline
341void
342sc_lv_base::clean_tail()
343{
344    int wi = m_size - 1;
345    int bi = m_len % SC_DIGIT_SIZE;
346    sc_digit mask = ~SC_DIGIT_ZERO >> (SC_DIGIT_SIZE - bi);
347	if ( mask )
348	{
349		m_data[wi] &= mask;
350		m_ctrl[wi] &= mask;
351	}
352}
353
354
355// ----------------------------------------------------------------------------
356//  CLASS TEMPLATE : sc_proxy
357//
358//  Base class template for bit/logic vector classes.
359//  (Barton/Nackmann implementation)
360// ----------------------------------------------------------------------------
361
362// bitwise operators and functions
363
364// bitwise complement
365
366template <class X>
367inline
368const sc_lv_base
369sc_proxy<X>::operator ~ () const
370{
371    sc_lv_base a( back_cast() );
372    return a.b_not();
373}
374
375
376// bitwise and
377
378template <class X, class Y>
379inline
380X&
381operator &= ( sc_proxy<X>& px, const sc_proxy<Y>& py )
382{
383    X& x = px.back_cast();
384    sc_lv_base a( x.length() );
385    a = py.back_cast();
386    return b_and_assign_( x, a );
387}
388
389
390#define DEFN_BITWISE_AND_ASN_OP_T(tp)                                         \
391template <class X>                                                            \
392inline                                                                        \
393X&                                                                            \
394sc_proxy<X>::operator &= ( tp b )                                             \
395{                                                                             \
396    X& x = back_cast();                                                       \
397    sc_lv_base a( x.length() );                                               \
398    a = b;                                                                    \
399    return b_and_assign_( x, a );                                             \
400}
401
402DEFN_BITWISE_AND_ASN_OP_T(const char*)
403DEFN_BITWISE_AND_ASN_OP_T(const bool*)
404DEFN_BITWISE_AND_ASN_OP_T(const sc_logic*)
405DEFN_BITWISE_AND_ASN_OP_T(const sc_unsigned&)
406DEFN_BITWISE_AND_ASN_OP_T(const sc_signed&)
407DEFN_BITWISE_AND_ASN_OP_T(unsigned long)
408DEFN_BITWISE_AND_ASN_OP_T(long)
409DEFN_BITWISE_AND_ASN_OP_T(uint64)
410DEFN_BITWISE_AND_ASN_OP_T(int64)
411
412#undef DEFN_BITWISE_AND_ASN_OP_T
413
414
415template <class X, class Y>
416inline
417const sc_lv_base
418operator & ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
419{
420    sc_lv_base a( px.back_cast() );
421    return ( a &= py.back_cast() );
422}
423
424
425#define DEFN_BITWISE_AND_OP_T_A(tp)                                           \
426template <class X>                                                            \
427inline                                                                        \
428const sc_lv_base                                                              \
429sc_proxy<X>::operator & ( tp b ) const                                        \
430{                                                                             \
431    sc_lv_base a( back_cast() );                                              \
432    return ( a &= b );                                                        \
433}
434
435DEFN_BITWISE_AND_OP_T_A(const char*)
436DEFN_BITWISE_AND_OP_T_A(const bool*)
437DEFN_BITWISE_AND_OP_T_A(const sc_logic*)
438DEFN_BITWISE_AND_OP_T_A(const sc_unsigned&)
439DEFN_BITWISE_AND_OP_T_A(const sc_signed&)
440DEFN_BITWISE_AND_OP_T_A(const sc_uint_base&)
441DEFN_BITWISE_AND_OP_T_A(const sc_int_base&)
442DEFN_BITWISE_AND_OP_T_A(unsigned long)
443DEFN_BITWISE_AND_OP_T_A(long)
444DEFN_BITWISE_AND_OP_T_A(unsigned int)
445DEFN_BITWISE_AND_OP_T_A(int)
446DEFN_BITWISE_AND_OP_T_A(uint64)
447DEFN_BITWISE_AND_OP_T_A(int64)
448
449#undef DEFN_BITWISE_AND_OP_T_A
450
451
452#define DEFN_BITWISE_AND_OP_T_B(tp)                                           \
453template <class X>                                                            \
454inline                                                                        \
455const sc_lv_base                                                              \
456operator & ( tp b, const sc_proxy<X>& px )                                    \
457{                                                                             \
458    return ( px & b );                                                        \
459}
460
461DEFN_BITWISE_AND_OP_T_B(const char*)
462DEFN_BITWISE_AND_OP_T_B(const bool*)
463DEFN_BITWISE_AND_OP_T_B(const sc_logic*)
464DEFN_BITWISE_AND_OP_T_B(const sc_unsigned&)
465DEFN_BITWISE_AND_OP_T_B(const sc_signed&)
466DEFN_BITWISE_AND_OP_T_B(const sc_uint_base&)
467DEFN_BITWISE_AND_OP_T_B(const sc_int_base&)
468DEFN_BITWISE_AND_OP_T_B(unsigned long)
469DEFN_BITWISE_AND_OP_T_B(long)
470DEFN_BITWISE_AND_OP_T_B(unsigned int)
471DEFN_BITWISE_AND_OP_T_B(int)
472DEFN_BITWISE_AND_OP_T_B(uint64)
473DEFN_BITWISE_AND_OP_T_B(int64)
474
475#undef DEFN_BITWISE_AND_OP_T_B
476
477
478// bitwise or
479
480template <class X, class Y>
481inline
482X&
483operator |= ( sc_proxy<X>& px, const sc_proxy<Y>& py )
484{
485    X& x = px.back_cast();
486    sc_lv_base a( x.length() );
487    a = py.back_cast();
488    return b_or_assign_( x, a );
489}
490
491
492#define DEFN_BITWISE_OR_ASN_OP_T(tp)                                          \
493template <class X>                                                            \
494inline                                                                        \
495X&                                                                            \
496sc_proxy<X>::operator |= ( tp b )                                             \
497{                                                                             \
498    X& x = back_cast();                                                       \
499    sc_lv_base a( x.length() );                                               \
500    a = b;                                                                    \
501    return b_or_assign_( x, a );                                              \
502}
503
504DEFN_BITWISE_OR_ASN_OP_T(const char*)
505DEFN_BITWISE_OR_ASN_OP_T(const bool*)
506DEFN_BITWISE_OR_ASN_OP_T(const sc_logic*)
507DEFN_BITWISE_OR_ASN_OP_T(const sc_unsigned&)
508DEFN_BITWISE_OR_ASN_OP_T(const sc_signed&)
509DEFN_BITWISE_OR_ASN_OP_T(unsigned long)
510DEFN_BITWISE_OR_ASN_OP_T(long)
511DEFN_BITWISE_OR_ASN_OP_T(uint64)
512DEFN_BITWISE_OR_ASN_OP_T(int64)
513
514#undef DEFN_BITWISE_OR_ASN_OP_T
515
516
517template <class X, class Y>
518inline
519const sc_lv_base
520operator | ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
521{
522    sc_lv_base a( px.back_cast() );
523    return ( a |= py.back_cast() );
524}
525
526
527#define DEFN_BITWISE_OR_OP_T_A(tp)                                            \
528template <class X>                                                            \
529inline                                                                        \
530const sc_lv_base                                                              \
531sc_proxy<X>::operator | ( tp b ) const                                        \
532{                                                                             \
533    sc_lv_base a( back_cast() );                                              \
534    return ( a |= b );                                                        \
535}
536
537DEFN_BITWISE_OR_OP_T_A(const char*)
538DEFN_BITWISE_OR_OP_T_A(const bool*)
539DEFN_BITWISE_OR_OP_T_A(const sc_logic*)
540DEFN_BITWISE_OR_OP_T_A(const sc_unsigned&)
541DEFN_BITWISE_OR_OP_T_A(const sc_signed&)
542DEFN_BITWISE_OR_OP_T_A(const sc_uint_base&)
543DEFN_BITWISE_OR_OP_T_A(const sc_int_base&)
544DEFN_BITWISE_OR_OP_T_A(unsigned long)
545DEFN_BITWISE_OR_OP_T_A(long)
546DEFN_BITWISE_OR_OP_T_A(unsigned int)
547DEFN_BITWISE_OR_OP_T_A(int)
548DEFN_BITWISE_OR_OP_T_A(uint64)
549DEFN_BITWISE_OR_OP_T_A(int64)
550
551#undef DEFN_BITWISE_OR_OP_T_A
552
553
554#define DEFN_BITWISE_OR_OP_T_B(tp)                                           \
555template <class X>                                                            \
556inline                                                                        \
557const sc_lv_base                                                              \
558operator | ( tp b, const sc_proxy<X>& px )                                    \
559{                                                                             \
560    return ( px | b );                                                        \
561}
562
563DEFN_BITWISE_OR_OP_T_B(const char*)
564DEFN_BITWISE_OR_OP_T_B(const bool*)
565DEFN_BITWISE_OR_OP_T_B(const sc_logic*)
566DEFN_BITWISE_OR_OP_T_B(const sc_unsigned&)
567DEFN_BITWISE_OR_OP_T_B(const sc_signed&)
568DEFN_BITWISE_OR_OP_T_B(const sc_uint_base&)
569DEFN_BITWISE_OR_OP_T_B(const sc_int_base&)
570DEFN_BITWISE_OR_OP_T_B(unsigned long)
571DEFN_BITWISE_OR_OP_T_B(long)
572DEFN_BITWISE_OR_OP_T_B(unsigned int)
573DEFN_BITWISE_OR_OP_T_B(int)
574DEFN_BITWISE_OR_OP_T_B(uint64)
575DEFN_BITWISE_OR_OP_T_B(int64)
576
577#undef DEFN_BITWISE_OR_OP_T_B
578
579
580// bitwise xor
581
582template <class X, class Y>
583inline
584X&
585operator ^= ( sc_proxy<X>& px, const sc_proxy<Y>& py )
586{
587    X& x = px.back_cast();
588    sc_lv_base a( x.length() );
589    a = py.back_cast();
590    return b_xor_assign_( x, a );
591}
592
593
594#define DEFN_BITWISE_XOR_ASN_OP_T(tp)                                         \
595template <class X>                                                            \
596inline                                                                        \
597X&                                                                            \
598sc_proxy<X>::operator ^= ( tp b )                                             \
599{                                                                             \
600    X& x = back_cast();                                                       \
601    sc_lv_base a( x.length() );                                               \
602    a = b;                                                                    \
603    return b_xor_assign_( x, a );                                             \
604}
605
606DEFN_BITWISE_XOR_ASN_OP_T(const char*)
607DEFN_BITWISE_XOR_ASN_OP_T(const bool*)
608DEFN_BITWISE_XOR_ASN_OP_T(const sc_logic*)
609DEFN_BITWISE_XOR_ASN_OP_T(const sc_unsigned&)
610DEFN_BITWISE_XOR_ASN_OP_T(const sc_signed&)
611DEFN_BITWISE_XOR_ASN_OP_T(unsigned long)
612DEFN_BITWISE_XOR_ASN_OP_T(long)
613DEFN_BITWISE_XOR_ASN_OP_T(uint64)
614DEFN_BITWISE_XOR_ASN_OP_T(int64)
615
616#undef DEFN_BITWISE_XOR_ASN_OP_T
617
618
619template <class X, class Y>
620inline
621const sc_lv_base
622operator ^ ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
623{
624    sc_lv_base a( px.back_cast() );
625    return ( a ^= py.back_cast() );
626}
627
628
629#define DEFN_BITWISE_XOR_OP_T_A(tp)                                           \
630template <class X>                                                            \
631inline                                                                        \
632const sc_lv_base                                                              \
633sc_proxy<X>::operator ^ ( tp b ) const                                        \
634{                                                                             \
635    sc_lv_base a( back_cast() );                                              \
636    return ( a ^= b );                                                        \
637}
638
639DEFN_BITWISE_XOR_OP_T_A(const char*)
640DEFN_BITWISE_XOR_OP_T_A(const bool*)
641DEFN_BITWISE_XOR_OP_T_A(const sc_logic*)
642DEFN_BITWISE_XOR_OP_T_A(const sc_unsigned&)
643DEFN_BITWISE_XOR_OP_T_A(const sc_signed&)
644DEFN_BITWISE_XOR_OP_T_A(const sc_uint_base&)
645DEFN_BITWISE_XOR_OP_T_A(const sc_int_base&)
646DEFN_BITWISE_XOR_OP_T_A(unsigned long)
647DEFN_BITWISE_XOR_OP_T_A(long)
648DEFN_BITWISE_XOR_OP_T_A(unsigned int)
649DEFN_BITWISE_XOR_OP_T_A(int)
650DEFN_BITWISE_XOR_OP_T_A(uint64)
651DEFN_BITWISE_XOR_OP_T_A(int64)
652
653#undef DEFN_BITWISE_XOR_OP_T_A
654
655
656#define DEFN_BITWISE_XOR_OP_T_B(tp)                                           \
657template <class X>                                                            \
658inline                                                                        \
659const sc_lv_base                                                              \
660operator ^ ( tp b, const sc_proxy<X>& px )                                    \
661{                                                                             \
662    return ( px ^ b );                                                        \
663}
664
665DEFN_BITWISE_XOR_OP_T_B(const char*)
666DEFN_BITWISE_XOR_OP_T_B(const bool*)
667DEFN_BITWISE_XOR_OP_T_B(const sc_logic*)
668DEFN_BITWISE_XOR_OP_T_B(const sc_unsigned&)
669DEFN_BITWISE_XOR_OP_T_B(const sc_signed&)
670DEFN_BITWISE_XOR_OP_T_B(const sc_uint_base&)
671DEFN_BITWISE_XOR_OP_T_B(const sc_int_base&)
672DEFN_BITWISE_XOR_OP_T_B(unsigned long)
673DEFN_BITWISE_XOR_OP_T_B(long)
674DEFN_BITWISE_XOR_OP_T_B(unsigned int)
675DEFN_BITWISE_XOR_OP_T_B(int)
676DEFN_BITWISE_XOR_OP_T_B(uint64)
677DEFN_BITWISE_XOR_OP_T_B(int64)
678
679#undef DEFN_BITWISE_XOR_OP_T_B
680
681
682// bitwise left shift
683
684template <class X>
685inline
686const sc_lv_base
687sc_proxy<X>::operator << ( int n ) const
688{
689    sc_lv_base a( back_cast().length()+n );
690	a = back_cast();
691    return ( a <<= n );
692}
693
694
695// bitwise right shift
696
697template <class X>
698inline
699const sc_lv_base
700sc_proxy<X>::operator >> ( int n ) const
701{
702    sc_lv_base a( back_cast() );
703    return ( a >>= n );
704}
705
706
707// bitwise left rotate
708
709template <class X>
710inline
711X&
712sc_proxy<X>::lrotate( int n )
713{
714    X& x = back_cast();
715    if( n < 0 ) {
716	char msg[BUFSIZ];
717	std::sprintf( msg,
718		 "left rotate operation is only allowed with positive "
719		 "rotate values, rotate value = %d", n );
720	SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
721    }
722    int len = x.length();
723    n %= len;
724    // x = (x << n) | (x >> (len - n));
725    sc_lv_base a( x << n );
726    sc_lv_base b( x >> (len - n) );
727    int sz = x.size();
728    for( int i = 0; i < sz; ++ i ) {
729	x.set_word( i, a.get_word( i ) | b.get_word( i ) );
730	x.set_cword( i, a.get_cword( i ) | b.get_cword( i ) );
731    }
732    x.clean_tail();
733    return x;
734}
735
736template <class X>
737inline
738const sc_lv_base
739lrotate( const sc_proxy<X>& x, int n )
740{
741    sc_lv_base a( x.back_cast() );
742    return a.lrotate( n );
743}
744
745
746// bitwise right rotate
747
748template <class X>
749inline
750X&
751sc_proxy<X>::rrotate( int n )
752{
753    X& x = back_cast();
754    if( n < 0 ) {
755	char msg[BUFSIZ];
756	std::sprintf( msg,
757		 "right rotate operation is only allowed with positive "
758		 "rotate values, rotate value = %d", n );
759	SC_REPORT_ERROR( sc_core::SC_ID_OUT_OF_BOUNDS_, msg );
760    }
761    int len = x.length();
762    n %= len;
763    // x = (x >> n) | (x << (len - n));
764    sc_lv_base a( x >> n );
765    sc_lv_base b( x << (len - n) );
766    int sz = x.size();
767    for( int i = 0; i < sz; ++ i ) {
768	x.set_word( i, a.get_word( i ) | b.get_word( i ) );
769	x.set_cword( i, a.get_cword( i ) | b.get_cword( i ) );
770    }
771    x.clean_tail();
772    return x;
773}
774
775template <class X>
776inline
777const sc_lv_base
778rrotate( const sc_proxy<X>& x, int n )
779{
780    sc_lv_base a( x.back_cast() );
781    return a.rrotate( n );
782}
783
784
785// bitwise reverse
786
787template <class X>
788inline
789const sc_lv_base
790reverse( const sc_proxy<X>& x )
791{
792    sc_lv_base a( x.back_cast() );
793    return a.reverse();
794}
795
796
797// relational operators
798
799template <class X, class Y>
800inline
801bool
802operator == ( const sc_proxy<X>& px, const sc_proxy<Y>& py )
803{
804    const X& x = px.back_cast();
805    const Y& y = py.back_cast();
806    int x_len = x.length();
807    int y_len = y.length();
808    if( x_len != y_len ) {
809	return false;
810    }
811    int sz = x.size();
812    for( int i = 0; i < sz; ++ i ) {
813	if( x.get_word( i ) != y.get_word( i ) ||
814	    x.get_cword( i ) != y.get_cword( i ) ) {
815	    return false;
816	}
817    }
818    return true;
819}
820
821
822#define DEFN_REL_OP_T(tp)                                                     \
823template <class X>                                                            \
824inline                                                                        \
825bool                                                                          \
826sc_proxy<X>::operator == ( tp b ) const                                       \
827{                                                                             \
828    const X& x = back_cast();                                                 \
829    sc_lv_base y( x.length() );                                               \
830    y = b;                                                                    \
831    return ( x == y );                                                        \
832}
833
834DEFN_REL_OP_T(const char*)
835DEFN_REL_OP_T(const bool*)
836DEFN_REL_OP_T(const sc_logic*)
837DEFN_REL_OP_T(const sc_unsigned&)
838DEFN_REL_OP_T(const sc_signed&)
839DEFN_REL_OP_T(const sc_uint_base&)
840DEFN_REL_OP_T(const sc_int_base&)
841DEFN_REL_OP_T(unsigned long)
842DEFN_REL_OP_T(long)
843DEFN_REL_OP_T(unsigned int)
844DEFN_REL_OP_T(int)
845DEFN_REL_OP_T(uint64)
846DEFN_REL_OP_T(int64)
847
848#undef DEFN_REL_OP_T
849
850
851// ----------------------------------------------------------------------------
852//  CLASS TEMPLATE : sc_bitref_r<X>
853//
854//  Proxy class for sc_proxy bit selection (r-value only).
855// ----------------------------------------------------------------------------
856
857// r-value concatenation operators and functions
858
859template <class T>
860inline
861sc_concref_r<sc_bitref_r<T>,sc_lv_base>
862operator , ( sc_bitref_r<T> a, const char* b )
863{
864    return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
865	*a.clone(), *new sc_lv_base( b ), 3 );
866}
867
868template <class T>
869inline
870sc_concref_r<sc_lv_base,sc_bitref_r<T> >
871operator , ( const char* a, sc_bitref_r<T> b )
872{
873    return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
874	*new sc_lv_base( a ), *b.clone(), 3 );
875}
876
877template <class T>
878inline
879sc_concref_r<sc_bitref_r<T>,sc_lv_base>
880operator , ( sc_bitref_r<T> a, const sc_logic& b )
881{
882    return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
883	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
884}
885
886template <class T>
887inline
888sc_concref_r<sc_lv_base,sc_bitref_r<T> >
889operator , ( const sc_logic& a, sc_bitref_r<T> b )
890{
891    return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
892	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
893}
894
895template <class T>
896inline
897sc_concref_r<sc_bitref_r<T>,sc_bv_base>
898operator , ( sc_bitref_r<T> a, bool b )
899{
900    return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
901        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
902}
903
904template <class T>
905inline
906sc_concref_r<sc_bv_base,sc_bitref_r<T> >
907operator , ( bool a, sc_bitref_r<T> b )
908{
909    return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
910        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
911}
912
913
914template <class T>
915inline
916sc_concref_r<sc_bitref_r<T>,sc_lv_base>
917concat( sc_bitref_r<T> a, const char* b )
918{
919    return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
920	*a.clone(), *new sc_lv_base( b ), 3 );
921}
922
923template <class T>
924inline
925sc_concref_r<sc_lv_base,sc_bitref_r<T> >
926concat( const char* a, sc_bitref_r<T> b )
927{
928    return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
929	*new sc_lv_base( a ), *b.clone(), 3 );
930}
931
932template <class T>
933inline
934sc_concref_r<sc_bitref_r<T>,sc_lv_base>
935concat( sc_bitref_r<T> a, const sc_logic& b )
936{
937    return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
938	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
939}
940
941template <class T>
942inline
943sc_concref_r<sc_lv_base,sc_bitref_r<T> >
944concat( const sc_logic& a, sc_bitref_r<T> b )
945{
946    return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
947	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
948}
949
950template <class T>
951inline
952sc_concref_r<sc_bitref_r<T>,sc_bv_base>
953concat( sc_bitref_r<T> a, bool b )
954{
955    return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
956        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
957}
958
959template <class T>
960inline
961sc_concref_r<sc_bv_base,sc_bitref_r<T> >
962concat( bool a, sc_bitref_r<T> b )
963{
964    return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
965        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
966}
967
968
969#ifdef SC_DT_MIXED_COMMA_OPERATORS
970
971template <class T>
972inline
973sc_concref_r<sc_bitref_r<T>,sc_lv_base>
974operator , ( sc_bitref<T> a, const char* b )
975{
976    return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
977	*a.clone(), *new sc_lv_base( b ), 3 );
978}
979
980template <class T>
981inline
982sc_concref_r<sc_lv_base,sc_bitref_r<T> >
983operator , ( const char* a, sc_bitref<T> b )
984{
985    return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
986	*new sc_lv_base( a ), *b.clone(), 3 );
987}
988
989template <class T>
990inline
991sc_concref_r<sc_bitref_r<T>,sc_lv_base>
992operator , ( sc_bitref<T> a, const sc_logic& b )
993{
994    return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
995	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
996}
997
998template <class T>
999inline
1000sc_concref_r<sc_lv_base,sc_bitref_r<T> >
1001operator , ( const sc_logic& a, sc_bitref<T> b )
1002{
1003    return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
1004	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1005}
1006
1007template <class T>
1008inline
1009sc_concref_r<sc_bitref_r<T>,sc_bv_base>
1010operator , ( sc_bitref<T> a, bool b )
1011{
1012    return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
1013        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1014}
1015
1016template <class T>
1017inline
1018sc_concref_r<sc_bv_base,sc_bitref_r<T> >
1019operator , ( bool a, sc_bitref<T> b )
1020{
1021    return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
1022        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1023}
1024
1025
1026template <class T>
1027inline
1028sc_concref_r<sc_bitref_r<T>,sc_lv_base>
1029concat( sc_bitref<T> a, const char* b )
1030{
1031    return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
1032	*a.clone(), *new sc_lv_base( b ), 3 );
1033}
1034
1035template <class T>
1036inline
1037sc_concref_r<sc_lv_base,sc_bitref_r<T> >
1038concat( const char* a, sc_bitref<T> b )
1039{
1040    return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
1041	*new sc_lv_base( a ), *b.clone(), 3 );
1042}
1043
1044template <class T>
1045inline
1046sc_concref_r<sc_bitref_r<T>,sc_lv_base>
1047concat( sc_bitref<T> a, const sc_logic& b )
1048{
1049    return sc_concref_r<sc_bitref_r<T>,sc_lv_base>(
1050	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1051}
1052
1053template <class T>
1054inline
1055sc_concref_r<sc_lv_base,sc_bitref_r<T> >
1056concat( const sc_logic& a, sc_bitref<T> b )
1057{
1058    return sc_concref_r<sc_lv_base,sc_bitref_r<T> >(
1059	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1060}
1061
1062template <class T>
1063inline
1064sc_concref_r<sc_bitref_r<T>,sc_bv_base>
1065concat( sc_bitref<T> a, bool b )
1066{
1067    return sc_concref_r<sc_bitref_r<T>,sc_bv_base>
1068        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1069}
1070
1071template <class T>
1072inline
1073sc_concref_r<sc_bv_base,sc_bitref_r<T> >
1074concat( bool a, sc_bitref<T> b )
1075{
1076    return sc_concref_r<sc_bv_base,sc_bitref_r<T> >
1077        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1078}
1079
1080#endif
1081
1082
1083// ----------------------------------------------------------------------------
1084//  CLASS TEMPLATE : sc_subref_r<X>
1085//
1086//  Proxy class for sc_proxy part selection (r-value only).
1087// ----------------------------------------------------------------------------
1088
1089// r-value concatenation operators and functions
1090
1091template <class T>
1092inline
1093sc_concref_r<sc_subref_r<T>,sc_lv_base>
1094operator , ( sc_subref_r<T> a, const char* b )
1095{
1096    return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1097	*a.clone(), *new sc_lv_base( b ), 3 );
1098}
1099
1100template <class T>
1101inline
1102sc_concref_r<sc_lv_base,sc_subref_r<T> >
1103operator , ( const char* a, sc_subref_r<T> b )
1104{
1105    return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1106	*new sc_lv_base( a ), *b.clone(), 3 );
1107}
1108
1109template <class T>
1110inline
1111sc_concref_r<sc_subref_r<T>,sc_lv_base>
1112operator , ( sc_subref_r<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
1120sc_concref_r<sc_lv_base,sc_subref_r<T> >
1121operator , ( const sc_logic& a, sc_subref_r<T> b )
1122{
1123    return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1124	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1125}
1126
1127template <class T>
1128inline
1129sc_concref_r<sc_subref_r<T>,sc_bv_base>
1130operator , ( sc_subref_r<T> a, bool b )
1131{
1132    return sc_concref_r<sc_subref_r<T>,sc_bv_base>
1133        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1134}
1135
1136template <class T>
1137inline
1138sc_concref_r<sc_bv_base,sc_subref_r<T> >
1139operator , ( bool a, sc_subref_r<T> b )
1140{
1141    return sc_concref_r<sc_bv_base,sc_subref_r<T> >
1142        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1143}
1144
1145
1146template <class T>
1147inline
1148sc_concref_r<sc_subref_r<T>,sc_lv_base>
1149concat( sc_subref_r<T> a, const char* b )
1150{
1151    return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1152	*a.clone(), *new sc_lv_base( b ), 3 );
1153}
1154
1155template <class T>
1156inline
1157sc_concref_r<sc_lv_base,sc_subref_r<T> >
1158concat( const char* a, sc_subref_r<T> b )
1159{
1160    return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1161	*new sc_lv_base( a ), *b.clone(), 3 );
1162}
1163
1164template <class T>
1165inline
1166sc_concref_r<sc_subref_r<T>,sc_lv_base>
1167concat( sc_subref_r<T> a, const sc_logic& b )
1168{
1169    return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1170	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1171}
1172
1173template <class T>
1174inline
1175sc_concref_r<sc_lv_base,sc_subref_r<T> >
1176concat( const sc_logic& a, sc_subref_r<T> b )
1177{
1178    return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1179	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1180}
1181
1182template <class T>
1183inline
1184sc_concref_r<sc_subref_r<T>,sc_bv_base>
1185concat( sc_subref_r<T> a, bool b )
1186{
1187    return sc_concref_r<sc_subref_r<T>,sc_bv_base>
1188        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1189}
1190
1191template <class T>
1192inline
1193sc_concref_r<sc_bv_base,sc_subref_r<T> >
1194concat( bool a, sc_subref_r<T> b )
1195{
1196    return sc_concref_r<sc_bv_base,sc_subref_r<T> >
1197        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1198}
1199
1200
1201#ifdef SC_DT_MIXED_COMMA_OPERATORS
1202
1203template <class T>
1204inline
1205sc_concref_r<sc_subref_r<T>,sc_lv_base>
1206operator , ( sc_subref<T> a, const char* b )
1207{
1208    return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1209	*a.clone(), *new sc_lv_base( b ), 3 );
1210}
1211
1212template <class T>
1213inline
1214sc_concref_r<sc_lv_base,sc_subref_r<T> >
1215operator , ( const char* a, sc_subref<T> b )
1216{
1217    return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1218	*new sc_lv_base( a ), *b.clone(), 3 );
1219}
1220
1221template <class T>
1222inline
1223sc_concref_r<sc_subref_r<T>,sc_lv_base>
1224operator , ( sc_subref<T> a, const sc_logic& b )
1225{
1226    return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1227	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1228}
1229
1230template <class T>
1231inline
1232sc_concref_r<sc_lv_base,sc_subref_r<T> >
1233operator , ( const sc_logic& a, sc_subref<T> b )
1234{
1235    return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1236	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1237}
1238
1239template <class T>
1240inline
1241sc_concref_r<sc_subref_r<T>,sc_bv_base>
1242operator , ( sc_subref<T> a, bool b )
1243{
1244    return sc_concref_r<sc_subref_r<T>,sc_bv_base>
1245        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1246}
1247
1248template <class T>
1249inline
1250sc_concref_r<sc_bv_base,sc_subref_r<T> >
1251operator , ( bool a, sc_subref<T> b )
1252{
1253    return sc_concref_r<sc_bv_base,sc_subref_r<T> >
1254        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1255}
1256
1257
1258template <class T>
1259inline
1260sc_concref_r<sc_subref_r<T>,sc_lv_base>
1261concat( sc_subref<T> a, const char* b )
1262{
1263    return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1264	*a.clone(), *new sc_lv_base( b ), 3 );
1265}
1266
1267template <class T>
1268inline
1269sc_concref_r<sc_lv_base,sc_subref_r<T> >
1270concat( const char* a, sc_subref<T> b )
1271{
1272    return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1273	*new sc_lv_base( a ), *b.clone(), 3 );
1274}
1275
1276template <class T>
1277inline
1278sc_concref_r<sc_subref_r<T>,sc_lv_base>
1279concat( sc_subref<T> a, const sc_logic& b )
1280{
1281    return sc_concref_r<sc_subref_r<T>,sc_lv_base>(
1282	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1283}
1284
1285template <class T>
1286inline
1287sc_concref_r<sc_lv_base,sc_subref_r<T> >
1288concat( const sc_logic& a, sc_subref<T> b )
1289{
1290    return sc_concref_r<sc_lv_base,sc_subref_r<T> >(
1291	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1292}
1293
1294template <class T>
1295inline
1296sc_concref_r<sc_subref_r<T>,sc_bv_base>
1297concat( sc_subref<T> a, bool b )
1298{
1299    return sc_concref_r<sc_subref_r<T>,sc_bv_base>
1300        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1301}
1302
1303template <class T>
1304inline
1305sc_concref_r<sc_bv_base,sc_subref_r<T> >
1306concat( bool a, sc_subref<T> b )
1307{
1308    return sc_concref_r<sc_bv_base,sc_subref_r<T> >
1309        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1310}
1311
1312#endif
1313
1314
1315// ----------------------------------------------------------------------------
1316//  CLASS TEMPLATE : sc_subref<X>
1317//
1318//  Proxy class for sc_proxy part selection (r-value and l-value).
1319// ----------------------------------------------------------------------------
1320
1321template <class X>
1322inline
1323sc_subref<X>&
1324sc_subref<X>::operator = ( const sc_subref_r<X>& b )
1325{
1326    sc_lv_base t( b ); // (partial) self assignment protection
1327    int len = sc_min( this->length(), t.length() );
1328    if( ! this->reversed() ) {
1329        for( int i = len - 1; i >= 0; -- i ) {
1330            this->m_obj.set_bit( this->m_lo + i, t[i].value() );
1331        }
1332    } else {
1333        for( int i = len - 1; i >= 0; -- i ) {
1334            this->m_obj.set_bit( this->m_lo - i, t[i].value() );
1335        }
1336    }
1337    return *this;
1338}
1339
1340template <class X>
1341inline
1342sc_subref<X>&
1343sc_subref<X>::operator = ( const sc_subref<X>& b )
1344{
1345    sc_lv_base t( b ); // (partial) self assignment protection
1346    int len = sc_min( this->length(), t.length() );
1347    if( ! this->reversed() ) {
1348        for( int i = len - 1; i >= 0; -- i ) {
1349            this->m_obj.set_bit( this->m_lo + i, t[i].value() );
1350        }
1351    } else {
1352        for( int i = len - 1; i >= 0; -- i ) {
1353            this->m_obj.set_bit( this->m_lo - i, t[i].value() );
1354        }
1355    }
1356    return *this;
1357}
1358
1359
1360// ----------------------------------------------------------------------------
1361//  CLASS TEMPLATE : sc_concref_r<X,Y>
1362//
1363//  Proxy class for sc_proxy concatenation (r-value only).
1364// ----------------------------------------------------------------------------
1365
1366// r-value concatenation operators and functions
1367
1368template <class T1, class T2>
1369inline
1370sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1371operator , ( sc_concref_r<T1,T2> a, const char* b )
1372{
1373    return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>(
1374	*a.clone(), *new sc_lv_base( b ), 3 );
1375}
1376
1377template <class T1, class T2>
1378inline
1379sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1380operator , ( const char* a, sc_concref_r<T1,T2> b )
1381{
1382    return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >(
1383	*new sc_lv_base( a ), *b.clone(), 3 );
1384}
1385
1386template <class T1, class T2>
1387inline
1388sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1389operator , ( sc_concref_r<T1,T2> a, const sc_logic& b )
1390{
1391    return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>(
1392	*a.clone(), *new sc_lv_base( b, 1 ), 3 );
1393}
1394
1395template <class T1, class T2>
1396inline
1397sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1398operator , ( const sc_logic& a, sc_concref_r<T1,T2> b )
1399{
1400    return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >(
1401	*new sc_lv_base( a, 1 ), *b.clone(), 3 );
1402}
1403
1404template <class T1, class T2>
1405inline
1406sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1407operator , ( sc_concref_r<T1,T2> a, bool b )
1408{
1409    return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1410        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1411}
1412
1413template <class T1, class T2>
1414inline
1415sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1416operator , ( bool a, sc_concref_r<T1,T2> b )
1417{
1418    return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1419        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1420}
1421
1422
1423template <class T1, class T2>
1424inline
1425sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1426concat( sc_concref_r<T1,T2> a, const char* b )
1427{
1428    return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1429        ( *a.clone(), *new sc_lv_base( b ), 3 );
1430}
1431
1432template <class T1, class T2>
1433inline
1434sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1435concat( const char* a, sc_concref_r<T1,T2> b )
1436{
1437    return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1438        ( *new sc_lv_base( a ), *b.clone(), 3 );
1439}
1440
1441template <class T1, class T2>
1442inline
1443sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1444concat( sc_concref_r<T1,T2> a, const sc_logic& b )
1445{
1446    return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1447        ( *a.clone(), *new sc_lv_base( b, 1 ), 3 );
1448}
1449
1450template <class T1, class T2>
1451inline
1452sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1453concat( const sc_logic& a, sc_concref_r<T1,T2> b )
1454{
1455    return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1456        ( *new sc_lv_base( a, 1 ), *b.clone(), 3 );
1457}
1458
1459template <class T1, class T2>
1460inline
1461sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1462concat( sc_concref_r<T1,T2> a, bool b )
1463{
1464    return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1465        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1466}
1467
1468template <class T1, class T2>
1469inline
1470sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1471concat( bool a, sc_concref_r<T1,T2> b )
1472{
1473    return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1474        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1475}
1476
1477
1478#ifdef SC_DT_MIXED_COMMA_OPERATORS
1479
1480template <class T1, class T2>
1481inline
1482sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1483operator , ( sc_concref<T1,T2> a, const char* b )
1484{
1485    return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1486        ( *a.clone(), *new sc_lv_base( b ), 3 );
1487}
1488
1489template <class T1, class T2>
1490inline
1491sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1492operator , ( const char* a, sc_concref<T1,T2> b )
1493{
1494    return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1495        ( *new sc_lv_base( a ), *b.clone(), 3 );
1496}
1497
1498template <class T1, class T2>
1499inline
1500sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1501operator , ( sc_concref<T1,T2> a, const sc_logic& b )
1502{
1503    return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1504        ( *a.clone(), *new sc_lv_base( b, 1 ), 3 );
1505}
1506
1507template <class T1, class T2>
1508inline
1509sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1510operator , ( const sc_logic& a, sc_concref<T1,T2> b )
1511{
1512    return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1513        ( *new sc_lv_base( a, 1 ), *b.clone(), 3 );
1514}
1515
1516template <class T1, class T2>
1517inline
1518sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1519operator , ( sc_concref<T1,T2> a, bool b )
1520{
1521    return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1522        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1523}
1524
1525template <class T1, class T2>
1526inline
1527sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1528operator , ( bool a, sc_concref<T1,T2> b )
1529{
1530    return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1531        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1532}
1533
1534
1535template <class T1, class T2>
1536inline
1537sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1538concat( sc_concref<T1,T2> a, const char* b )
1539{
1540    return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1541        ( *a.clone(), *new sc_lv_base( b ), 3 );
1542}
1543
1544template <class T1, class T2>
1545inline
1546sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1547concat( const char* a, sc_concref<T1,T2> b )
1548{
1549    return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1550        ( *new sc_lv_base( a ), *b.clone(), 3 );
1551}
1552
1553template <class T1, class T2>
1554inline
1555sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1556concat( sc_concref<T1,T2> a, const sc_logic& b )
1557{
1558    return sc_concref_r<sc_concref_r<T1,T2>,sc_lv_base>
1559        ( *a.clone(), *new sc_lv_base( b, 1 ), 3 );
1560}
1561
1562template <class T1, class T2>
1563inline
1564sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1565concat( const sc_logic& a, sc_concref<T1,T2> b )
1566{
1567    return sc_concref_r<sc_lv_base,sc_concref_r<T1,T2> >
1568        ( *new sc_lv_base( a, 1 ), *b.clone(), 3 );
1569}
1570
1571template <class T1, class T2>
1572inline
1573sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1574concat( sc_concref<T1,T2> a, bool b )
1575{
1576    return sc_concref_r<sc_concref_r<T1,T2>,sc_bv_base>
1577        ( *a.clone(), *new sc_bv_base( b, 1 ), 3 );
1578}
1579
1580template <class T1, class T2>
1581inline
1582sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1583concat( bool a, sc_concref<T1,T2> b )
1584{
1585    return sc_concref_r<sc_bv_base,sc_concref_r<T1,T2> >
1586        ( *new sc_bv_base( a, 1 ), *b.clone(), 3 );
1587}
1588
1589#endif
1590
1591
1592// ----------------------------------------------------------------------------
1593//  CLASS TEMPLATE : sc_proxy<T>
1594//
1595//  Base class template for bit/logic vector classes.
1596//  (Barton/Nackmann implementation)
1597// ----------------------------------------------------------------------------
1598
1599// r-value concatenation operators and functions
1600
1601template <class T>
1602inline
1603sc_concref_r<T,sc_lv_base>
1604operator , ( const sc_proxy<T>& a, const char* b )
1605{
1606    return sc_concref_r<T,sc_lv_base>
1607      ( a.back_cast(), *new sc_lv_base( b ), 2 );
1608}
1609
1610template <class T>
1611inline
1612sc_concref_r<sc_lv_base,T>
1613operator , ( const char* a, const sc_proxy<T>& b )
1614{
1615    return sc_concref_r<sc_lv_base,T>
1616      ( *new sc_lv_base( a ), b.back_cast(), 1 );
1617}
1618
1619template <class T>
1620inline
1621sc_concref_r<T,sc_lv_base>
1622operator , ( const sc_proxy<T>& a, const sc_logic& b )
1623{
1624    return sc_concref_r<T,sc_lv_base>
1625      ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
1626}
1627
1628template <class T>
1629inline
1630sc_concref_r<sc_lv_base,T>
1631operator , ( const sc_logic& a, const sc_proxy<T>& b )
1632{
1633    return sc_concref_r<sc_lv_base,T>
1634      ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
1635}
1636
1637template <class T>
1638inline
1639sc_concref_r<T,sc_bv_base>
1640operator , ( const sc_proxy<T>& a, bool b )
1641{
1642    return sc_concref_r<T,sc_bv_base>
1643        ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
1644}
1645
1646template <class T>
1647inline
1648sc_concref_r<sc_bv_base,T>
1649operator , ( bool a, const sc_proxy<T>& b )
1650{
1651    return sc_concref_r<sc_bv_base,T>
1652      ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
1653}
1654
1655
1656template <class T>
1657inline
1658sc_concref_r<T,sc_lv_base>
1659concat( const sc_proxy<T>& a, const char* b )
1660{
1661    return sc_concref_r<T,sc_lv_base>
1662      ( a.back_cast(), *new sc_lv_base( b ), 2 );
1663}
1664
1665template <class T>
1666inline
1667sc_concref_r<sc_lv_base,T>
1668concat( const char* a, const sc_proxy<T>& b )
1669{
1670    return sc_concref_r<sc_lv_base,T>
1671      ( *new sc_lv_base( a ), b.back_cast(), 1 );
1672}
1673
1674template <class T>
1675inline
1676sc_concref_r<T,sc_lv_base>
1677concat( const sc_proxy<T>& a, const sc_logic& b )
1678{
1679    return sc_concref_r<T,sc_lv_base>
1680      ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
1681}
1682
1683template <class T>
1684inline
1685sc_concref_r<sc_lv_base,T>
1686concat( const sc_logic& a, const sc_proxy<T>& b )
1687{
1688    return sc_concref_r<sc_lv_base,T>
1689      ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
1690}
1691
1692template <class T>
1693inline
1694sc_concref_r<T,sc_bv_base>
1695concat( const sc_proxy<T>& a, bool b )
1696{
1697    return sc_concref_r<T,sc_bv_base>
1698      ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
1699}
1700
1701template <class T>
1702inline
1703sc_concref_r<sc_bv_base,T>
1704concat( bool a, const sc_proxy<T>& b )
1705{
1706    return sc_concref_r<sc_bv_base,T>
1707      ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
1708}
1709
1710
1711#ifdef SC_DT_MIXED_COMMA_OPERATORS
1712
1713template <class T>
1714inline
1715sc_concref_r<T,sc_lv_base>
1716operator , ( sc_proxy<T>& a, const char* b )
1717{
1718    return sc_concref_r<T,sc_lv_base>
1719      ( a.back_cast(), *new sc_lv_base( b ), 2 );
1720}
1721
1722template <class T>
1723inline
1724sc_concref_r<sc_lv_base,T>
1725operator , ( const char* a, sc_proxy<T>& b )
1726{
1727    return sc_concref_r<sc_lv_base,T>
1728        ( *new sc_lv_base( a ), b.back_cast(), 1 );
1729}
1730
1731template <class T>
1732inline
1733sc_concref_r<T,sc_lv_base>
1734operator , ( sc_proxy<T>& a, const sc_logic& b )
1735{
1736    return sc_concref_r<T,sc_lv_base>
1737        ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
1738}
1739
1740template <class T>
1741inline
1742sc_concref_r<sc_lv_base,T>
1743operator , ( const sc_logic& a, sc_proxy<T>& b )
1744{
1745    return sc_concref_r<sc_lv_base,T>
1746        ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
1747}
1748
1749template <class T>
1750inline
1751sc_concref_r<T,sc_bv_base>
1752operator , ( sc_proxy<T>& a, bool b )
1753{
1754    return sc_concref_r<T,sc_bv_base>
1755        ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
1756}
1757
1758template <class T>
1759inline
1760sc_concref_r<sc_bv_base,T>
1761operator , ( bool a, sc_proxy<T>& b )
1762{
1763    return sc_concref_r<sc_bv_base,T>
1764        ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
1765}
1766
1767
1768template <class T>
1769inline
1770sc_concref_r<T,sc_lv_base>
1771concat( sc_proxy<T>& a, const char* b )
1772{
1773    return sc_concref_r<T,sc_lv_base>
1774        ( a.back_cast(), *new sc_lv_base( b ), 2 );
1775}
1776
1777template <class T>
1778inline
1779sc_concref_r<sc_lv_base,T>
1780concat( const char* a, sc_proxy<T>& b )
1781{
1782    return sc_concref_r<sc_lv_base,T>
1783        ( *new sc_lv_base( a ), b.back_cast(), 1 );
1784}
1785
1786template <class T>
1787inline
1788sc_concref_r<T,sc_lv_base>
1789concat( sc_proxy<T>& a, const sc_logic& b )
1790{
1791    return sc_concref_r<T,sc_lv_base>
1792        ( a.back_cast(), *new sc_lv_base( b, 1 ), 2 );
1793}
1794
1795template <class T>
1796inline
1797sc_concref_r<sc_lv_base,T>
1798concat( const sc_logic& a, sc_proxy<T>& b )
1799{
1800    return sc_concref_r<sc_lv_base,T>
1801        ( *new sc_lv_base( a, 1 ), b.back_cast(), 1 );
1802}
1803
1804template <class T>
1805inline
1806sc_concref_r<T,sc_bv_base>
1807concat( sc_proxy<T>& a, bool b )
1808{
1809    return sc_concref_r<T,sc_bv_base>
1810        ( a.back_cast(), *new sc_bv_base( b, 1 ), 2 );
1811}
1812
1813template <class T>
1814inline
1815sc_concref_r<sc_bv_base,T>
1816concat( bool a, sc_proxy<T>& b )
1817{
1818    return sc_concref_r<sc_bv_base,T>
1819        ( *new sc_bv_base( a, 1 ), b.back_cast(), 1 );
1820}
1821
1822#endif
1823
1824} // namespace sc_dt
1825
1826
1827#endif
1828