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_bit_proxies.h -- Proxy classes for vector data types.
23
24  Original Author: Gene Bushuyev, Synopsys, Inc.
25
26 CHANGE LOG AT THE END OF THE FILE
27 *****************************************************************************/
28
29#ifndef __SYSTEMC_EXT_DT_BIT_SC_BIT_PROXIES_HH__
30#define __SYSTEMC_EXT_DT_BIT_SC_BIT_PROXIES_HH__
31
32#include <iostream>
33
34#include "../../utils/messages.hh"
35#include "sc_proxy.hh"
36
37namespace sc_dt
38{
39
40// classes defined in this module
41template <class X, class Traits>
42class sc_bitref_conv_r;
43template <class X>
44class sc_bitref_r;
45template <class X>
46class sc_bitref;
47template <class X>
48class sc_subref_r;
49template <class X>
50class sc_subref;
51template <class X, class Y>
52class sc_concref_r;
53template <class X, class Y>
54class sc_concref;
55
56// ----------------------------------------------------------------------------
57//  CLASS TEMPLATE : sc_bitref_conv_r<T>
58//
59//  Proxy class for sc_proxy bit selection (r-value only, boolean conversion).
60// ----------------------------------------------------------------------------
61template <class T, class Traits=typename T::traits_type>
62class sc_bitref_conv_r { /* empty by default */ };
63
64// specialization for bit-vector based sc_proxy classes
65template<typename T>
66class sc_bitref_conv_r<T, sc_proxy_traits<sc_bv_base> >
67{
68  public:
69#if __cplusplus >= 201103L // explicit operator needs C++11
70    // explicit conversion to bool
71    explicit operator bool() const
72    {
73        return static_cast<const sc_bitref_r<T> &>(*this).to_bool();
74    }
75#endif
76
77    // explicit (negating) conversion to bool
78    bool
79    operator ! () const
80    {
81        return !static_cast<const sc_bitref_r<T> &>(*this).to_bool();
82    }
83};
84
85// ----------------------------------------------------------------------------
86//  CLASS TEMPLATE : sc_bitref_r<T>
87//
88//  Proxy class for sc_proxy bit selection (r-value only).
89// ----------------------------------------------------------------------------
90
91template <class T>
92class sc_bitref_r : public sc_bitref_conv_r<T>
93{
94    friend class sc_bv_base;
95    friend class sc_lv_base;
96
97  public:
98    // typedefs
99    typedef typename T::traits_type traits_type;
100    typedef typename traits_type::bit_type bit_type;
101    typedef typename traits_type::value_type value_type;
102
103    // constructor
104    sc_bitref_r(const T &obj_, int index_) :
105            m_obj(const_cast<T &>(obj_)), m_index(index_)
106    {}
107
108    // copy constructor
109    sc_bitref_r(const sc_bitref_r<T> &a) : m_obj(a.m_obj), m_index(a.m_index)
110    {}
111
112    // cloning
113    sc_bitref_r<T> *clone() const { return new sc_bitref_r<T>(*this); }
114
115    // bitwise operators and functions
116
117    // bitwise complement
118    bit_type
119    operator ~ () const
120    {
121        return bit_type(sc_logic::not_table[value()]);
122    }
123
124    // implicit conversion to bit_type
125    operator bit_type() const { return bit_type(m_obj.get_bit(m_index)); }
126
127    // explicit conversions
128    value_type value() const { return m_obj.get_bit(m_index); }
129    bool is_01() const { return sc_logic(value()).is_01(); }
130    bool to_bool() const { return sc_logic(value()).to_bool(); }
131    char to_char() const { return sc_logic(value()).to_char(); }
132
133    // common methods
134    int length() const { return 1; }
135    int size() const { return ((length() - 1) / SC_DIGIT_SIZE + 1); }
136
137    value_type get_bit(int n) const;
138
139    sc_digit get_word(int i) const;
140    sc_digit get_cword(int i) const;
141
142    // other methods
143    void print(::std::ostream &os=::std::cout) const { os << to_char(); }
144
145  protected:
146    T &m_obj;
147    int m_index;
148
149  private:
150    // Disabled
151    sc_bitref_r();
152    sc_bitref_r<T> &operator = (const sc_bitref_r<T> &);
153};
154
155// bitwise operators and functions
156
157// bitwise and
158template <class T1, class T2>
159inline sc_logic operator & (
160        const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b);
161
162
163// bitwise or
164template <class T1, class T2>
165inline sc_logic operator | (
166        const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b);
167
168// bitwise xor
169template <class T1, class T2>
170inline sc_logic operator ^ (
171        const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b);
172
173// relational operators and functions
174template <class T1, class T2>
175inline bool operator == (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b);
176
177template <class T1, class T2>
178inline bool operator != (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b);
179
180// r-value concatenation operators and functions
181template <class T1, class T2>
182inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > operator , (
183        sc_bitref_r<T1>, sc_bitref_r<T2>);
184
185template <class T1, class T2>
186inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > operator , (
187        sc_bitref_r<T1>, sc_subref_r<T2>);
188
189template <class T1, class T2, class T3>
190inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2,T3> > operator , (
191        sc_bitref_r<T1>, sc_concref_r<T2,T3>);
192
193template <class T1, class T2>
194inline sc_concref_r<sc_bitref_r<T1>, T2> operator , (
195        sc_bitref_r<T1>, const sc_proxy<T2> &);
196
197template <class T>
198inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , (
199        sc_bitref_r<T>, const char *);
200
201template <class T>
202inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , (
203        const char *, sc_bitref_r<T>);
204
205template <class T>
206inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , (
207        sc_bitref_r<T>, const sc_logic &);
208
209template <class T>
210inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , (
211        const sc_logic &, sc_bitref_r<T>);
212
213template <class T>
214inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , (
215        sc_bitref_r<T>, bool);
216
217template <class T>
218inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , (
219        bool, sc_bitref_r<T>);
220
221
222template <class T1, class T2>
223inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > concat(
224        sc_bitref_r<T1>, sc_bitref_r<T2>);
225
226template <class T1, class T2>
227inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > concat(
228        sc_bitref_r<T1>, sc_subref_r<T2>);
229
230template <class T1, class T2, class T3>
231inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2,T3> > concat(
232        sc_bitref_r<T1>, sc_concref_r<T2, T3>);
233
234template <class T1, class T2>
235inline sc_concref_r<sc_bitref_r<T1>, T2> concat(
236        sc_bitref_r<T1>, const sc_proxy<T2> &);
237
238template <class T>
239inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat(
240        sc_bitref_r<T>, const char *);
241
242template <class T>
243inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat(
244        const char *, sc_bitref_r<T>);
245
246template <class T>
247inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat(
248        sc_bitref_r<T>, const sc_logic &);
249
250template <class T>
251inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat(
252        const sc_logic &, sc_bitref_r<T>);
253
254template <class T>
255inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat(
256        sc_bitref_r<T>, bool);
257
258template <class T>
259inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat(
260        bool, sc_bitref_r<T>);
261
262
263template <class T1, class T2>
264inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > operator , (
265        sc_bitref_r<T1>, sc_bitref<T2>);
266
267template <class T1, class T2>
268inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > operator , (
269        sc_bitref<T1>, sc_bitref_r<T2>);
270
271template <class T1, class T2>
272inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > operator , (
273        sc_bitref_r<T1>, sc_subref<T2>);
274
275template <class T1, class T2>
276inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > operator , (
277        sc_bitref<T1>, sc_subref_r<T2>);
278
279template <class T1, class T2, class T3>
280inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > operator , (
281        sc_bitref_r<T1>, sc_concref<T2, T3>);
282
283template <class T1, class T2, class T3>
284inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2,T3> > operator , (
285        sc_bitref<T1>, sc_concref_r<T2, T3>);
286
287template <class T1, class T2>
288inline sc_concref_r<sc_bitref_r<T1>, T2> operator , (
289        sc_bitref<T1>, const sc_proxy<T2> &);
290
291template <class T1, class T2>
292inline sc_concref_r<sc_bitref_r<T1>, T2> operator , (
293        sc_bitref_r<T1>, sc_proxy<T2> &);
294
295template <class T>
296inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , (
297        sc_bitref<T>, const char *);
298
299template <class T>
300inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , (
301        const char *, sc_bitref<T>);
302
303template <class T>
304inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , (
305        sc_bitref<T>, const sc_logic &);
306
307template <class T>
308inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , (
309        const sc_logic &, sc_bitref<T>);
310
311template <class T>
312inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> operator , (
313        sc_bitref<T>, bool);
314
315template <class T>
316inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > operator , (
317        bool, sc_bitref<T>);
318
319
320template <class T1, class T2>
321inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > concat(
322        sc_bitref_r<T1>, sc_bitref<T2>);
323
324template <class T1, class T2>
325inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> > concat(
326        sc_bitref<T1>, sc_bitref_r<T2>);
327
328template <class T1, class T2>
329inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > concat(
330        sc_bitref_r<T1>, sc_subref<T2>);
331
332template <class T1, class T2>
333inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> > concat(
334        sc_bitref<T1>, sc_subref_r<T2>);
335
336template <class T1, class T2, class T3>
337inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > concat(
338        sc_bitref_r<T1>, sc_concref<T2, T3>);
339
340template <class T1, class T2, class T3>
341inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> > concat(
342        sc_bitref<T1>, sc_concref_r<T2, T3>);
343
344template <class T1, class T2>
345inline sc_concref_r<sc_bitref_r<T1>, T2> concat(
346        sc_bitref<T1>, const sc_proxy<T2> &);
347
348template <class T1, class T2>
349inline sc_concref_r<sc_bitref_r<T1>, T2> concat(
350        sc_bitref_r<T1>, sc_proxy<T2> &);
351
352template <class T>
353inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat(
354        sc_bitref<T>, const char *);
355
356template <class T>
357inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat(
358        const char *, sc_bitref<T>);
359
360template <class T>
361inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat(
362        sc_bitref<T>, const sc_logic &);
363
364template <class T>
365inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat(
366        const sc_logic &, sc_bitref<T>);
367
368template <class T>
369inline sc_concref_r<sc_bitref_r<T>, sc_lv_base> concat(sc_bitref<T>, bool);
370
371template <class T>
372inline sc_concref_r<sc_lv_base, sc_bitref_r<T> > concat(bool, sc_bitref<T>);
373
374
375// ----------------------------------------------------------------------------
376//  CLASS TEMPLATE : sc_bitref<X>
377//
378//  Proxy class for sc_proxy bit selection (r-value and l-value).
379// ----------------------------------------------------------------------------
380
381template <class X>
382class sc_bitref : public sc_bitref_r<X>
383{
384    friend class sc_bv_base;
385    friend class sc_lv_base;
386
387  public:
388    typedef typename sc_bitref_r<X>::value_type value_type;
389
390    // constructor
391    sc_bitref(X &obj_, int index_) : sc_bitref_r<X>(obj_, index_) {}
392
393    // copy constructor
394    sc_bitref(const sc_bitref<X> &a) : sc_bitref_r<X>(a) {}
395
396    // cloning
397    sc_bitref<X> *clone() const { return new sc_bitref<X>(*this); }
398
399    // assignment operators
400    sc_bitref<X> &operator = (const sc_bitref_r<X> &a);
401    sc_bitref<X> &operator = (const sc_bitref<X> &a);
402
403    sc_bitref<X> &
404    operator = (const sc_logic &a)
405    {
406        this->m_obj.set_bit(this->m_index, a.value());
407        return *this;
408    }
409
410    sc_bitref<X> &
411    operator = (sc_logic_value_t v)
412    {
413        *this = sc_logic(v);
414        return *this;
415    }
416
417    sc_bitref<X> &
418    operator = (bool a)
419    {
420        *this = sc_logic(a);
421        return *this;
422    }
423
424    sc_bitref<X> &
425    operator = (char a)
426    {
427        *this = sc_logic(a);
428        return *this;
429    }
430
431    sc_bitref<X> &
432    operator = (int a)
433    {
434        *this = sc_logic(a);
435        return *this;
436    }
437
438    sc_bitref<X> &
439    operator = (const sc_bit &a)
440    {
441        *this = sc_logic(a);
442        return *this;
443    }
444
445    // bitwise assignment operators
446    sc_bitref<X> &operator &= (const sc_bitref_r<X> &a);
447    sc_bitref<X> &operator &= (const sc_logic &a);
448
449    sc_bitref<X> &
450    operator &= (sc_logic_value_t v)
451    {
452        *this &= sc_logic(v);
453        return *this;
454    }
455
456    sc_bitref<X> &
457    operator &= (bool a)
458    {
459        *this &= sc_logic(a);
460        return *this;
461    }
462
463    sc_bitref<X> &
464    operator &= (char a)
465    {
466        *this &= sc_logic(a);
467        return *this;
468    }
469
470    sc_bitref<X> &
471    operator &= (int a)
472    {
473        *this &= sc_logic(a);
474        return *this;
475    }
476
477    sc_bitref<X> &operator |= (const sc_bitref_r<X> &a);
478    sc_bitref<X> &operator |= (const sc_logic &a);
479
480    sc_bitref<X> &
481    operator |= (sc_logic_value_t v)
482    {
483        *this |= sc_logic(v);
484        return *this;
485    }
486
487    sc_bitref<X> &
488    operator |= (bool a)
489    {
490        *this |= sc_logic(a);
491        return *this;
492    }
493
494    sc_bitref<X> &
495    operator |= (char a)
496    {
497        *this |= sc_logic(a);
498        return *this;
499    }
500
501    sc_bitref<X> &
502    operator |= (int a)
503    {
504        *this |= sc_logic(a);
505        return *this;
506    }
507
508    sc_bitref<X> &operator ^= (const sc_bitref_r<X> &a);
509    sc_bitref<X> &operator ^= (const sc_logic &a);
510
511    sc_bitref<X> &
512    operator ^= (sc_logic_value_t v)
513    {
514        *this ^= sc_logic(v);
515        return *this;
516    }
517
518    sc_bitref<X> &
519    operator ^= (bool a)
520    {
521        *this ^= sc_logic(a);
522        return *this;
523    }
524
525    sc_bitref<X> &
526    operator ^= (char a)
527    {
528        *this ^= sc_logic(a);
529        return *this;
530    }
531
532    sc_bitref<X> &
533    operator ^= (int a)
534    {
535        *this ^= sc_logic(a);
536        return *this;
537    }
538
539    // bitwise operators and functions
540
541    // bitwise complement
542    sc_bitref<X> &b_not();
543
544    // common methods
545    void set_bit(int n, value_type value);
546
547    void set_word(int i, sc_digit w);
548    void set_cword(int i, sc_digit w);
549
550    void clean_tail() { this->m_obj.clean_tail(); }
551
552    // other methods
553    void scan(::std::istream &is=::std::cin);
554
555  private:
556    // Disabled
557    sc_bitref();
558};
559
560
561// l-value concatenation operators and functions
562
563template <class T1, class T2>
564inline sc_concref<sc_bitref<T1>, sc_bitref<T2> > operator , (
565        sc_bitref<T1>, sc_bitref<T2>);
566
567template <class T1, class T2>
568inline sc_concref<sc_bitref<T1>, sc_subref<T2> > operator , (
569        sc_bitref<T1>, sc_subref<T2>);
570
571template <class T1, class T2, class T3>
572inline sc_concref<sc_bitref<T1>, sc_concref<T2, T3> > operator , (
573        sc_bitref<T1>, sc_concref<T2, T3>);
574
575template <class T1, class T2>
576inline sc_concref<sc_bitref<T1>, T2> operator , (
577        sc_bitref<T1>, sc_proxy<T2> &);
578
579
580template <class T1, class T2>
581inline sc_concref<sc_bitref<T1>, sc_bitref<T2> > concat(
582        sc_bitref<T1>, sc_bitref<T2>);
583
584template <class T1, class T2>
585inline sc_concref<sc_bitref<T1>, sc_subref<T2> > concat(
586        sc_bitref<T1>, sc_subref<T2>);
587
588template <class T1, class T2, class T3>
589inline sc_concref<sc_bitref<T1>, sc_concref<T2,T3> > concat(
590        sc_bitref<T1>, sc_concref<T2, T3>);
591
592template <class T1, class T2>
593inline sc_concref<sc_bitref<T1>, T2> concat(sc_bitref<T1>, sc_proxy<T2> &);
594
595
596template <class T>
597::std::istream &operator >> (::std::istream &, sc_bitref<T>);
598
599
600// ----------------------------------------------------------------------------
601//  CLASS TEMPLATE : sc_subref_r<X>
602//
603//  Proxy class for sc_proxy part selection (r-value only).
604// ----------------------------------------------------------------------------
605
606template <class X>
607class sc_subref_r : public sc_proxy<sc_subref_r<X> >
608{
609    void check_bounds();
610
611  public:
612    typedef typename sc_proxy<sc_subref_r<X> >::value_type value_type;
613
614    // constructor
615    sc_subref_r(const X &obj_, int hi_, int lo_) :
616            m_obj(const_cast<X &>(obj_)), m_hi(hi_), m_lo(lo_), m_len(0)
617    { check_bounds(); }
618
619    // copy constructor
620    sc_subref_r(const sc_subref_r<X> &a) :
621        m_obj(a.m_obj), m_hi(a.m_hi), m_lo(a.m_lo), m_len(a.m_len)
622    {}
623
624    // cloning
625    sc_subref_r<X> *clone() const { return new sc_subref_r<X>(*this); }
626
627    // common methods
628    int length() const { return m_len; }
629
630    int size() const { return ((length() - 1) / SC_DIGIT_SIZE + 1); }
631
632    value_type get_bit(int n) const;
633    void set_bit(int n, value_type value);
634
635    sc_digit get_word(int i) const;
636    void set_word(int i, sc_digit w);
637
638    sc_digit get_cword(int i) const;
639    void set_cword(int i, sc_digit w);
640
641    void clean_tail() { m_obj.clean_tail(); }
642
643    // other methods
644    bool is_01() const;
645    bool reversed() const { return m_lo > m_hi; }
646
647  protected:
648    X &m_obj;
649    int m_hi;
650    int m_lo;
651    int m_len;
652
653  private:
654    // Disabled
655    sc_subref_r();
656    sc_subref_r<X> &operator = (const sc_subref_r<X> &);
657};
658
659
660// r-value concatenation operators and functions
661
662template <class T1, class T2>
663inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > operator , (
664        sc_subref_r<T1>, sc_bitref_r<T2>);
665
666template <class T1, class T2>
667inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > operator , (
668        sc_subref_r<T1>, sc_subref_r<T2>);
669
670template <class T1, class T2, class T3>
671inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2,T3> > operator , (
672        sc_subref_r<T1>, sc_concref_r<T2, T3>);
673
674template <class T1, class T2>
675inline sc_concref_r<sc_subref_r<T1>, T2> operator , (
676        sc_subref_r<T1>, const sc_proxy<T2> &);
677
678template <class T>
679inline sc_concref_r<sc_subref_r<T>,sc_lv_base> operator , (
680        sc_subref_r<T>, const char *);
681
682template <class T>
683inline sc_concref_r<sc_lv_base, sc_subref_r<T> > operator , (
684        const char *, sc_subref_r<T>);
685
686template <class T>
687inline sc_concref_r<sc_subref_r<T>, sc_lv_base> operator , (
688        sc_subref_r<T>, const sc_logic &);
689
690template <class T>
691inline sc_concref_r<sc_lv_base, sc_subref_r<T> > operator , (
692        const sc_logic &, sc_subref_r<T>);
693
694template <class T>
695inline sc_concref_r<sc_subref_r<T>, sc_bv_base> operator , (
696        sc_subref_r<T>, bool);
697
698template <class T>
699inline sc_concref_r<sc_bv_base, sc_subref_r<T> > operator , (
700        bool, sc_subref_r<T>);
701
702
703template <class T1, class T2>
704inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > concat(
705        sc_subref_r<T1>, sc_bitref_r<T2>);
706
707template <class T1, class T2>
708inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > concat(
709        sc_subref_r<T1>, sc_subref_r<T2>);
710
711template <class T1, class T2, class T3>
712inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > concat(
713        sc_subref_r<T1>, sc_concref_r<T2, T3>);
714
715template <class T1, class T2>
716inline sc_concref_r<sc_subref_r<T1>, T2> concat(
717        sc_subref_r<T1>, const sc_proxy<T2> &);
718
719template <class T>
720inline sc_concref_r<sc_subref_r<T>, sc_lv_base> concat(
721        sc_subref_r<T>, const char *);
722
723template <class T>
724inline sc_concref_r<sc_lv_base,sc_subref_r<T> > concat(
725        const char *, sc_subref_r<T>);
726
727template <class T>
728inline sc_concref_r<sc_subref_r<T>, sc_lv_base> concat(
729        sc_subref_r<T>, const sc_logic &);
730
731template <class T>
732inline sc_concref_r<sc_lv_base, sc_subref_r<T> > concat(
733        const sc_logic &, sc_subref_r<T>);
734
735template <class T>
736inline sc_concref_r<sc_subref_r<T>, sc_bv_base> concat(sc_subref_r<T>, bool);
737
738template <class T>
739inline sc_concref_r<sc_bv_base, sc_subref_r<T> > concat(bool, sc_subref_r<T>);
740
741
742template <class T1, class T2>
743inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > operator , (
744        sc_subref_r<T1>, sc_bitref<T2>);
745
746template <class T1, class T2>
747inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > operator , (
748        sc_subref<T1>, sc_bitref_r<T2>);
749
750template <class T1, class T2>
751inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > operator , (
752        sc_subref_r<T1>, sc_subref<T2>);
753
754template <class T1, class T2>
755inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > operator , (
756        sc_subref<T1>, sc_subref_r<T2>);
757
758template <class T1, class T2, class T3>
759inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > operator , (
760        sc_subref_r<T1>, sc_concref<T2, T3>);
761
762template <class T1, class T2, class T3>
763inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > operator , (
764        sc_subref<T1>, sc_concref_r<T2, T3>);
765
766template <class T1, class T2>
767inline sc_concref_r<sc_subref_r<T1>, T2> operator , (
768        sc_subref<T1>, const sc_proxy<T2> &);
769
770template <class T1, class T2>
771inline sc_concref_r<sc_subref_r<T1>, T2> operator , (
772        sc_subref_r<T1>, sc_proxy<T2> &);
773
774template <class T>
775inline sc_concref_r<sc_subref_r<T>, sc_lv_base> operator , (
776        sc_subref<T>, const char *);
777
778template <class T>
779inline sc_concref_r<sc_lv_base, sc_subref_r<T> > operator , (
780        const char *, sc_subref<T>);
781
782template <class T>
783inline sc_concref_r<sc_subref_r<T>, sc_lv_base> operator , (
784        sc_subref<T>, const sc_logic &);
785
786template <class T>
787inline sc_concref_r<sc_lv_base, sc_subref_r<T> > operator , (
788        const sc_logic &, sc_subref<T>);
789
790template <class T>
791inline sc_concref_r<sc_subref_r<T>, sc_bv_base> operator , (
792        sc_subref<T>, bool);
793
794template <class T>
795inline sc_concref_r<sc_bv_base, sc_subref_r<T> > operator , (
796        bool, sc_subref<T>);
797
798
799template <class T1, class T2>
800inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > concat(
801        sc_subref_r<T1>, sc_bitref<T2>);
802
803template <class T1, class T2>
804inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> > concat(
805        sc_subref<T1>, sc_bitref_r<T2>);
806
807template <class T1, class T2>
808inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > concat(
809        sc_subref_r<T1>, sc_subref<T2>);
810
811template <class T1, class T2>
812inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> > concat(
813        sc_subref<T1>, sc_subref_r<T2>);
814
815template <class T1, class T2, class T3>
816inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > concat(
817        sc_subref_r<T1>, sc_concref<T2, T3>);
818
819template <class T1, class T2, class T3>
820inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> > concat(
821        sc_subref<T1>, sc_concref_r<T2, T3>);
822
823template <class T1, class T2>
824inline sc_concref_r<sc_subref_r<T1>, T2> concat(
825        sc_subref<T1>, const sc_proxy<T2> &);
826
827template <class T1, class T2>
828inline sc_concref_r<sc_subref_r<T1>, T2> concat(
829        sc_subref_r<T1>, sc_proxy<T2> &);
830
831template <class T>
832inline sc_concref_r<sc_subref_r<T>, sc_lv_base> concat(
833        sc_subref<T>, const char *);
834
835template <class T>
836inline sc_concref_r<sc_lv_base, sc_subref_r<T> > concat(
837        const char *, sc_subref<T>);
838
839template <class T>
840inline sc_concref_r<sc_subref_r<T>, sc_lv_base> concat(
841        sc_subref<T>, const sc_logic &);
842
843template <class T>
844inline sc_concref_r<sc_lv_base, sc_subref_r<T> > concat(
845        const sc_logic &, sc_subref<T>);
846
847template <class T>
848inline sc_concref_r<sc_subref_r<T>, sc_bv_base> concat(sc_subref<T>, bool);
849
850template <class T>
851inline sc_concref_r<sc_bv_base, sc_subref_r<T> > concat(bool, sc_subref<T>);
852
853
854// ----------------------------------------------------------------------------
855//  CLASS TEMPLATE : sc_subref<X>
856//
857//  Proxy class for sc_proxy part selection (r-value and l-value).
858// ----------------------------------------------------------------------------
859
860template <class X>
861class sc_subref : public sc_subref_r<X>
862{
863  public:
864    // typedefs
865    typedef sc_subref_r<X> base_type;
866
867    // constructor
868    sc_subref(X &obj_, int hi_, int lo_) : sc_subref_r<X>(obj_, hi_, lo_) {}
869
870    // copy constructor
871    sc_subref(const sc_subref<X> &a) : sc_subref_r<X>(a) {}
872
873    // cloning
874    sc_subref<X> *clone() const { return new sc_subref<X>(*this); }
875
876    // assignment operators
877    template <class Y>
878    sc_subref<X> &
879    operator = (const sc_proxy<Y> &a)
880    {
881        base_type::assign_(a);
882        return *this;
883    }
884
885    sc_subref<X> &operator = (const sc_subref_r<X> &a);
886    sc_subref<X> &operator = (const sc_subref<X> &a);
887
888    sc_subref<X> &
889    operator = (const char *a)
890    {
891        base_type::assign_(a);
892        return *this;
893    }
894
895    sc_subref<X> &
896    operator = (const bool *a)
897    {
898        base_type::assign_(a);
899        return *this;
900    }
901
902    sc_subref<X> &
903    operator = (const sc_logic *a)
904    {
905        base_type::assign_(a);
906        return *this;
907    }
908
909    sc_subref<X> &
910    operator = (const sc_unsigned &a)
911    {
912        base_type::assign_(a);
913        return *this;
914    }
915
916    sc_subref<X> &
917    operator = (const sc_signed &a)
918    {
919        base_type::assign_(a);
920        return *this;
921    }
922
923    sc_subref<X> &
924    operator = (const sc_uint_base &a)
925    {
926        base_type::assign_(a);
927        return *this;
928    }
929
930    sc_subref<X> &
931    operator = (const sc_int_base &a)
932    {
933        base_type::assign_(a);
934        return *this;
935    }
936
937    sc_subref<X> &
938    operator = (unsigned long a)
939    {
940        base_type::assign_(a);
941        return *this;
942    }
943
944    sc_subref<X> &
945    operator = (long a)
946    {
947        base_type::assign_(a);
948        return *this;
949    }
950
951    sc_subref<X> &
952    operator = (unsigned int a)
953    {
954        base_type::assign_(a);
955        return *this;
956    }
957
958    sc_subref<X> &
959    operator = (int a)
960    {
961        base_type::assign_(a);
962        return *this;
963    }
964
965    sc_subref<X> &
966    operator = (uint64 a)
967    {
968        base_type::assign_(a);
969        return *this;
970    }
971
972    sc_subref<X> &
973    operator = (int64 a)
974    {
975        base_type::assign_(a);
976        return *this;
977    }
978
979    // other methods
980    void scan(::std::istream & =::std::cin);
981
982  private:
983    // Disabled
984    sc_subref();
985};
986
987
988// l-value concatenation operators and functions
989
990template <class T1, class T2>
991inline sc_concref<sc_subref<T1>, sc_bitref<T2> > operator , (
992        sc_subref<T1>, sc_bitref<T2>);
993
994template <class T1, class T2>
995inline sc_concref<sc_subref<T1>, sc_subref<T2> > operator , (
996        sc_subref<T1>, sc_subref<T2>);
997
998template <class T1, class T2, class T3>
999inline sc_concref<sc_subref<T1>, sc_concref<T2, T3> > operator , (
1000        sc_subref<T1>, sc_concref<T2, T3>);
1001
1002template <class T1, class T2>
1003inline sc_concref<sc_subref<T1>, T2> operator , (
1004        sc_subref<T1>, sc_proxy<T2> &);
1005
1006
1007template <class T1, class T2>
1008inline sc_concref<sc_subref<T1>, sc_bitref<T2> > concat(
1009        sc_subref<T1>, sc_bitref<T2>);
1010
1011template <class T1, class T2>
1012inline sc_concref<sc_subref<T1>, sc_subref<T2> > concat(
1013        sc_subref<T1>, sc_subref<T2>);
1014
1015template <class T1, class T2, class T3>
1016inline sc_concref<sc_subref<T1>, sc_concref<T2, T3> > concat(
1017        sc_subref<T1>, sc_concref<T2, T3>);
1018
1019template <class T1, class T2>
1020inline sc_concref<sc_subref<T1>, T2> concat(sc_subref<T1>, sc_proxy<T2> &);
1021
1022
1023template <class T>
1024inline ::std::istream &operator >> (::std::istream &, sc_subref<T>);
1025
1026
1027// ----------------------------------------------------------------------------
1028//  CLASS TEMPLATE : sc_concref_r<X,Y>
1029//
1030//  Proxy class for sc_proxy concatenation (r-value only).
1031// ----------------------------------------------------------------------------
1032
1033template <class X, class Y>
1034class sc_concref_r : public sc_proxy<sc_concref_r<X, Y> >
1035{
1036  public:
1037    typedef typename sc_proxy<sc_concref_r<X, Y> >::value_type value_type;
1038
1039    // constructor
1040    sc_concref_r(const X &left_, const Y &right_, int delete_=0) :
1041        m_left(const_cast<X &>(left_)), m_right(const_cast<Y &>(right_)),
1042          m_delete(delete_), m_refs(*new int(1))
1043    {}
1044
1045    // copy constructor
1046    sc_concref_r(const sc_concref_r<X, Y> &a) :
1047            m_left(a.m_left), m_right(a.m_right),
1048            m_delete(a.m_delete), m_refs(a.m_refs)
1049    { ++ m_refs; }
1050
1051    // destructor
1052    virtual ~sc_concref_r();
1053
1054    // cloning
1055    sc_concref_r<X, Y> *clone() const { return new sc_concref_r<X, Y>(*this); }
1056
1057    // common methods
1058    int length() const { return (m_left.length() + m_right.length()); }
1059
1060    int size() const { return ((length() - 1) / SC_DIGIT_SIZE + 1); }
1061
1062    value_type get_bit(int n) const;
1063    void set_bit(int n, value_type value);
1064
1065    sc_digit get_word(int i) const;
1066    void set_word(int i, sc_digit w);
1067
1068    sc_digit get_cword(int i) const;
1069    void set_cword(int i, sc_digit w);
1070
1071    void clean_tail() { m_left.clean_tail(); m_right.clean_tail(); }
1072
1073    // other methods
1074    bool is_01() const { return (m_left.is_01() && m_right.is_01()); }
1075
1076  protected:
1077    X &m_left;
1078    Y &m_right;
1079    mutable int m_delete;
1080    int &m_refs;
1081
1082  private:
1083    // Disabled
1084    sc_concref_r();
1085    sc_concref_r<X, Y> &operator = (const sc_concref_r<X, Y> &);
1086};
1087
1088
1089// r-value concatenation operators and functions
1090
1091template <class T1, class T2, class T3>
1092inline sc_concref_r<sc_concref_r<T1, T2>,sc_bitref_r<T3> > operator , (
1093        sc_concref_r<T1, T2>, sc_bitref_r<T3>);
1094
1095template <class T1, class T2, class T3>
1096inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > operator , (
1097        sc_concref_r<T1, T2>, sc_subref_r<T3>);
1098
1099template <class T1, class T2, class T3, class T4>
1100inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > operator , (
1101        sc_concref_r<T1, T2>, sc_concref_r<T3, T4>);
1102
1103template <class T1, class T2, class T3>
1104inline sc_concref_r<sc_concref_r<T1, T2>, T3> operator , (
1105        sc_concref_r<T1, T2>, const sc_proxy<T3> &);
1106
1107template <class T1, class T2>
1108inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> operator , (
1109        sc_concref_r<T1, T2>, const char *);
1110
1111template <class T1, class T2>
1112inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > operator , (
1113        const char *, sc_concref_r<T1, T2>);
1114
1115template <class T1, class T2>
1116inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> operator , (
1117        sc_concref_r<T1, T2>, const sc_logic &);
1118
1119template <class T1, class T2>
1120inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > operator , (
1121        const sc_logic &, sc_concref_r<T1, T2>);
1122
1123template <class T1, class T2>
1124inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> operator , (
1125        sc_concref_r<T1, T2>, bool);
1126
1127template <class T1, class T2>
1128inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > operator , (
1129        bool, sc_concref_r<T1, T2>);
1130
1131
1132template <class T1, class T2, class T3>
1133inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > concat(
1134        sc_concref_r<T1, T2>, sc_bitref_r<T3>);
1135
1136template <class T1, class T2, class T3>
1137inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > concat(
1138        sc_concref_r<T1, T2>, sc_subref_r<T3>);
1139
1140template <class T1, class T2, class T3, class T4>
1141inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > concat(
1142        sc_concref_r<T1, T2>, sc_concref_r<T3, T4>);
1143
1144template <class T1, class T2, class T3>
1145inline sc_concref_r<sc_concref_r<T1, T2>, T3> concat(
1146        sc_concref_r<T1, T2>, const sc_proxy<T3> &);
1147
1148template <class T1, class T2>
1149inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> concat(
1150        sc_concref_r<T1, T2>, const char *);
1151
1152template <class T1, class T2>
1153inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > concat(
1154        const char *, sc_concref_r<T1, T2>);
1155
1156template <class T1, class T2>
1157inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> concat(
1158        sc_concref_r<T1, T2>, const sc_logic &);
1159
1160template <class T1, class T2>
1161inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > concat(
1162        const sc_logic &, sc_concref_r<T1, T2>);
1163
1164template <class T1, class T2>
1165inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> concat(
1166        sc_concref_r<T1, T2>, bool);
1167
1168template <class T1, class T2>
1169inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > concat(
1170        bool, sc_concref_r<T1, T2>);
1171
1172
1173template <class T1, class T2, class T3>
1174inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > operator , (
1175        sc_concref_r<T1, T2>, sc_bitref<T3>);
1176
1177template <class T1, class T2, class T3>
1178inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > operator , (
1179        sc_concref<T1, T2>, sc_bitref_r<T3>);
1180
1181template <class T1, class T2, class T3>
1182inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > operator , (
1183        sc_concref_r<T1, T2>, sc_subref<T3>);
1184
1185template <class T1, class T2, class T3>
1186inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > operator , (
1187        sc_concref<T1, T2>, sc_subref_r<T3>);
1188
1189template <class T1, class T2, class T3, class T4>
1190inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > operator , (
1191        sc_concref_r<T1, T2>, sc_concref<T3, T4>);
1192
1193template <class T1, class T2, class T3, class T4>
1194inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > operator , (
1195        sc_concref<T1, T2>, sc_concref_r<T3, T4>);
1196
1197template <class T1, class T2, class T3>
1198inline sc_concref_r<sc_concref_r<T1, T2>, T3> operator , (
1199        sc_concref<T1, T2>, const sc_proxy<T3> &);
1200
1201template <class T1, class T2, class T3>
1202inline sc_concref_r<sc_concref_r<T1, T2>, T3> operator , (
1203        sc_concref_r<T1, T2>, sc_proxy<T3> &);
1204
1205template <class T1, class T2>
1206inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> operator , (
1207        sc_concref<T1, T2>, const char *);
1208
1209template <class T1, class T2>
1210inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > operator , (
1211        const char *, sc_concref<T1, T2>);
1212
1213template <class T1, class T2>
1214inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> operator , (
1215        sc_concref<T1, T2>, const sc_logic &);
1216
1217template <class T1, class T2>
1218inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > operator , (
1219        const sc_logic &, sc_concref<T1, T2>);
1220
1221template <class T1, class T2>
1222inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> operator , (
1223        sc_concref<T1, T2>, bool);
1224
1225template <class T1, class T2>
1226inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > operator , (
1227        bool, sc_concref<T1, T2>);
1228
1229
1230template <class T1, class T2, class T3>
1231inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > concat(
1232        sc_concref_r<T1, T2>, sc_bitref<T3>);
1233
1234template <class T1, class T2, class T3>
1235inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> > concat(
1236        sc_concref<T1, T2>, sc_bitref_r<T3>);
1237
1238template <class T1, class T2, class T3>
1239inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > concat(
1240        sc_concref_r<T1, T2>, sc_subref<T3>);
1241
1242template <class T1, class T2, class T3>
1243inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> > concat(
1244        sc_concref<T1, T2>, sc_subref_r<T3>);
1245
1246template <class T1, class T2, class T3, class T4>
1247inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > concat(
1248        sc_concref_r<T1, T2>, sc_concref<T3, T4>);
1249
1250template <class T1, class T2, class T3, class T4>
1251inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> > concat(
1252        sc_concref<T1, T2>, sc_concref_r<T3, T4> );
1253
1254template <class T1, class T2, class T3>
1255inline sc_concref_r<sc_concref_r<T1, T2>, T3> concat(
1256        sc_concref<T1, T2>, const sc_proxy<T3> &);
1257
1258template <class T1, class T2, class T3>
1259inline sc_concref_r<sc_concref_r<T1, T2>, T3> concat(
1260        sc_concref_r<T1, T2>, sc_proxy<T3> &);
1261
1262template <class T1, class T2>
1263inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> concat(
1264        sc_concref<T1, T2>, const char *);
1265
1266template <class T1, class T2>
1267inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > concat(
1268        const char *, sc_concref<T1, T2>);
1269
1270template <class T1, class T2>
1271inline sc_concref_r<sc_concref_r<T1, T2>, sc_lv_base> concat(
1272        sc_concref<T1, T2>, const sc_logic &);
1273
1274template <class T1, class T2>
1275inline sc_concref_r<sc_lv_base, sc_concref_r<T1, T2> > concat(
1276        const sc_logic &, sc_concref<T1, T2>);
1277
1278template <class T1, class T2>
1279inline sc_concref_r<sc_concref_r<T1, T2>, sc_bv_base> concat(
1280        sc_concref<T1, T2>, bool);
1281
1282template <class T1, class T2>
1283inline sc_concref_r<sc_bv_base, sc_concref_r<T1, T2> > concat(
1284        bool, sc_concref<T1, T2>);
1285
1286
1287// ----------------------------------------------------------------------------
1288//  CLASS TEMPLATE : sc_concref<X,Y>
1289//
1290//  Proxy class for sc_proxy concatenation (r-value and l-value).
1291// ----------------------------------------------------------------------------
1292
1293template <class X, class Y>
1294class sc_concref : public sc_concref_r<X, Y>
1295{
1296  public:
1297    // typedefs
1298    typedef sc_concref_r<X, Y> base_type;
1299
1300    // constructor
1301    sc_concref(X &left_, Y &right_, int delete_=0) :
1302            sc_concref_r<X, Y>(left_, right_, delete_)
1303    {}
1304
1305    // copy constructor
1306    sc_concref(const sc_concref<X, Y> &a) : sc_concref_r<X, Y>(a) {}
1307
1308    // cloning
1309    sc_concref<X, Y> *clone() const { return new sc_concref<X, Y>(*this); }
1310
1311    // assignment operators
1312    template <class Z>
1313    sc_concref<X, Y> &
1314    operator = (const sc_proxy<Z> &a)
1315    {
1316        base_type::assign_(a);
1317        return *this;
1318    }
1319
1320    sc_concref<X, Y> &
1321    operator = (const sc_concref<X, Y> &a)
1322    {
1323        base_type::assign_(a);
1324        return *this;
1325    }
1326
1327    sc_concref<X, Y> &
1328    operator = (const char *a)
1329    {
1330        base_type::assign_(a);
1331        return *this;
1332    }
1333
1334    sc_concref<X, Y> &
1335    operator = (const bool *a)
1336    {
1337        base_type::assign_(a);
1338        return *this;
1339    }
1340
1341    sc_concref<X, Y> &
1342    operator = (const sc_logic *a)
1343    {
1344        base_type::assign_(a);
1345        return *this;
1346    }
1347
1348    sc_concref<X, Y> &
1349    operator = (const sc_unsigned &a)
1350    {
1351        base_type::assign_(a);
1352        return *this;
1353    }
1354
1355    sc_concref<X, Y> &
1356    operator = (const sc_signed &a)
1357    {
1358        base_type::assign_(a);
1359        return *this;
1360    }
1361
1362    sc_concref<X, Y> &
1363    operator = (const sc_uint_base &a)
1364    {
1365        base_type::assign_(a);
1366        return *this;
1367    }
1368
1369    sc_concref<X, Y> &
1370    operator = (const sc_int_base &a)
1371    {
1372        base_type::assign_(a);
1373        return *this;
1374    }
1375
1376    sc_concref<X, Y> &
1377    operator = (unsigned long a)
1378    {
1379        base_type::assign_(a);
1380        return *this;
1381    }
1382
1383    sc_concref<X, Y> &
1384    operator = (long a)
1385    {
1386        base_type::assign_(a);
1387        return *this;
1388    }
1389
1390    sc_concref<X, Y> &
1391    operator = (unsigned int a)
1392    {
1393        base_type::assign_(a);
1394        return *this;
1395    }
1396
1397    sc_concref<X, Y> &
1398    operator = (int a)
1399    {
1400        base_type::assign_(a);
1401        return *this;
1402    }
1403
1404    sc_concref<X, Y> &
1405    operator = (uint64 a)
1406    {
1407        base_type::assign_(a);
1408        return *this;
1409    }
1410
1411    sc_concref<X, Y> &
1412    operator = (int64 a)
1413    {
1414        base_type::assign_(a);
1415        return *this;
1416    }
1417
1418    // other methods
1419    void scan(::std::istream & =::std::cin);
1420
1421  private:
1422    // Disabled
1423    sc_concref();
1424};
1425
1426
1427// l-value concatenation operators and functions
1428
1429template <class T1, class T2, class T3>
1430inline sc_concref<sc_concref<T1, T2>, sc_bitref<T3> > operator , (
1431        sc_concref<T1, T2>, sc_bitref<T3>);
1432
1433template <class T1, class T2, class T3>
1434inline sc_concref<sc_concref<T1, T2>, sc_subref<T3> > operator , (
1435        sc_concref<T1, T2>, sc_subref<T3>);
1436
1437template <class T1, class T2, class T3, class T4>
1438inline sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> > operator , (
1439        sc_concref<T1, T2>, sc_concref<T3, T4>);
1440
1441template <class T1, class T2, class T3>
1442inline sc_concref<sc_concref<T1, T2>, T3> operator , (
1443        sc_concref<T1, T2>, sc_proxy<T3> &);
1444
1445
1446template <class T1, class T2, class T3>
1447inline sc_concref<sc_concref<T1, T2>, sc_bitref<T3> > concat(
1448        sc_concref<T1, T2>, sc_bitref<T3>);
1449
1450template <class T1, class T2, class T3>
1451inline sc_concref<sc_concref<T1, T2>, sc_subref<T3> > concat(
1452        sc_concref<T1, T2>, sc_subref<T3>);
1453
1454template <class T1, class T2, class T3, class T4>
1455inline sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> > concat(
1456        sc_concref<T1, T2>, sc_concref<T3, T4>);
1457
1458template <class T1, class T2, class T3>
1459inline sc_concref<sc_concref<T1, T2>, T3> concat(
1460        sc_concref<T1, T2>, sc_proxy<T3> &);
1461
1462
1463template <class T1, class T2>
1464inline ::std::istream &operator >> (::std::istream &, sc_concref<T1, T2>);
1465
1466
1467// ----------------------------------------------------------------------------
1468//  CLASS TEMPLATE : sc_proxy<T>
1469//
1470//  Base class template for bit/logic vector classes.
1471//  (Barton/Nackmann implementation)
1472// ----------------------------------------------------------------------------
1473
1474// r-value concatenation operators and functions
1475
1476template <class T1, class T2>
1477inline sc_concref_r<T1, sc_bitref_r<T2> > operator , (
1478        const sc_proxy<T1> &, sc_bitref_r<T2>);
1479
1480template <class T1, class T2>
1481inline sc_concref_r<T1, sc_subref_r<T2> > operator , (
1482        const sc_proxy<T1> &, sc_subref_r<T2>);
1483
1484template <class T1, class T2, class T3>
1485inline sc_concref_r<T1, sc_concref_r<T2, T3> > operator , (
1486        const sc_proxy<T1> &, sc_concref_r<T2, T3>);
1487
1488template <class T1, class T2>
1489inline sc_concref_r<T1, T2> operator , (
1490        const sc_proxy<T1> &, const sc_proxy<T2> &);
1491
1492template <class T>
1493inline sc_concref_r<T, sc_lv_base> operator , (
1494        const sc_proxy<T> &, const char *);
1495
1496template <class T>
1497inline sc_concref_r<sc_lv_base,T> operator , (
1498        const char *, const sc_proxy<T> &);
1499
1500template <class T>
1501inline sc_concref_r<T, sc_lv_base> operator , (
1502        const sc_proxy<T> &, const sc_logic &);
1503
1504template <class T>
1505inline sc_concref_r<sc_lv_base, T> operator , (
1506        const sc_logic &, const sc_proxy<T> &);
1507
1508template <class T>
1509inline sc_concref_r<T, sc_bv_base> operator , (const sc_proxy<T> &, bool);
1510
1511template <class T>
1512inline sc_concref_r<sc_bv_base, T> operator , (bool, const sc_proxy<T> &);
1513
1514
1515template <class T1, class T2>
1516inline sc_concref_r<T1, sc_bitref_r<T2> > concat(
1517        const sc_proxy<T1> &, sc_bitref_r<T2>);
1518
1519template <class T1, class T2>
1520inline sc_concref_r<T1, sc_subref_r<T2> > concat(
1521        const sc_proxy<T1> &, sc_subref_r<T2>);
1522
1523template <class T1, class T2, class T3>
1524inline sc_concref_r<T1, sc_concref_r<T2, T3> > concat(
1525        const sc_proxy<T1> &, sc_concref_r<T2, T3>);
1526
1527template <class T1, class T2>
1528inline sc_concref_r<T1, T2> concat(const sc_proxy<T1> &, const sc_proxy<T2> &);
1529
1530template <class T>
1531inline sc_concref_r<T, sc_lv_base> concat(const sc_proxy<T> &, const char *);
1532
1533template <class T>
1534inline sc_concref_r<sc_lv_base, T> concat(const char *, const sc_proxy<T> &);
1535
1536template <class T>
1537inline sc_concref_r<T, sc_lv_base> concat(
1538        const sc_proxy<T> &, const sc_logic &);
1539
1540template <class T>
1541inline sc_concref_r<sc_lv_base, T> concat(
1542        const sc_logic &, const sc_proxy<T> &);
1543
1544template <class T>
1545inline sc_concref_r<T, sc_bv_base> concat(const sc_proxy<T> &, bool);
1546
1547template <class T>
1548inline sc_concref_r<sc_bv_base, T> concat(bool, const sc_proxy<T> &);
1549
1550
1551template <class T1, class T2>
1552inline sc_concref_r<T1, sc_bitref_r<T2> > operator , (
1553        const sc_proxy<T1> &, sc_bitref<T2>);
1554
1555template <class T1, class T2>
1556inline sc_concref_r<T1, sc_bitref_r<T2> > operator , (
1557        sc_proxy<T1> &, sc_bitref_r<T2>);
1558
1559template <class T1, class T2>
1560inline sc_concref_r<T1, sc_subref_r<T2> > operator , (
1561        const sc_proxy<T1> &, sc_subref<T2>);
1562
1563template <class T1, class T2>
1564inline sc_concref_r<T1, sc_subref_r<T2> > operator , (
1565        sc_proxy<T1> &, sc_subref_r<T2>);
1566
1567template <class T1, class T2, class T3>
1568inline sc_concref_r<T1, sc_concref_r<T2, T3> > operator , (
1569        const sc_proxy<T1> &, sc_concref<T2, T3>);
1570
1571template <class T1, class T2, class T3>
1572inline sc_concref_r<T1, sc_concref_r<T2, T3> > operator , (
1573        sc_proxy<T1> &, sc_concref_r<T2, T3>);
1574
1575template <class T1, class T2>
1576inline sc_concref_r<T1, T2> operator , (const sc_proxy<T1> &, sc_proxy<T2> &);
1577
1578template <class T1, class T2>
1579inline sc_concref_r<T1, T2> operator , (sc_proxy<T1> &, const sc_proxy<T2> &);
1580
1581template <class T>
1582inline sc_concref_r<T, sc_lv_base> operator , (sc_proxy<T> &, const char *);
1583
1584template <class T>
1585inline sc_concref_r<sc_lv_base, T> operator , (const char *, sc_proxy<T> &);
1586
1587template <class T>
1588inline sc_concref_r<T, sc_lv_base> operator , (
1589        sc_proxy<T> &, const sc_logic &);
1590
1591template <class T>
1592inline sc_concref_r<sc_lv_base, T> operator , (
1593        const sc_logic &, sc_proxy<T> &);
1594
1595template <class T>
1596inline sc_concref_r<T, sc_bv_base> operator , (sc_proxy<T> &, bool);
1597
1598template <class T>
1599inline sc_concref_r<sc_bv_base, T> operator , (bool, sc_proxy<T> &);
1600
1601
1602template <class T1, class T2>
1603inline sc_concref_r<T1, sc_bitref_r<T2> > concat(
1604        const sc_proxy<T1> &, sc_bitref<T2>);
1605
1606template <class T1, class T2>
1607inline sc_concref_r<T1, sc_bitref_r<T2> > concat(
1608        sc_proxy<T1> &, sc_bitref_r<T2>);
1609
1610template <class T1, class T2>
1611inline sc_concref_r<T1, sc_subref_r<T2> > concat(
1612        const sc_proxy<T1> &, sc_subref<T2>);
1613
1614template <class T1, class T2>
1615inline sc_concref_r<T1, sc_subref_r<T2> > concat(
1616        sc_proxy<T1> &, sc_subref_r<T2>);
1617
1618template <class T1, class T2, class T3>
1619inline sc_concref_r<T1, sc_concref_r<T2, T3> > concat(
1620        const sc_proxy<T1> &, sc_concref<T2, T3>);
1621
1622template <class T1, class T2, class T3>
1623inline sc_concref_r<T1, sc_concref_r<T2, T3> > concat(
1624        sc_proxy<T1> &, sc_concref_r<T2, T3>);
1625
1626template <class T1, class T2>
1627inline sc_concref_r<T1, T2> concat(const sc_proxy<T1> &, sc_proxy<T2> &);
1628
1629template <class T1, class T2>
1630inline sc_concref_r<T1, T2> concat(sc_proxy<T1> &, const sc_proxy<T2> &);
1631
1632template <class T>
1633inline sc_concref_r<T, sc_lv_base> concat(sc_proxy<T> &, const char *);
1634
1635template <class T>
1636inline sc_concref_r<sc_lv_base, T> concat(const char *, sc_proxy<T> &);
1637
1638template <class T>
1639inline sc_concref_r<T, sc_lv_base> concat(sc_proxy<T> &, const sc_logic &);
1640
1641template <class T>
1642inline sc_concref_r<sc_lv_base, T> concat(const sc_logic &, sc_proxy<T> &);
1643
1644template <class T>
1645inline sc_concref_r<T, sc_bv_base> concat(sc_proxy<T> &, bool);
1646
1647template <class T>
1648inline sc_concref_r<sc_bv_base, T> concat(bool, sc_proxy<T> &);
1649
1650
1651// l-value concatenation operators and functions
1652template <class T1, class T2>
1653inline sc_concref<T1,sc_bitref<T2> > operator , (
1654        sc_proxy<T1> &, sc_bitref<T2>);
1655
1656template <class T1, class T2>
1657inline sc_concref<T1, sc_subref<T2> > operator , (
1658        sc_proxy<T1> &, sc_subref<T2>);
1659
1660template <class T1, class T2, class T3>
1661inline sc_concref<T1, sc_concref<T2, T3> > operator , (
1662        sc_proxy<T1> &, sc_concref<T2, T3>);
1663
1664template <class T1, class T2>
1665inline sc_concref<T1, T2> operator , (sc_proxy<T1> &, sc_proxy<T2> &);
1666
1667
1668template <class T1, class T2>
1669inline sc_concref<T1, sc_bitref<T2> > concat(sc_proxy<T1> &, sc_bitref<T2>);
1670
1671template <class T1, class T2>
1672inline sc_concref<T1, sc_subref<T2> > concat(sc_proxy<T1> &, sc_subref<T2>);
1673
1674template <class T1, class T2, class T3>
1675inline sc_concref<T1, sc_concref<T2, T3> > concat(
1676        sc_proxy<T1> &, sc_concref<T2, T3>);
1677
1678template <class T1, class T2>
1679inline sc_concref<T1, T2> concat(sc_proxy<T1> &, sc_proxy<T2> &);
1680
1681
1682// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
1683
1684// ----------------------------------------------------------------------------
1685//  CLASS TEMPLATE : sc_bitref_r<T>
1686//
1687//  Proxy class for sc_proxy bit selection (r-value only).
1688// ----------------------------------------------------------------------------
1689
1690// bitwise operators and functions
1691
1692// bitwise and
1693template <class T1, class T2>
1694inline sc_logic
1695operator & (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b)
1696{
1697    return sc_logic(sc_logic::and_table[a.value()][b.value()]);
1698}
1699
1700// bitwise or
1701template <class T1, class T2>
1702inline sc_logic
1703operator | (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b)
1704{
1705    return sc_logic(sc_logic::or_table[a.value()][b.value()]);
1706}
1707
1708// bitwise xor
1709template <class T1, class T2>
1710inline sc_logic
1711operator ^ (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b)
1712{
1713    return sc_logic(sc_logic::xor_table[a.value()][b.value()]);
1714}
1715
1716// relational operators and functions
1717template <class T1, class T2>
1718inline bool
1719operator == (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b)
1720{
1721    return ((int)a.value() == b.value());
1722}
1723
1724template <class T1, class T2>
1725inline bool
1726operator != (const sc_bitref_r<T1> &a, const sc_bitref_r<T2> &b)
1727{
1728    return ((int)a.value() != b.value());
1729}
1730
1731// common methods
1732template <class T>
1733inline typename sc_bitref_r<T>::value_type
1734sc_bitref_r<T>::get_bit(int n) const
1735{
1736    if (n == 0) {
1737        return m_obj.get_bit(m_index);
1738    } else {
1739        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
1740        return Log_0;
1741    }
1742}
1743
1744template <class T>
1745inline sc_digit
1746sc_bitref_r<T>::get_word(int n) const
1747{
1748    if (n == 0) {
1749        return (get_bit(n) & SC_DIGIT_ONE);
1750    } else {
1751        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
1752        return 0;
1753    }
1754}
1755
1756template <class T>
1757inline sc_digit
1758sc_bitref_r<T>::get_cword(int n) const
1759{
1760    if (n == 0) {
1761        return ((get_bit(n) & SC_DIGIT_TWO) >> 1);
1762    } else {
1763        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
1764        return 0;
1765    }
1766}
1767
1768// r-value concatenation operators and functions
1769template <class T1, class T2>
1770inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >
1771operator , (sc_bitref_r<T1> a, sc_bitref_r<T2> b)
1772{
1773    return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >(
1774        *a.clone(), *b.clone(), 3);
1775}
1776
1777template <class T1, class T2>
1778inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >
1779operator , (sc_bitref_r<T1> a, sc_subref_r<T2> b)
1780{
1781    return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >(
1782        *a.clone(), *b.clone(), 3);
1783}
1784
1785template <class T1, class T2, class T3>
1786inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >
1787operator , (sc_bitref_r<T1> a, sc_concref_r<T2, T3> b)
1788{
1789    return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >(
1790        *a.clone(), *b.clone(), 3);
1791}
1792
1793template <class T1, class T2>
1794inline sc_concref_r<sc_bitref_r<T1>, T2>
1795operator , (sc_bitref_r<T1> a, const sc_proxy<T2> &b)
1796{
1797    return sc_concref_r<sc_bitref_r<T1>, T2>(
1798        *a.clone(), b.back_cast(), 1);
1799}
1800
1801
1802template <class T1, class T2>
1803inline
1804sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >
1805concat(sc_bitref_r<T1> a, sc_bitref_r<T2> b)
1806{
1807    return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >(
1808        *a.clone(), *b.clone(), 3);
1809}
1810
1811template <class T1, class T2>
1812inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >
1813concat(sc_bitref_r<T1> a, sc_subref_r<T2> b)
1814{
1815    return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >(
1816        *a.clone(), *b.clone(), 3);
1817}
1818
1819template <class T1, class T2, class T3>
1820inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >
1821concat(sc_bitref_r<T1> a, sc_concref_r<T2, T3> b)
1822{
1823    return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >(
1824        *a.clone(), *b.clone(), 3);
1825}
1826
1827template <class T1, class T2>
1828inline sc_concref_r<sc_bitref_r<T1>, T2>
1829concat(sc_bitref_r<T1> a, const sc_proxy<T2> &b)
1830{
1831    return sc_concref_r<sc_bitref_r<T1>, T2>(
1832        *a.clone(), b.back_cast(), 1);
1833}
1834
1835
1836template <class T1, class T2>
1837inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >
1838operator , (sc_bitref_r<T1> a, sc_bitref<T2> b)
1839{
1840    return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >(
1841        *a.clone(), *b.clone(), 3);
1842}
1843
1844template <class T1, class T2>
1845inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >
1846operator , (sc_bitref<T1> a, sc_bitref_r<T2> b)
1847{
1848    return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >(
1849        *a.clone(), *b.clone(), 3);
1850}
1851
1852template <class T1, class T2>
1853inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >
1854operator , (sc_bitref_r<T1> a, sc_subref<T2> b)
1855{
1856    return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >(
1857        *a.clone(), *b.clone(), 3);
1858}
1859
1860template <class T1, class T2>
1861inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >
1862operator , (sc_bitref<T1> a, sc_subref_r<T2> b)
1863{
1864    return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >(
1865        *a.clone(), *b.clone(), 3);
1866}
1867
1868template <class T1, class T2, class T3>
1869inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >
1870operator , (sc_bitref_r<T1> a, sc_concref<T2, T3> b)
1871{
1872    return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >(
1873        *a.clone(), *b.clone(), 3);
1874}
1875
1876template <class T1, class T2, class T3>
1877inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >
1878operator , (sc_bitref<T1> a, sc_concref_r<T2, T3> b)
1879{
1880    return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >(
1881        *a.clone(), *b.clone(), 3);
1882}
1883
1884template <class T1, class T2>
1885inline sc_concref_r<sc_bitref_r<T1>, T2>
1886operator , (sc_bitref<T1> a, const sc_proxy<T2> &b)
1887{
1888    return sc_concref_r<sc_bitref_r<T1>, T2>(
1889        *a.clone(), b.back_cast(), 1);
1890}
1891
1892template <class T1, class T2>
1893inline sc_concref_r<sc_bitref_r<T1>, T2>
1894operator , (sc_bitref_r<T1> a, sc_proxy<T2> &b)
1895{
1896    return sc_concref_r<sc_bitref_r<T1>, T2>(
1897        *a.clone(), b.back_cast(), 1);
1898}
1899
1900
1901template <class T1, class T2>
1902inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >
1903concat(sc_bitref_r<T1> a, sc_bitref<T2> b)
1904{
1905    return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >(
1906        *a.clone(), *b.clone(), 3);
1907}
1908
1909template <class T1, class T2>
1910inline sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >
1911concat(sc_bitref<T1> a, sc_bitref_r<T2> b)
1912{
1913    return sc_concref_r<sc_bitref_r<T1>, sc_bitref_r<T2> >(
1914        *a.clone(), *b.clone(), 3);
1915}
1916
1917template <class T1, class T2>
1918inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >
1919concat(sc_bitref_r<T1> a, sc_subref<T2> b)
1920{
1921    return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >(
1922        *a.clone(), *b.clone(), 3);
1923}
1924
1925template <class T1, class T2>
1926inline sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >
1927concat(sc_bitref<T1> a, sc_subref_r<T2> b)
1928{
1929    return sc_concref_r<sc_bitref_r<T1>, sc_subref_r<T2> >(
1930        *a.clone(), *b.clone(), 3);
1931}
1932
1933template <class T1, class T2, class T3>
1934inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >
1935concat(sc_bitref_r<T1> a, sc_concref<T2, T3> b)
1936{
1937    return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2,T3> >(
1938        *a.clone(), *b.clone(), 3);
1939}
1940
1941template <class T1, class T2, class T3>
1942inline sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2, T3> >
1943concat(sc_bitref<T1> a, sc_concref_r<T2, T3> b)
1944{
1945    return sc_concref_r<sc_bitref_r<T1>, sc_concref_r<T2,T3> >(
1946        *a.clone(), *b.clone(), 3);
1947}
1948
1949template <class T1, class T2>
1950inline sc_concref_r<sc_bitref_r<T1>, T2>
1951concat(sc_bitref<T1> a, const sc_proxy<T2> &b)
1952{
1953    return sc_concref_r<sc_bitref_r<T1>, T2>(*a.clone(), b.back_cast(), 1);
1954}
1955
1956template <class T1, class T2>
1957inline sc_concref_r<sc_bitref_r<T1>, T2>
1958concat(sc_bitref_r<T1> a, sc_proxy<T2> &b)
1959{
1960    return sc_concref_r<sc_bitref_r<T1>, T2>(*a.clone(), b.back_cast(), 1);
1961}
1962
1963
1964// ----------------------------------------------------------------------------
1965//  CLASS TEMPLATE : sc_bitref<X>
1966//
1967//  Proxy class for sc_proxy bit selection (r-value and l-value).
1968// ----------------------------------------------------------------------------
1969
1970// assignment operators
1971template <class X>
1972inline sc_bitref<X> &
1973sc_bitref<X>::operator = (const sc_bitref_r<X> &a)
1974{
1975    this->m_obj.set_bit(this->m_index, a.value());
1976    return *this;
1977}
1978
1979template <class X>
1980inline sc_bitref<X> &
1981sc_bitref<X>::operator = (const sc_bitref<X> &a)
1982{
1983    if (&a != this) {
1984        this->m_obj.set_bit(this->m_index, a.value());
1985    }
1986    return *this;
1987}
1988
1989
1990// bitwise assignment operators
1991template <class X>
1992inline sc_bitref<X> &
1993sc_bitref<X>::operator &= (const sc_bitref_r<X> &a)
1994{
1995    if (&a != this) {
1996        this->m_obj.set_bit(
1997                this->m_index, sc_logic::and_table[this->value()][a.value()]);
1998    }
1999    return *this;
2000}
2001
2002template <class X>
2003inline sc_bitref<X> &
2004sc_bitref<X>::operator &= (const sc_logic &a)
2005{
2006    this->m_obj.set_bit(
2007            this->m_index, sc_logic::and_table[this->value()][a.value()]);
2008    return *this;
2009}
2010
2011
2012template <class X>
2013inline sc_bitref<X> &
2014sc_bitref<X>::operator |= (const sc_bitref_r<X> &a)
2015{
2016    if (&a != this) {
2017        this->m_obj.set_bit(
2018                this->m_index, sc_logic::or_table[this->value()][a.value()]);
2019    }
2020    return *this;
2021}
2022
2023template <class X>
2024inline sc_bitref<X> &
2025sc_bitref<X>::operator |= (const sc_logic &a)
2026{
2027    this->m_obj.set_bit(
2028            this->m_index, sc_logic::or_table[this->value()][a.value()]);
2029    return *this;
2030}
2031
2032
2033template <class X>
2034inline sc_bitref<X> &
2035sc_bitref<X>::operator ^= (const sc_bitref_r<X> &a)
2036{
2037    if (&a != this) {
2038        this->m_obj.set_bit(
2039                this->m_index, sc_logic::xor_table[this->value()][a.value()]);
2040    }
2041    return *this;
2042}
2043
2044template <class X>
2045inline sc_bitref<X> &
2046sc_bitref<X>::operator ^= (const sc_logic &a)
2047{
2048    this->m_obj.set_bit(
2049            this->m_index, sc_logic::xor_table[this->value()][a.value()]);
2050    return *this;
2051}
2052
2053// bitwise operators and functions
2054
2055// bitwise complement
2056template <class X>
2057inline sc_bitref<X> &
2058sc_bitref<X>::b_not()
2059{
2060    this->m_obj.set_bit(this->m_index, sc_logic::not_table[this->value()]);
2061    return *this;
2062}
2063
2064// common methods
2065template <class X>
2066inline void
2067sc_bitref<X>::set_bit(int n, value_type value)
2068{
2069    if (n == 0) {
2070        this->m_obj.set_bit(this->m_index, value);
2071    } else {
2072        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
2073    }
2074}
2075
2076template <class X>
2077inline void
2078sc_bitref<X>::set_word(int n, sc_digit w)
2079{
2080    unsigned int bi = this->m_index % (8 * sizeof(sc_digit));
2081    sc_digit temp;
2082    unsigned int wi = this->m_index / (8 * sizeof(sc_digit));
2083    if (n == 0) {
2084        temp = this->m_obj.get_word(wi);
2085        temp = (temp & ~(1 << bi)) | ((w & 1) << bi);
2086        this->m_obj.set_word(wi, temp);
2087    } else {
2088        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
2089    }
2090}
2091
2092template <class X>
2093inline void
2094sc_bitref<X>::set_cword(int n, sc_digit w)
2095{
2096    unsigned int bi = this->m_index % (8 * sizeof(sc_digit));
2097    sc_digit temp;
2098    unsigned int wi = this->m_index / (8 * sizeof(sc_digit));
2099    if (n == 0) {
2100        temp = this->m_obj.get_cword(wi);
2101        temp = (temp & ~(1 << bi)) | ((w & 1) << bi);
2102        this->m_obj.set_cword(wi, temp);
2103    } else {
2104        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
2105    }
2106}
2107
2108// other methods
2109template <class X>
2110inline void
2111sc_bitref<X>::scan(::std::istream &is)
2112{
2113    char c;
2114    is >> c;
2115    *this = c;
2116}
2117
2118// l-value concatenation operators and functions
2119template <class T1, class T2>
2120inline sc_concref<sc_bitref<T1>, sc_bitref<T2> >
2121operator , (sc_bitref<T1> a, sc_bitref<T2> b)
2122{
2123    return sc_concref<sc_bitref<T1>, sc_bitref<T2> >(
2124            *a.clone(), *b.clone(), 3);
2125}
2126
2127template <class T1, class T2>
2128inline sc_concref<sc_bitref<T1>, sc_subref<T2> >
2129operator , (sc_bitref<T1> a, sc_subref<T2> b)
2130{
2131    return sc_concref<sc_bitref<T1>, sc_subref<T2> >(
2132            *a.clone(), *b.clone(), 3);
2133}
2134
2135template <class T1, class T2, class T3>
2136inline sc_concref<sc_bitref<T1>, sc_concref<T2, T3> >
2137operator , (sc_bitref<T1> a, sc_concref<T2, T3> b)
2138{
2139    return sc_concref<sc_bitref<T1>, sc_concref<T2, T3> >(
2140            *a.clone(), *b.clone(), 3);
2141}
2142
2143template <class T1, class T2>
2144inline sc_concref<sc_bitref<T1>, T2>
2145operator , (sc_bitref<T1> a, sc_proxy<T2> &b)
2146{
2147    return sc_concref<sc_bitref<T1>, T2>(*a.clone(), b.back_cast(), 1);
2148}
2149
2150
2151template <class T1, class T2>
2152inline sc_concref<sc_bitref<T1>, sc_bitref<T2> >
2153concat(sc_bitref<T1> a, sc_bitref<T2> b)
2154{
2155    return sc_concref<sc_bitref<T1>, sc_bitref<T2> >(
2156            *a.clone(), *b.clone(), 3);
2157}
2158
2159template <class T1, class T2>
2160inline sc_concref<sc_bitref<T1>, sc_subref<T2> >
2161concat(sc_bitref<T1> a, sc_subref<T2> b)
2162{
2163    return sc_concref<sc_bitref<T1>, sc_subref<T2> >(
2164            *a.clone(), *b.clone(), 3);
2165}
2166
2167template <class T1, class T2, class T3>
2168inline sc_concref<sc_bitref<T1>, sc_concref<T2, T3> >
2169concat(sc_bitref<T1> a, sc_concref<T2, T3> b)
2170{
2171    return sc_concref<sc_bitref<T1>, sc_concref<T2,T3> >(
2172            *a.clone(), *b.clone(), 3);
2173}
2174
2175template <class T1, class T2>
2176inline sc_concref<sc_bitref<T1>, T2>
2177concat(sc_bitref<T1> a, sc_proxy<T2> &b)
2178{
2179    return sc_concref<sc_bitref<T1>, T2>(*a.clone(), b.back_cast(), 1);
2180}
2181
2182template <class X>
2183inline ::std::istream &
2184operator >> (::std::istream &is, sc_bitref<X> a)
2185{
2186    a.scan(is);
2187    return is;
2188}
2189
2190
2191// ----------------------------------------------------------------------------
2192//  CLASS TEMPLATE : sc_subref_r<X>
2193//
2194//  Proxy class for sc_proxy part selection (r-value only).
2195// ----------------------------------------------------------------------------
2196
2197template <class X>
2198inline void
2199sc_subref_r<X>::check_bounds()
2200{
2201    int len = m_obj.length();
2202    if (m_hi < 0 || m_hi >= len || m_lo < 0 || m_lo >= len) {
2203        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
2204        sc_core::sc_abort(); // can't recover from here
2205    }
2206    if (reversed()) {
2207        m_len = m_lo - m_hi + 1;
2208    } else {
2209        m_len = m_hi - m_lo + 1;
2210    }
2211}
2212
2213// common methods
2214template <class X>
2215inline typename sc_subref_r<X>::value_type
2216sc_subref_r<X>::get_bit(int n) const
2217{
2218    if (reversed()) {
2219        return m_obj.get_bit(m_lo - n);
2220    } else {
2221        return m_obj.get_bit(m_lo + n);
2222    }
2223}
2224
2225template <class X>
2226inline void
2227sc_subref_r<X>::set_bit(int n, value_type value)
2228{
2229    if (reversed()) {
2230        m_obj.set_bit(m_lo - n, value);
2231    } else {
2232        m_obj.set_bit(m_lo + n, value);
2233    }
2234}
2235
2236template <class X>
2237inline sc_digit
2238sc_subref_r<X>::get_word(int i) const
2239{
2240    int n1 = 0;
2241    int n2 = 0;
2242    sc_digit result = 0;
2243    int k = 0;
2244    if (reversed()) {
2245        n1 = m_lo - i * SC_DIGIT_SIZE;
2246        n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1);
2247        for (int n = n1; n > n2; n--) {
2248            result |= (m_obj[n].value() & SC_DIGIT_ONE) << k++;
2249        }
2250    } else {
2251        n1 = m_lo + i * SC_DIGIT_SIZE;
2252        n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1);
2253        for (int n = n1; n < n2; n++) {
2254            result |= (m_obj[n].value() & SC_DIGIT_ONE) << k++;
2255        }
2256    }
2257    return result;
2258}
2259
2260template <class X>
2261inline void
2262sc_subref_r<X>::set_word(int i, sc_digit w)
2263{
2264    int n1 = 0;
2265    int n2 = 0;
2266    int k = 0;
2267    if (reversed()) {
2268        n1 = m_lo - i * SC_DIGIT_SIZE;
2269        n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1);
2270        for (int n = n1; n > n2; n--) {
2271            m_obj.set_bit(n, value_type(
2272                    ((w >> k++) & SC_DIGIT_ONE) |
2273                    (m_obj[n].value() & SC_DIGIT_TWO)));
2274        }
2275    } else {
2276        n1 = m_lo + i * SC_DIGIT_SIZE;
2277        n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1);
2278        for (int n = n1; n < n2; n++) {
2279            m_obj.set_bit(n, value_type(
2280                    ((w >> k++) & SC_DIGIT_ONE) |
2281                    (m_obj[n].value() & SC_DIGIT_TWO)));
2282        }
2283    }
2284}
2285
2286
2287template <class X>
2288inline sc_digit
2289sc_subref_r<X>::get_cword(int i) const
2290{
2291    int n1 = 0;
2292    int n2 = 0;
2293    sc_digit result = 0;
2294    int k = 0;
2295    if (reversed()) {
2296        n1 = m_lo - i * SC_DIGIT_SIZE;
2297        n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1);
2298        for (int n = n1; n > n2; n--) {
2299            result |= ((m_obj[n].value() & SC_DIGIT_TWO) >> 1) << k++;
2300        }
2301    } else {
2302        n1 = m_lo + i * SC_DIGIT_SIZE;
2303        n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1);
2304        for (int n = n1; n < n2; n++) {
2305            result |= ((m_obj[n].value() & SC_DIGIT_TWO) >> 1) << k++;
2306        }
2307    }
2308    return result;
2309}
2310
2311template <class X>
2312inline void
2313sc_subref_r<X>::set_cword(int i, sc_digit w)
2314{
2315    int n1 = 0;
2316    int n2 = 0;
2317    int k = 0;
2318    if (reversed()) {
2319        n1 = m_lo - i * SC_DIGIT_SIZE;
2320        n2 = sc_max(n1 - SC_DIGIT_SIZE, m_hi - 1);
2321        for (int n = n1; n > n2; n--) {
2322            m_obj.set_bit(n, value_type(
2323                    (((w >> k++) & SC_DIGIT_ONE) << 1) |
2324                    (m_obj[n].value() & SC_DIGIT_ONE)));
2325        }
2326    } else {
2327        n1 = m_lo + i * SC_DIGIT_SIZE;
2328        n2 = sc_min(n1 + SC_DIGIT_SIZE, m_hi + 1);
2329        for (int n = n1; n < n2; n++) {
2330            m_obj.set_bit(n, value_type(
2331                    (((w >> k++) & SC_DIGIT_ONE) << 1) |
2332                    (m_obj[n].value() & SC_DIGIT_ONE)));
2333        }
2334    }
2335}
2336
2337// other methods
2338template <class X>
2339inline bool
2340sc_subref_r<X>::is_01() const
2341{
2342    int sz = size();
2343    for (int i = 0; i < sz; ++i) {
2344        if (get_cword(i) != SC_DIGIT_ZERO) {
2345            return false;
2346        }
2347    }
2348    return true;
2349}
2350
2351// r-value concatenation operators and functions
2352template <class T1, class T2>
2353inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >
2354operator , (sc_subref_r<T1> a, sc_bitref_r<T2> b)
2355{
2356    return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >(
2357            *a.clone(), *b.clone(), 3);
2358}
2359
2360template <class T1, class T2>
2361inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >
2362operator , (sc_subref_r<T1> a, sc_subref_r<T2> b)
2363{
2364    return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >(
2365            *a.clone(), *b.clone(), 3);
2366}
2367
2368template <class T1, class T2, class T3>
2369inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >
2370operator , (sc_subref_r<T1> a, sc_concref_r<T2, T3> b)
2371{
2372    return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >(
2373            *a.clone(), *b.clone(), 3);
2374}
2375
2376template <class T1, class T2>
2377inline sc_concref_r<sc_subref_r<T1>, T2>
2378operator , (sc_subref_r<T1> a, const sc_proxy<T2> &b)
2379{
2380    return sc_concref_r<sc_subref_r<T1>, T2>(
2381            *a.clone(), b.back_cast(), 1);
2382}
2383
2384
2385template <class T1, class T2>
2386inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >
2387concat(sc_subref_r<T1> a, sc_bitref_r<T2> b)
2388{
2389    return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >(
2390            *a.clone(), *b.clone(), 3);
2391}
2392
2393template <class T1, class T2>
2394inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >
2395concat(sc_subref_r<T1> a, sc_subref_r<T2> b)
2396{
2397    return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >(
2398            *a.clone(), *b.clone(), 3);
2399}
2400
2401template <class T1, class T2, class T3>
2402inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >
2403concat(sc_subref_r<T1> a, sc_concref_r<T2, T3> b)
2404{
2405    return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >(
2406            *a.clone(), *b.clone(), 3);
2407}
2408
2409template <class T1, class T2>
2410inline sc_concref_r<sc_subref_r<T1>, T2>
2411concat(sc_subref_r<T1> a, const sc_proxy<T2> &b)
2412{
2413    return sc_concref_r<sc_subref_r<T1>, T2>(*a.clone(), b.back_cast(), 1);
2414}
2415
2416
2417template <class T1, class T2>
2418inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >
2419operator , (sc_subref_r<T1> a, sc_bitref<T2> b)
2420{
2421    return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >(
2422            *a.clone(), *b.clone(), 3);
2423}
2424
2425template <class T1, class T2>
2426inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >
2427operator , (sc_subref<T1> a, sc_bitref_r<T2> b)
2428{
2429    return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >(
2430            *a.clone(), *b.clone(), 3);
2431}
2432
2433template <class T1, class T2>
2434inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >
2435operator , (sc_subref_r<T1> a, sc_subref<T2> b)
2436{
2437    return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >(
2438        *a.clone(), *b.clone(), 3);
2439}
2440
2441template <class T1, class T2>
2442inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >
2443operator , (sc_subref<T1> a, sc_subref_r<T2> b)
2444{
2445    return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >(
2446        *a.clone(), *b.clone(), 3);
2447}
2448
2449template <class T1, class T2, class T3>
2450inline
2451sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >
2452operator , (sc_subref_r<T1> a, sc_concref<T2, T3> b)
2453{
2454    return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >(
2455        *a.clone(), *b.clone(), 3);
2456}
2457
2458template <class T1, class T2, class T3>
2459inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >
2460operator , (sc_subref<T1> a, sc_concref_r<T2, T3> b)
2461{
2462    return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >(
2463        *a.clone(), *b.clone(), 3);
2464}
2465
2466template <class T1, class T2>
2467inline sc_concref_r<sc_subref_r<T1>, T2>
2468operator , (sc_subref<T1> a, const sc_proxy<T2> &b)
2469{
2470    return sc_concref_r<sc_subref_r<T1>, T2>(*a.clone(), b.back_cast(), 1);
2471}
2472
2473template <class T1, class T2>
2474inline sc_concref_r<sc_subref_r<T1>, T2>
2475operator , (sc_subref_r<T1> a, sc_proxy<T2> &b)
2476{
2477    return sc_concref_r<sc_subref_r<T1>, T2>(*a.clone(), b.back_cast(), 1);
2478}
2479
2480
2481template <class T1, class T2>
2482inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >
2483concat(sc_subref_r<T1> a, sc_bitref<T2> b)
2484{
2485    return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >(
2486            *a.clone(), *b.clone(), 3);
2487}
2488
2489template <class T1, class T2>
2490inline sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >
2491concat(sc_subref<T1> a, sc_bitref_r<T2> b)
2492{
2493    return sc_concref_r<sc_subref_r<T1>, sc_bitref_r<T2> >(
2494            *a.clone(), *b.clone(), 3);
2495}
2496
2497template <class T1, class T2>
2498inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >
2499concat(sc_subref_r<T1> a, sc_subref<T2> b)
2500{
2501    return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >(
2502            *a.clone(), *b.clone(), 3);
2503}
2504
2505template <class T1, class T2>
2506inline sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >
2507concat(sc_subref<T1> a, sc_subref_r<T2> b)
2508{
2509    return sc_concref_r<sc_subref_r<T1>, sc_subref_r<T2> >(
2510            *a.clone(), *b.clone(), 3);
2511}
2512
2513template <class T1, class T2, class T3>
2514inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >
2515concat(sc_subref_r<T1> a, sc_concref<T2, T3> b)
2516{
2517    return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >(
2518            *a.clone(), *b.clone(), 3);
2519}
2520
2521template <class T1, class T2, class T3>
2522inline sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >
2523concat(sc_subref<T1> a, sc_concref_r<T2, T3> b)
2524{
2525    return sc_concref_r<sc_subref_r<T1>, sc_concref_r<T2, T3> >(
2526            *a.clone(), *b.clone(), 3);
2527}
2528
2529template <class T1, class T2>
2530inline sc_concref_r<sc_subref_r<T1>, T2>
2531concat(sc_subref<T1> a, const sc_proxy<T2> &b)
2532{
2533    return sc_concref_r<sc_subref_r<T1>, T2>(*a.clone(), b.back_cast(), 1);
2534}
2535
2536template <class T1, class T2>
2537inline sc_concref_r<sc_subref_r<T1>, T2>
2538concat(sc_subref_r<T1> a, sc_proxy<T2> &b)
2539{
2540    return sc_concref_r<sc_subref_r<T1>, T2>(*a.clone(), b.back_cast(), 1);
2541}
2542
2543
2544// ----------------------------------------------------------------------------
2545//  CLASS TEMPLATE : sc_subref<X>
2546//
2547//  Proxy class for sc_proxy part selection (r-value and l-value).
2548// ----------------------------------------------------------------------------
2549
2550// assignment operators
2551// sc_subref<X>::operator = ( const sc_subref_r<X>& ) in sc_lv_base.h
2552// sc_subref<X>::operator = ( const sc_subref<X>& )   in sc_lv_base.h
2553
2554// other methods
2555template <class T>
2556inline void
2557sc_subref<T>::scan(::std::istream &is)
2558{
2559    std::string s;
2560    is >> s;
2561    *this = s.c_str();
2562}
2563
2564// l-value concatenation operators and functions
2565template <class T1, class T2>
2566inline
2567sc_concref<sc_subref<T1>, sc_bitref<T2> >
2568operator , (sc_subref<T1> a, sc_bitref<T2> b)
2569{
2570    return sc_concref<sc_subref<T1>, sc_bitref<T2> >(
2571            *a.clone(), *b.clone(), 3);
2572}
2573
2574template <class T1, class T2>
2575inline sc_concref<sc_subref<T1>, sc_subref<T2> >
2576operator , (sc_subref<T1> a, sc_subref<T2> b)
2577{
2578    return sc_concref<sc_subref<T1>, sc_subref<T2> >(
2579            *a.clone(), *b.clone(), 3);
2580}
2581
2582template <class T1, class T2, class T3>
2583inline sc_concref<sc_subref<T1>, sc_concref<T2,T3> >
2584operator , (sc_subref<T1> a, sc_concref<T2, T3> b)
2585{
2586    return sc_concref<sc_subref<T1>, sc_concref<T2, T3> >(
2587            *a.clone(), *b.clone(), 3);
2588}
2589
2590template <class T1, class T2>
2591inline sc_concref<sc_subref<T1>, T2>
2592operator , (sc_subref<T1> a, sc_proxy<T2> &b)
2593{
2594    return sc_concref<sc_subref<T1>, T2>(*a.clone(), b.back_cast(), 1);
2595}
2596
2597
2598template <class T1, class T2>
2599inline sc_concref<sc_subref<T1>, sc_bitref<T2> >
2600concat(sc_subref<T1> a, sc_bitref<T2> b)
2601{
2602    return sc_concref<sc_subref<T1>, sc_bitref<T2> >(
2603            *a.clone(), *b.clone(), 3);
2604}
2605
2606template <class T1, class T2>
2607inline sc_concref<sc_subref<T1>, sc_subref<T2> >
2608concat(sc_subref<T1> a, sc_subref<T2> b)
2609{
2610    return sc_concref<sc_subref<T1>, sc_subref<T2> >(
2611            *a.clone(), *b.clone(), 3);
2612}
2613
2614template <class T1, class T2, class T3>
2615inline sc_concref<sc_subref<T1>, sc_concref<T2, T3> >
2616concat(sc_subref<T1> a, sc_concref<T2, T3> b)
2617{
2618    return sc_concref<sc_subref<T1>, sc_concref<T2, T3> >(
2619            *a.clone(), *b.clone(), 3);
2620}
2621
2622template <class T1, class T2>
2623inline sc_concref<sc_subref<T1>, T2>
2624concat(sc_subref<T1> a, sc_proxy<T2> &b)
2625{
2626    return sc_concref<sc_subref<T1>, T2>(*a.clone(), b.back_cast(), 1);
2627}
2628
2629template <class X>
2630inline ::std::istream &
2631operator >> (::std::istream &is, sc_subref<X> a)
2632{
2633    a.scan(is);
2634    return is;
2635}
2636
2637// ----------------------------------------------------------------------------
2638//  CLASS TEMPLATE : sc_concref_r<X,Y>
2639//
2640//  Proxy class for sc_proxy concatenation (r-value only).
2641// ----------------------------------------------------------------------------
2642
2643// destructor
2644template <class X, class Y>
2645inline sc_concref_r<X, Y>::~sc_concref_r()
2646{
2647    if (--m_refs == 0) {
2648        delete &m_refs;
2649        if (m_delete == 0) {
2650            return;
2651        }
2652        if (m_delete & 1) {
2653            delete &m_left;
2654        }
2655        if (m_delete & 2) {
2656            delete &m_right;
2657        }
2658    }
2659}
2660
2661// common methods
2662template <class X, class Y>
2663inline typename sc_concref_r<X, Y>::value_type
2664sc_concref_r<X, Y>::get_bit(int n) const
2665{
2666    int r_len = m_right.length();
2667    if (n < r_len) {
2668        return value_type(m_right.get_bit(n));
2669    } else if (n < r_len + m_left.length()) {
2670        return value_type(m_left.get_bit(n - r_len));
2671    } else {
2672        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
2673        return Log_0;
2674    }
2675}
2676
2677template <class X, class Y>
2678inline void
2679sc_concref_r<X, Y>::set_bit(int n, value_type v)
2680{
2681    int r_len = m_right.length();
2682    if (n < r_len) {
2683        m_right.set_bit(n, typename Y::value_type(v));
2684    } else if (n < r_len + m_left.length()) {
2685        m_left.set_bit(n - r_len, typename X::value_type(v));
2686    } else {
2687        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
2688    }
2689}
2690
2691template <class X, class Y>
2692inline sc_digit
2693sc_concref_r<X, Y>::get_word(int i) const
2694{
2695    if (i < 0 || i >= size()) {
2696        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
2697    }
2698    // 0 <= i < size()
2699    Y &r = m_right;
2700    int r_len = r.length();
2701    int border = r_len / SC_DIGIT_SIZE;
2702    if (i < border) {
2703        return r.get_word(i);
2704    }
2705    // border <= i < size()
2706    X& l = m_left;
2707    int shift = r_len % SC_DIGIT_SIZE;
2708    int j = i - border;
2709    if (shift == 0) {
2710        return l.get_word(j);
2711    }
2712    // border <= i < size() && shift != 0
2713    int nshift = SC_DIGIT_SIZE - shift;
2714    if (i == border) {
2715        sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift;
2716        return ((r.get_word(i) & rl_mask) | (l.get_word(0) << shift));
2717    }
2718    // border < i < size() && shift != 0
2719    if (j < l.size())
2720        return ((l.get_word(j - 1) >> nshift) | (l.get_word(j) << shift));
2721    else
2722        return (l.get_word(j - 1) >> nshift);
2723}
2724
2725template <class X, class Y>
2726inline void
2727sc_concref_r<X, Y>::set_word(int i, sc_digit w)
2728{
2729    if (i < 0 || i >= size()) {
2730        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
2731    }
2732    // 0 <= i < size()
2733    Y &r = m_right;
2734    int r_len = r.length();
2735    int border = r_len / SC_DIGIT_SIZE;
2736    if (i < border) {
2737        r.set_word(i, w);
2738        return;
2739    }
2740    // border <= i < size()
2741    X &l = m_left;
2742    int shift = r_len % SC_DIGIT_SIZE;
2743    int j = i - border;
2744    if (shift == 0) {
2745        l.set_word(j, w);
2746        return;
2747    }
2748    // border <= i < size() && shift != 0
2749    int nshift = SC_DIGIT_SIZE - shift;
2750    sc_digit lh_mask = ~SC_DIGIT_ZERO << nshift;
2751    if (i == border) {
2752        sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift;
2753        r.set_word(i, w & rl_mask);
2754        l.set_word(0, (l.get_word(0) & lh_mask) | (w >> shift));
2755        return;
2756    }
2757    // border < i < size() && shift != 0
2758    sc_digit ll_mask = ~SC_DIGIT_ZERO >> shift;
2759    l.set_word(j - 1, (l.get_word(j - 1) & ll_mask) | (w << nshift));
2760    if (j < l.size())
2761        l.set_word(j, (l.get_word(j) & lh_mask) | (w >> shift));
2762}
2763
2764template <class X, class Y>
2765inline sc_digit
2766sc_concref_r<X, Y>::get_cword(int i) const
2767{
2768    if (i < 0 || i >= size()) {
2769        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
2770    }
2771    // 0 <= i < size()
2772    Y &r = m_right;
2773    int r_len = r.length();
2774    int border = r_len / SC_DIGIT_SIZE;
2775    if (i < border) {
2776        return r.get_cword(i);
2777    }
2778    // border <= i < size()
2779    X &l = m_left;
2780    int shift = r_len % SC_DIGIT_SIZE;
2781    int j = i - border;
2782    if (shift == 0) {
2783        return l.get_cword(j);
2784    }
2785    // border <= i < size() && shift != 0
2786    int nshift = SC_DIGIT_SIZE - shift;
2787    if (i == border) {
2788        sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift;
2789        return ((r.get_cword(i) & rl_mask) | (l.get_cword(0) << shift));
2790    }
2791    // border < i < size() && shift != 0
2792    if (j < l.size())
2793        return ((l.get_cword(j - 1) >> nshift) | (l.get_cword(j) << shift));
2794    else
2795        return (l.get_cword( j - 1 ) >> nshift);
2796}
2797
2798template <class X, class Y>
2799inline void
2800sc_concref_r<X, Y>::set_cword(int i, sc_digit w)
2801{
2802    if (i < 0 || i >= size()) {
2803        SC_REPORT_ERROR(sc_core::SC_ID_OUT_OF_BOUNDS_, 0);
2804    }
2805    // 0 <= i < size()
2806    Y &r = m_right;
2807    int r_len = r.length();
2808    int border = r_len / SC_DIGIT_SIZE;
2809    if (i < border) {
2810        r.set_cword(i, w);
2811        return;
2812    }
2813    // border <= i < size()
2814    X &l = m_left;
2815    int shift = r_len % SC_DIGIT_SIZE;
2816    int j = i - border;
2817    if (shift == 0) {
2818        l.set_cword(j, w);
2819        return;
2820    }
2821    // border <= i < size() && shift != 0
2822    int nshift = SC_DIGIT_SIZE - shift;
2823    sc_digit lh_mask = ~SC_DIGIT_ZERO << nshift;
2824    if (i == border) {
2825        sc_digit rl_mask = ~SC_DIGIT_ZERO >> nshift;
2826        r.set_cword(i, w & rl_mask);
2827        l.set_cword(0, (l.get_cword(0) & lh_mask) | (w >> shift));
2828        return;
2829    }
2830    // border < i < size() && shift != 0
2831    sc_digit ll_mask = ~SC_DIGIT_ZERO >> shift;
2832    l.set_cword(j - 1, (l.get_cword(j - 1) & ll_mask) | (w << nshift));
2833    if (j < l.size())
2834        l.set_cword(j, (l.get_cword(j) & lh_mask) | (w >> shift));
2835}
2836
2837// r-value concatenation operators and functions
2838template <class T1, class T2, class T3>
2839inline sc_concref_r<sc_concref_r<T1, T2>,sc_bitref_r<T3> >
2840operator , (sc_concref_r<T1, T2> a, sc_bitref_r<T3> b)
2841{
2842    return sc_concref_r<sc_concref_r<T1, T2>,sc_bitref_r<T3> >(
2843            *a.clone(), *b.clone(), 3);
2844}
2845
2846template <class T1, class T2, class T3>
2847inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >
2848operator , (sc_concref_r<T1, T2> a, sc_subref_r<T3> b)
2849{
2850    return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >(
2851            *a.clone(), *b.clone(), 3);
2852}
2853
2854template <class T1, class T2, class T3, class T4>
2855inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >
2856operator , (sc_concref_r<T1, T2> a, sc_concref_r<T3, T4> b)
2857{
2858    return sc_concref_r<sc_concref_r<T1, T2>,sc_concref_r<T3, T4> >(
2859            *a.clone(), *b.clone(), 3);
2860}
2861
2862template <class T1, class T2, class T3>
2863inline sc_concref_r<sc_concref_r<T1, T2>, T3>
2864operator , (sc_concref_r<T1, T2> a, const sc_proxy<T3> &b)
2865{
2866    return sc_concref_r<sc_concref_r<T1, T2>, T3>(
2867            *a.clone(), b.back_cast(), 1);
2868}
2869
2870
2871template <class T1, class T2, class T3>
2872inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >
2873concat(sc_concref_r<T1, T2> a, sc_bitref_r<T3> b)
2874{
2875    return sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >(
2876            *a.clone(), *b.clone(), 3);
2877}
2878
2879template <class T1, class T2, class T3>
2880inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >
2881concat(sc_concref_r<T1, T2> a, sc_subref_r<T3> b)
2882{
2883    return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >(
2884            *a.clone(), *b.clone(), 3);
2885}
2886
2887template <class T1, class T2, class T3, class T4>
2888inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >
2889concat(sc_concref_r<T1, T2> a, sc_concref_r<T3, T4> b)
2890{
2891    return sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >(
2892            *a.clone(), *b.clone(), 3);
2893}
2894
2895template <class T1, class T2, class T3>
2896inline sc_concref_r<sc_concref_r<T1, T2>, T3>
2897concat(sc_concref_r<T1, T2> a, const sc_proxy<T3> &b)
2898{
2899    return sc_concref_r<sc_concref_r<T1, T2>, T3>(
2900            *a.clone(), b.back_cast(), 1);
2901}
2902
2903
2904template <class T1, class T2, class T3>
2905inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >
2906operator , (sc_concref_r<T1, T2> a, sc_bitref<T3> b)
2907{
2908    return sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >(
2909            *a.clone(), *b.clone(), 3);
2910}
2911
2912template <class T1, class T2, class T3>
2913inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >
2914operator , (sc_concref<T1, T2> a, sc_bitref_r<T3> b)
2915{
2916    return sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >(
2917            *a.clone(), *b.clone(), 3);
2918}
2919
2920template <class T1, class T2, class T3>
2921inline
2922sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >
2923operator , (sc_concref_r<T1, T2> a, sc_subref<T3> b)
2924{
2925    return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >(
2926            *a.clone(), *b.clone(), 3);
2927}
2928
2929template <class T1, class T2, class T3>
2930inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >
2931operator , (sc_concref<T1, T2> a, sc_subref_r<T3> b)
2932{
2933    return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >(
2934            *a.clone(), *b.clone(), 3);
2935}
2936
2937template <class T1, class T2, class T3, class T4>
2938inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >
2939operator , (sc_concref_r<T1, T2> a, sc_concref<T3, T4> b)
2940{
2941    return sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >(
2942            *a.clone(), *b.clone(), 3);
2943}
2944
2945template <class T1, class T2, class T3, class T4>
2946inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >
2947operator , (sc_concref<T1, T2> a, sc_concref_r<T3, T4> b)
2948{
2949    return sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >(
2950            *a.clone(), *b.clone(), 3);
2951}
2952
2953template <class T1, class T2, class T3>
2954inline sc_concref_r<sc_concref_r<T1, T2>, T3>
2955operator , (sc_concref<T1, T2> a, const sc_proxy<T3> &b)
2956{
2957    return sc_concref_r<sc_concref_r<T1, T2>, T3>(
2958            *a.clone(), b.back_cast(), 1);
2959}
2960
2961template <class T1, class T2, class T3>
2962inline sc_concref_r<sc_concref_r<T1, T2>, T3>
2963operator , (sc_concref_r<T1, T2> a, sc_proxy<T3> &b)
2964{
2965    return sc_concref_r<sc_concref_r<T1, T2>, T3>(
2966            *a.clone(), b.back_cast(), 1);
2967}
2968
2969
2970template <class T1, class T2, class T3>
2971inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >
2972concat(sc_concref_r<T1, T2> a, sc_bitref<T3> b)
2973{
2974    return sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >(
2975            *a.clone(), *b.clone(), 3);
2976}
2977
2978template <class T1, class T2, class T3>
2979inline sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >
2980concat(sc_concref<T1, T2> a, sc_bitref_r<T3> b)
2981{
2982    return sc_concref_r<sc_concref_r<T1, T2>, sc_bitref_r<T3> >(
2983            *a.clone(), *b.clone(), 3);
2984}
2985
2986template <class T1, class T2, class T3>
2987inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >
2988concat(sc_concref_r<T1, T2> a, sc_subref<T3> b)
2989{
2990    return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >(
2991            *a.clone(), *b.clone(), 3);
2992}
2993
2994template <class T1, class T2, class T3>
2995inline sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >
2996concat(sc_concref<T1, T2> a, sc_subref_r<T3> b)
2997{
2998    return sc_concref_r<sc_concref_r<T1, T2>, sc_subref_r<T3> >(
2999            *a.clone(), *b.clone(), 3);
3000}
3001
3002template <class T1, class T2, class T3, class T4>
3003inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >
3004concat(sc_concref_r<T1, T2> a, sc_concref<T3, T4> b)
3005{
3006    return sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >(
3007            *a.clone(), *b.clone(), 3);
3008}
3009
3010template <class T1, class T2, class T3, class T4>
3011inline sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >
3012concat(sc_concref<T1, T2> a, sc_concref_r<T3, T4> b)
3013{
3014    return sc_concref_r<sc_concref_r<T1, T2>, sc_concref_r<T3, T4> >(
3015            *a.clone(), *b.clone(), 3);
3016}
3017
3018template <class T1, class T2, class T3>
3019inline sc_concref_r<sc_concref_r<T1, T2>, T3>
3020concat(sc_concref<T1, T2> a, const sc_proxy<T3> &b)
3021{
3022    return sc_concref_r<sc_concref_r<T1, T2>, T3>(
3023            *a.clone(), b.back_cast(), 1);
3024}
3025
3026template <class T1, class T2, class T3>
3027inline sc_concref_r<sc_concref_r<T1, T2>, T3>
3028concat(sc_concref_r<T1, T2> a, sc_proxy<T3> &b)
3029{
3030    return sc_concref_r<sc_concref_r<T1, T2>, T3>(
3031            *a.clone(), b.back_cast(), 1);
3032}
3033
3034
3035// ----------------------------------------------------------------------------
3036//  CLASS TEMPLATE : sc_concref<X,Y>
3037//
3038//  Proxy class for sc_proxy concatenation (r-value and l-value).
3039// ----------------------------------------------------------------------------
3040
3041// other methods
3042template <class T1, class T2>
3043inline void
3044sc_concref<T1, T2>::scan(::std::istream &is)
3045{
3046    std::string s;
3047    is >> s;
3048    *this = s.c_str();
3049}
3050
3051// l-value concatenation operators and functions
3052template <class T1, class T2, class T3>
3053inline sc_concref<sc_concref<T1, T2>, sc_bitref<T3> >
3054operator , (sc_concref<T1, T2> a, sc_bitref<T3> b)
3055{
3056    return sc_concref<sc_concref<T1, T2>, sc_bitref<T3> >(
3057            *a.clone(), *b.clone(), 3);
3058}
3059
3060template <class T1, class T2, class T3>
3061inline sc_concref<sc_concref<T1, T2>, sc_subref<T3> >
3062operator , (sc_concref<T1, T2> a, sc_subref<T3>b)
3063{
3064    return sc_concref<sc_concref<T1, T2>, sc_subref<T3> >(
3065            *a.clone(), *b.clone(), 3);
3066}
3067
3068template <class T1, class T2, class T3, class T4>
3069inline sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> >
3070operator , (sc_concref<T1, T2> a, sc_concref<T3, T4> b)
3071{
3072    return sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> >(
3073            *a.clone(), *b.clone(), 3);
3074}
3075
3076template <class T1, class T2, class T3>
3077inline sc_concref<sc_concref<T1, T2>, T3>
3078operator , (sc_concref<T1, T2> a, sc_proxy<T3> &b)
3079{
3080    return sc_concref<sc_concref<T1, T2>, T3>(
3081            *a.clone(), b.back_cast(), 1);
3082}
3083
3084
3085template <class T1, class T2, class T3>
3086inline sc_concref<sc_concref<T1, T2>, sc_bitref<T3> >
3087concat(sc_concref<T1, T2> a, sc_bitref<T3> b)
3088{
3089    return sc_concref<sc_concref<T1, T2>, sc_bitref<T3> >(
3090            *a.clone(), *b.clone(), 3);
3091}
3092
3093template <class T1, class T2, class T3>
3094inline sc_concref<sc_concref<T1, T2>, sc_subref<T3> >
3095concat(sc_concref<T1, T2> a, sc_subref<T3> b)
3096{
3097    return sc_concref<sc_concref<T1, T2>, sc_subref<T3> >(
3098            *a.clone(), *b.clone(), 3);
3099}
3100
3101template <class T1, class T2, class T3, class T4>
3102inline sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> >
3103concat(sc_concref<T1, T2> a, sc_concref<T3, T4> b)
3104{
3105    return sc_concref<sc_concref<T1, T2>, sc_concref<T3, T4> >(
3106            *a.clone(), *b.clone(), 3);
3107}
3108
3109template <class T1, class T2, class T3>
3110inline sc_concref<sc_concref<T1, T2>, T3>
3111concat(sc_concref<T1, T2> a, sc_proxy<T3> &b)
3112{
3113    return sc_concref<sc_concref<T1, T2>, T3>(
3114            *a.clone(), b.back_cast(), 1);
3115}
3116
3117template <class X, class Y>
3118inline ::std::istream &
3119operator >> (::std::istream &is, sc_concref<X, Y> a)
3120{
3121    a.scan(is);
3122    return is;
3123}
3124
3125
3126// ----------------------------------------------------------------------------
3127//  CLASS TEMPLATE : sc_proxy<T>
3128//
3129//  Base class template for bit/logic vector classes.
3130//  (Barton/Nackmann implementation)
3131// ----------------------------------------------------------------------------
3132
3133// r-value concatenation operators and functions
3134
3135template <class T1, class T2>
3136inline sc_concref_r<T1, sc_bitref_r<T2> >
3137operator , (const sc_proxy<T1> &a, sc_bitref_r<T2> b)
3138{
3139    return sc_concref_r<T1, sc_bitref_r<T2> >(
3140            a.back_cast(), *b.clone(), 2);
3141}
3142
3143template <class T1, class T2>
3144inline sc_concref_r<T1, sc_subref_r<T2> >
3145operator , (const sc_proxy<T1> &a, sc_subref_r<T2> b)
3146{
3147    return sc_concref_r<T1, sc_subref_r<T2> >(
3148            a.back_cast(), *b.clone(), 2);
3149}
3150
3151template <class T1, class T2, class T3>
3152inline sc_concref_r<T1, sc_concref_r<T2, T3> >
3153operator , (const sc_proxy<T1> &a, sc_concref_r<T2, T3> b)
3154{
3155    return sc_concref_r<T1, sc_concref_r<T2, T3> >(
3156            a.back_cast(), *b.clone(), 2);
3157}
3158
3159template <class T1, class T2>
3160inline sc_concref_r<T1, T2>
3161operator , (const sc_proxy<T1> &a, const sc_proxy<T2> &b)
3162{
3163    return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast());
3164}
3165
3166
3167template <class T1, class T2>
3168inline sc_concref_r<T1, sc_bitref_r<T2> >
3169concat(const sc_proxy<T1> &a, sc_bitref_r<T2> b)
3170{
3171    return sc_concref_r<T1, sc_bitref_r<T2> >(a.back_cast(), *b.clone(), 2);
3172}
3173
3174template <class T1, class T2>
3175inline sc_concref_r<T1, sc_subref_r<T2> >
3176concat(const sc_proxy<T1> &a, sc_subref_r<T2> b)
3177{
3178    return sc_concref_r<T1, sc_subref_r<T2> >(a.back_cast(), *b.clone(), 2);
3179}
3180
3181template <class T1, class T2, class T3>
3182inline sc_concref_r<T1, sc_concref_r<T2, T3> >
3183concat(const sc_proxy<T1> &a, sc_concref_r<T2, T3> b )
3184{
3185    return sc_concref_r<T1, sc_concref_r<T2, T3> >(
3186            a.back_cast(), *b.clone(), 2);
3187}
3188
3189template <class T1, class T2>
3190inline sc_concref_r<T1, T2>
3191concat(const sc_proxy<T1> &a, const sc_proxy<T2> &b)
3192{
3193    return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast());
3194}
3195
3196
3197template <class T1, class T2>
3198inline sc_concref_r<T1, sc_bitref_r<T2> >
3199operator , (const sc_proxy<T1> &a, sc_bitref<T2> b)
3200{
3201    return sc_concref_r<T1, sc_bitref_r<T2> >(a.back_cast(), *b.clone(), 2);
3202}
3203
3204template <class T1, class T2>
3205inline sc_concref_r<T1, sc_bitref_r<T2> >
3206operator , (sc_proxy<T1> &a, sc_bitref_r<T2> b)
3207{
3208    return sc_concref_r<T1, sc_bitref_r<T2> >(a.back_cast(), *b.clone(), 2);
3209}
3210
3211template <class T1, class T2>
3212inline sc_concref_r<T1, sc_subref_r<T2> >
3213operator , (const sc_proxy<T1> &a, sc_subref<T2> b)
3214{
3215    return sc_concref_r<T1, sc_subref_r<T2> >(a.back_cast(), *b.clone(), 2);
3216}
3217
3218template <class T1, class T2>
3219inline sc_concref_r<T1, sc_subref_r<T2> >
3220operator , (sc_proxy<T1> &a, sc_subref_r<T2> b)
3221{
3222    return sc_concref_r<T1, sc_subref_r<T2> >(a.back_cast(), *b.clone(), 2);
3223}
3224
3225template <class T1, class T2, class T3>
3226inline sc_concref_r<T1, sc_concref_r<T2, T3> >
3227operator , (const sc_proxy<T1> &a, sc_concref<T2, T3> b)
3228{
3229    return sc_concref_r<T1, sc_concref_r<T2, T3> >(
3230            a.back_cast(), *b.clone(), 2);
3231}
3232
3233template <class T1, class T2, class T3>
3234inline sc_concref_r<T1, sc_concref_r<T2, T3> >
3235operator , (sc_proxy<T1> &a, sc_concref_r<T2, T3> b)
3236{
3237    return sc_concref_r<T1, sc_concref_r<T2, T3> >(
3238            a.back_cast(), *b.clone(), 2);
3239}
3240
3241template <class T1, class T2>
3242inline sc_concref_r<T1, T2>
3243operator , (const sc_proxy<T1> &a, sc_proxy<T2> &b)
3244{
3245    return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast());
3246}
3247
3248template <class T1, class T2>
3249inline sc_concref_r<T1, T2>
3250operator , (sc_proxy<T1> &a, const sc_proxy<T2> &b)
3251{
3252    return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast());
3253}
3254
3255
3256template <class T1, class T2>
3257inline sc_concref_r<T1, sc_bitref_r<T2> >
3258concat(const sc_proxy<T1> &a, sc_bitref<T2> b)
3259{
3260    return sc_concref_r<T1, sc_bitref_r<T2> >(a.back_cast(), *b.clone(), 2);
3261}
3262
3263template <class T1, class T2>
3264inline sc_concref_r<T1, sc_bitref_r<T2> >
3265concat(sc_proxy<T1> &a, sc_bitref_r<T2> b)
3266{
3267    return sc_concref_r<T1, sc_bitref_r<T2> >(a.back_cast(), *b.clone(), 2);
3268}
3269
3270template <class T1, class T2>
3271inline sc_concref_r<T1, sc_subref_r<T2> >
3272concat(const sc_proxy<T1> &a, sc_subref<T2> b)
3273{
3274    return sc_concref_r<T1, sc_subref_r<T2> >(a.back_cast(), *b.clone(), 2);
3275}
3276
3277template <class T1, class T2>
3278inline sc_concref_r<T1, sc_subref_r<T2> >
3279concat(sc_proxy<T1> &a, sc_subref_r<T2> b)
3280{
3281    return sc_concref_r<T1, sc_subref_r<T2> >(a.back_cast(), *b.clone(), 2);
3282}
3283
3284template <class T1, class T2, class T3>
3285inline sc_concref_r<T1, sc_concref_r<T2, T3> >
3286concat(const sc_proxy<T1> &a, sc_concref<T2, T3> b)
3287{
3288    return sc_concref_r<T1, sc_concref_r<T2, T3> >(
3289            a.back_cast(), *b.clone(), 2);
3290}
3291
3292template <class T1, class T2, class T3>
3293inline sc_concref_r<T1, sc_concref_r<T2, T3> >
3294concat(sc_proxy<T1> &a, sc_concref_r<T2, T3> b)
3295{
3296    return sc_concref_r<T1, sc_concref_r<T2, T3> >(
3297            a.back_cast(), *b.clone(), 2);
3298}
3299
3300template <class T1, class T2>
3301inline sc_concref_r<T1, T2>
3302concat(const sc_proxy<T1> &a, sc_proxy<T2> &b)
3303{
3304    return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast());
3305}
3306
3307template <class T1, class T2>
3308inline sc_concref_r<T1, T2>
3309concat(sc_proxy<T1> &a, const sc_proxy<T2> &b)
3310{
3311    return sc_concref_r<T1, T2>(a.back_cast(), b.back_cast());
3312}
3313
3314
3315// l-value concatenation operators and functions
3316
3317template <class T1, class T2>
3318inline sc_concref<T1, sc_bitref<T2> >
3319operator , (sc_proxy<T1> &a, sc_bitref<T2> b)
3320{
3321    return sc_concref<T1, sc_bitref<T2> >(a.back_cast(), *b.clone(), 2);
3322}
3323
3324template <class T1, class T2>
3325inline sc_concref<T1, sc_subref<T2> >
3326operator , (sc_proxy<T1> &a, sc_subref<T2> b)
3327{
3328    return sc_concref<T1, sc_subref<T2> >(a.back_cast(), *b.clone(), 2);
3329}
3330
3331template <class T1, class T2, class T3>
3332inline sc_concref<T1, sc_concref<T2, T3> >
3333operator , (sc_proxy<T1> &a, sc_concref<T2, T3> b)
3334{
3335    return sc_concref<T1, sc_concref<T2, T3> >(a.back_cast(), *b.clone(), 2);
3336}
3337
3338template <class T1, class T2>
3339inline sc_concref<T1, T2>
3340operator , (sc_proxy<T1> &a, sc_proxy<T2> &b)
3341{
3342    return sc_concref<T1, T2>(a.back_cast(), b.back_cast());
3343}
3344
3345
3346template <class T1, class T2>
3347inline sc_concref<T1, sc_bitref<T2> >
3348concat(sc_proxy<T1> &a, sc_bitref<T2> b)
3349{
3350    return sc_concref<T1, sc_bitref<T2> >(a.back_cast(), *b.clone(), 2);
3351}
3352
3353template <class T1, class T2>
3354inline sc_concref<T1, sc_subref<T2> >
3355concat(sc_proxy<T1> &a, sc_subref<T2> b)
3356{
3357    return sc_concref<T1, sc_subref<T2> >(a.back_cast(), *b.clone(), 2);
3358}
3359
3360template <class T1, class T2, class T3>
3361inline sc_concref<T1, sc_concref<T2, T3> >
3362concat(sc_proxy<T1> &a, sc_concref<T2, T3> b)
3363{
3364    return sc_concref<T1, sc_concref<T2, T3> >(a.back_cast(), *b.clone(), 2);
3365}
3366
3367template <class T1, class T2>
3368inline sc_concref<T1, T2>
3369concat(sc_proxy<T1> &a, sc_proxy<T2> &b)
3370{
3371    return sc_concref<T1, T2>(a.back_cast(), b.back_cast());
3372}
3373
3374} // namespace sc_dt
3375
3376// $Log: sc_bit_proxies.h,v $
3377// Revision 1.10  2011/09/05 21:19:53  acg
3378//  Philipp A. Hartmann: added parentheses to expressions to eliminate
3379//  compiler warnings.
3380//
3381// Revision 1.9  2011/09/01 15:03:42  acg
3382//  Philipp A. Hartmann: add parentheses to eliminate compiler warnings.
3383//
3384// Revision 1.8  2011/08/29 18:04:32  acg
3385//  Philipp A. Hartmann: miscellaneous clean ups.
3386//
3387// Revision 1.7  2011/08/24 22:05:40  acg
3388//  Torsten Maehne: initialization changes to remove warnings.
3389//
3390// Revision 1.6  2010/02/22 14:25:43  acg
3391//  Andy Goodrich: removed 'mutable' directive from references, since it
3392//  is not a legal C++ construct.
3393//
3394// Revision 1.5  2009/02/28 00:26:14  acg
3395//  Andy Goodrich: bug fixes.
3396//
3397// Revision 1.4  2007/03/14 17:48:37  acg
3398//  Andy Goodrich: fixed bug.
3399//
3400// Revision 1.3  2007/01/18 19:29:18  acg
3401//  Andy Goodrich: fixed bug in concatenations of bit selects on sc_lv and
3402//  sc_bv types. The offending code was in sc_bitref<X>::set_word and
3403//  sc_bitref<X>::get_word. These methods were not writing the bit they
3404//  represented, but rather writing an entire word whose index was the
3405//  index of the bit they represented. This not only did not write the
3406//  correct bit, but clobbered a word that might not even be in the
3407//  variable the reference was for.
3408//
3409// Revision 1.2  2007/01/17 22:45:08  acg
3410//  Andy Goodrich: fixed sc_bitref<X>::set_bit().
3411//
3412// Revision 1.1.1.1  2006/12/15 20:31:36  acg
3413// SystemC 2.2
3414//
3415// Revision 1.3  2006/01/13 18:53:53  acg
3416// Andy Goodrich: added $Log command so that CVS comments are reproduced in
3417// the source.
3418//
3419
3420#endif // __SYSTEMC_EXT_DT_BIT_SC_BIT_PROXIES_HH__
3421