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