sc_vector.hh revision 12872:037b430699e8
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Authors: Gabe Black
28 */
29
30#ifndef __SYSTEMC_EXT_UTIL_SC_VECTOR_HH__
31#define __SYSTEMC_EXT_UTIL_SC_VECTOR_HH__
32
33#include <stdint.h>
34
35#include <exception>
36#include <iterator>
37#include <vector>
38
39#include "../core/sc_object.hh"
40#include "warn_unimpl.hh"
41
42namespace sc_gem5
43{
44
45// Goop for supporting sc_vector_iter, simplified from the Accellera version.
46
47#if __cplusplus >= 201103L
48
49using std::enable_if;
50using std::remove_const;
51using std::is_same;
52using std::is_const;
53
54#else
55
56template<bool Cond, typename T=void>
57struct enable_if
58{};
59
60template<typename T>
61struct enable_if<true, T>
62{
63    typedef T type;
64};
65
66template <typename T>
67struct remove_const
68{
69    typedef T type;
70};
71template <typename T>
72struct remove_const<const T>
73{
74    typedef T type;
75};
76
77template <typename T, typename U>
78struct is_same
79{
80    static const bool value = false;
81};
82template <typename T>
83struct is_same<T, T>
84{
85    static const bool value = true;
86};
87
88template <typename T>
89struct is_const
90{
91    static const bool value = false;
92};
93template <typename T>
94struct is_const<const T>
95{
96    static const bool value = true;
97};
98
99#endif
100
101template <typename CT, typename T>
102struct is_more_const
103{
104    static const bool value =
105        is_same<typename remove_const<CT>::type,
106                typename remove_const<T>::type>::value &&
107        is_const<CT>::value >= is_const<T>::value;
108};
109
110struct special_result
111{};
112
113template <typename T>
114struct remove_special_fptr
115{};
116
117template <typename T>
118struct remove_special_fptr<special_result & (*)(T)>
119{
120    typedef T type;
121};
122
123#define SC_RPTYPE_(Type) \
124    ::sc_gem5::remove_special_fptr< \
125        ::sc_gem5::special_result & (*) Type>::type::value
126
127#define SC_ENABLE_IF_(Cond) \
128    typename ::sc_gem5::enable_if<SC_RPTYPE_(Cond)>::type * = NULL
129
130} // namespace sc_gem5
131
132namespace sc_core
133{
134
135template <typename T, typename MT>
136class sc_vector_assembly;
137
138template <typename T>
139class sc_vector;
140
141template <typename T, typename MT>
142sc_vector_assembly<T, MT> sc_assemble_vector(
143        sc_vector<T> &, MT(T::* member_ptr));
144
145class sc_vector_base : public sc_object
146{
147  public:
148    typedef size_t size_type;
149
150    virtual const char *kind() const { return "sc_vector"; }
151    size_type size() const;
152    const std::vector<sc_object *> &get_elements() const;
153};
154
155
156/*
157 * Non-standard iterator access adapters. Without using these, the classes as
158 * defined in the standard won't compile because of redundant bind() overloads.
159 */
160
161template <typename Element>
162class sc_direct_access
163{
164  public:
165    typedef Element ElementType;
166    typedef ElementType Type;
167    typedef typename sc_gem5::remove_const<ElementType>::type PlainType;
168
169    typedef sc_direct_access<ElementType> Policy;
170    typedef sc_direct_access<PlainType> NonConstPolicy;
171    typedef sc_direct_access<const PlainType> ConstPolicy;
172
173    sc_direct_access() {}
174    sc_direct_access(const NonConstPolicy &) {}
175
176    template <typename U>
177    sc_direct_access(const U &,
178        SC_ENABLE_IF_((
179            sc_gem5::is_more_const<
180                    ElementType, typename U::Policy::ElementType>
181        ))
182    )
183    {}
184
185    ElementType *
186    get(ElementType *this_) const
187    {
188        return this_;
189    }
190};
191
192template <typename Element, typename Access>
193class sc_member_access
194{
195  public:
196    template <typename, typename>
197    friend class sc_member_access;
198
199    typedef Element ElementType;
200    typedef Access AccessType;
201    typedef AccessType (ElementType::*MemberType);
202    typedef AccessType Type;
203    typedef typename sc_gem5::remove_const<AccessType>::type PlainType;
204    typedef typename sc_gem5::remove_const<ElementType>::type PlainElemType;
205
206    typedef sc_member_access<ElementType, AccessType> Policy;
207    typedef sc_member_access<PlainElemType, PlainType> NonConstPolicy;
208    typedef sc_member_access<const PlainElemType, const PlainType> ConstPolicy;
209
210    sc_member_access(MemberType ptr) : ptr_(ptr) {}
211    sc_member_access(const NonConstPolicy &other) : ptr_(other.ptr_) {}
212
213    AccessType *get(ElementType *this_) const { return &(this_->*ptr_); }
214
215  private:
216    MemberType ptr_;
217};
218
219template <typename Element,
220          typename AccessPolicy=sc_direct_access<Element> >
221class sc_vector_iter :
222        public std::iterator<std::random_access_iterator_tag,
223                             typename AccessPolicy::Type>,
224        private AccessPolicy
225{
226  private:
227    typedef Element ElementType;
228    typedef typename AccessPolicy::Policy Policy;
229    typedef typename AccessPolicy::NonConstPolicy NonConstPolicy;
230    typedef typename AccessPolicy::ConstPolicy ConstPolicy;
231    typedef typename Policy::Type AccessType;
232
233    typedef typename sc_gem5::remove_const<ElementType>::type PlainType;
234    typedef const PlainType ConstPlainType;
235    typedef typename sc_direct_access<PlainType>::ConstPolicy
236        ConstDirectPolicy;
237
238    friend class sc_vector<PlainType>;
239    template <typename, typename>
240    friend class sc_vector_assembly;
241    template <typename, typename>
242    friend class sc_vector_iter;
243
244    typedef std::iterator<std::random_access_iterator_tag, AccessType>
245        BaseType;
246    typedef sc_vector_iter ThisType;
247    typedef sc_vector<PlainType> VectorType;
248    typedef std::vector<void *> StorageType;
249
250    template <typename U>
251    struct SelectIter
252    {
253        typedef typename std::vector<void *>::iterator type;
254    };
255    template <typename U>
256    struct SelectIter<const U>
257    {
258        typedef typename std::vector<void *>::const_iterator type;
259    };
260    typedef typename SelectIter<ElementType>::type RawIterator;
261    typedef sc_vector_iter<ConstPlainType, ConstPolicy> ConstIterator;
262    typedef sc_vector_iter<ConstPlainType, ConstDirectPolicy>
263        ConstDirectIterator;
264
265    RawIterator it_;
266
267    sc_vector_iter(RawIterator it, Policy acc=Policy()) :
268        Policy(acc), it_(it)
269    {}
270
271    Policy const &get_policy() const { return *this; }
272
273  public:
274    // Conforms to Random Access Iterator category.
275    // See ISO/IEC 14882:2003(E), 24.1 [lib.iterator.requirements]
276
277    typedef typename BaseType::difference_type difference_type;
278    typedef typename BaseType::reference reference;
279    typedef typename BaseType::pointer pointer;
280
281    sc_vector_iter() : Policy(), it_() {}
282
283    template <typename It>
284    sc_vector_iter(const It &it,
285        SC_ENABLE_IF_((
286            sc_gem5::is_more_const<
287                ElementType, typename It::Policy::ElementType>
288        ))
289    ) : Policy(it.get_policy()), it_(it.it_)
290    {}
291
292    ThisType &
293    operator ++ ()
294    {
295        ++it_;
296        return *this;
297    }
298    ThisType &
299    operator -- ()
300    {
301        --it_;
302        return *this;
303    }
304    ThisType
305    operator ++ (int)
306    {
307        ThisType old(*this);
308        ++it_;
309        return old;
310    }
311    ThisType
312    operator -- (int)
313    {
314        ThisType old(*this);
315        --it_;
316        return old;
317    }
318
319    ThisType
320    operator + (difference_type n) const
321    {
322        return ThisType(it_ + n, get_policy());
323    }
324    ThisType
325    operator - (difference_type n) const
326    {
327        return ThisType(it_ - n, get_policy());
328    }
329
330    ThisType &
331    operator += (difference_type n)
332    {
333        it_ += n;
334        return *this;
335    }
336
337    ThisType &
338    operator -= (difference_type n)
339    {
340        it_ -= n;
341        return *this;
342    }
343
344    bool
345    operator == (const ConstDirectIterator &other) const
346    {
347        return it_ == other.it_;
348    }
349    bool
350    operator != (const ConstDirectIterator &other) const
351    {
352        return it_ != other.it_;
353    }
354    bool
355    operator <= (const ConstDirectIterator &other) const
356    {
357        return it_ <= other.it_;
358    }
359    bool
360    operator >= (const ConstDirectIterator &other) const
361    {
362        return it_ >= other.it_;
363    }
364    bool
365    operator < (const ConstDirectIterator &other) const
366    {
367        return it_ < other.it_;
368    }
369    bool
370    operator > (const ConstDirectIterator &other) const
371    {
372        return it_ > other.it_;
373    }
374
375    reference
376    operator * () const
377    {
378        return *Policy::get(static_cast<ElementType *>((void *)*it_));
379    }
380    pointer
381    operator -> () const
382    {
383        return Policy::get(static_cast<ElementType *>((void *)*it_));
384    }
385    reference
386    operator [] (difference_type n) const
387    {
388        return *Policy::get(static_cast<ElementType *>((void *)it_[n]));
389    }
390
391    difference_type
392    operator - (ConstDirectIterator const &other) const
393    {
394        return it_ - other.it_;
395    }
396};
397
398template <typename T>
399class sc_vector : public sc_vector_base
400{
401  public:
402    using sc_vector_base::size_type;
403    typedef sc_vector_iter<T> iterator;
404    typedef sc_vector_iter<const T> const_iterator;
405
406    sc_vector() : sc_vector_base()
407    {
408        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
409    }
410    explicit sc_vector(const char *) : sc_vector_base()
411    {
412        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
413    }
414    sc_vector(const char *, size_type) : sc_vector_base()
415    {
416        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
417    }
418    template <typename Creator>
419    sc_vector(const char *, size_type, Creator) : sc_vector_base()
420    {
421        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
422    }
423    virtual ~sc_vector() {}
424
425    void
426    init(size_type)
427    {
428        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
429    }
430    static T *
431    create_element(const char *, size_type)
432    {
433        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
434        return nullptr;
435    }
436
437    template <typename Creator>
438    void
439    init(size_type, Creator)
440    {
441        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
442    }
443
444    T &
445    operator [] (size_type)
446    {
447        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
448        return *(T *)nullptr;
449    }
450    const T &
451    operator [] (size_type) const
452    {
453        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
454        return *(const T *)nullptr;
455    }
456
457    T &
458    at(size_type)
459    {
460        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
461        return *(T *)nullptr;
462    }
463    const T &
464    at(size_type) const
465    {
466        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
467        return *(const T *)nullptr;
468    }
469
470    iterator
471    begin()
472    {
473        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
474        return iterator();
475    }
476    iterator
477    end()
478    {
479        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
480        return iterator();
481    }
482
483    const_iterator
484    begin() const
485    {
486        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
487        return const_iterator();
488    }
489    const_iterator
490    end() const
491    {
492        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
493        return const_iterator();
494    }
495
496    const_iterator
497    cbegin() const
498    {
499        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
500        return const_iterator();
501    }
502    const_iterator
503    cend() const
504    {
505        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
506        return const_iterator();
507    }
508
509    template <typename ContainerType, typename ArgumentType>
510    iterator
511    bind(sc_vector_assembly<ContainerType, ArgumentType>)
512    {
513        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
514        return iterator();
515    }
516
517    template <typename BindableContainer>
518    iterator
519    bind(BindableContainer &)
520    {
521        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
522        return iterator();
523    }
524
525    template <typename BindableIterator>
526    iterator
527    bind(BindableIterator, BindableIterator)
528    {
529        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
530        return iterator();
531    }
532
533    template <typename BindableIterator>
534    iterator
535    bind(BindableIterator, BindableIterator, iterator)
536    {
537        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
538        return iterator();
539    }
540
541    template <typename ContainerType, typename ArgumentType>
542    iterator
543    operator () (sc_vector_assembly<ContainerType, ArgumentType> c)
544    {
545        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
546        return iterator();
547    }
548
549    template <typename ArgumentContainer>
550    iterator
551    operator () (ArgumentContainer &)
552    {
553        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
554        return iterator();
555    }
556
557    template <typename ArgumentIterator>
558    iterator
559    operator () (ArgumentIterator, ArgumentIterator)
560    {
561        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
562        return iterator();
563    }
564
565    template <typename ArgumentIterator>
566    iterator
567    operator () (ArgumentIterator, ArgumentIterator, iterator)
568    {
569        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
570        return iterator();
571    }
572
573  private:
574    // Disabled
575    sc_vector(const sc_vector &) : sc_vector_base() {}
576    sc_vector &operator = (const sc_vector &) { return *this; }
577};
578
579template <typename T, typename MT>
580class sc_vector_assembly
581{
582  public:
583    friend sc_vector_assembly<T, MT> sc_assemble_vector<>(
584            sc_vector<T> &, MT (T::*));
585
586    typedef size_t size_type;
587    typedef sc_vector_iter<T, sc_member_access<T, MT> > iterator;
588    typedef sc_vector_iter<
589        const T, sc_member_access<const T, const MT> > const_iterator;
590    typedef MT (T::*MemberType);
591
592    sc_vector_assembly(const sc_vector_assembly &)
593    {
594        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
595    }
596
597    iterator begin() { return iterator(vec_->begin().it_, ptr_); }
598    iterator end() { return iterator(vec_->end().it_, ptr_); }
599
600    const_iterator
601    cbegin() const
602    {
603        return const_iterator(vec_->begin().it_, ptr_);
604    }
605    const_iterator
606    cend() const
607    {
608        return const_iterator(vec_->end().it_, ptr_);
609    }
610
611    const_iterator
612    begin() const
613    {
614        return const_iterator(vec_->begin().it_, ptr_);
615    }
616    const_iterator
617    end() const
618    {
619        return const_iterator(vec_->end().it_, ptr_);
620    }
621
622    size_type size() const { return vec_->size(); }
623
624    std::vector<sc_object *>
625    get_elements() const
626    {
627        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
628        return *(std::vector<sc_object *> *)nullptr;
629    }
630
631    typename iterator::reference
632    operator [] (size_type i)
633    {
634        return (*vec_)[i].*ptr_;
635    }
636    typename const_iterator::reference
637    operator [] (size_type i) const
638    {
639        return (*vec_)[i].*ptr_;
640    }
641
642    typename iterator::reference
643    at(size_type i)
644    {
645        return vec_->at(i).*ptr_;
646    }
647    typename const_iterator::reference
648    at(size_type i) const
649    {
650        return vec_->at(i).*ptr_;
651    }
652
653    template <typename ContainerType, typename ArgumentType>
654    iterator
655    bind(sc_vector_assembly<ContainerType, ArgumentType>)
656    {
657        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
658        return begin();
659    }
660
661    template <typename BindableContainer>
662    iterator
663    bind(BindableContainer &)
664    {
665        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
666        return begin();
667    }
668
669    template <typename BindableIterator>
670    iterator
671    bind(BindableIterator, BindableIterator)
672    {
673        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
674        return begin();
675    }
676
677    template <typename BindableIterator>
678    iterator
679    bind(BindableIterator, BindableIterator, iterator)
680    {
681        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
682        return begin();
683    }
684
685    template <typename BindableIterator>
686    iterator
687    bind(BindableIterator, BindableIterator, typename sc_vector<T>::iterator)
688    {
689        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
690        return begin();
691    }
692
693    template <typename ContainerType, typename ArgumentType>
694    iterator
695    operator () (sc_vector_assembly<ContainerType, ArgumentType>)
696    {
697        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
698        return begin();
699    }
700
701    template <typename ArgumentContainer>
702    iterator
703    operator () (ArgumentContainer &)
704    {
705        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
706        return begin();
707    }
708
709    template <typename ArgumentIterator>
710    iterator
711    operator () (ArgumentIterator, ArgumentIterator)
712    {
713        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
714        return begin();
715    }
716
717    template <typename ArgumentIterator>
718    iterator
719    operator () (ArgumentIterator, ArgumentIterator, iterator)
720    {
721        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
722        return begin();
723    }
724
725    template <typename ArgumentIterator>
726    iterator
727    operator () (ArgumentIterator, ArgumentIterator,
728                 typename sc_vector<T>::iterator)
729    {
730        sc_utils_warn_unimpl(__PRETTY_FUNCTION__);
731        return begin();
732    }
733
734  private:
735    sc_vector_assembly(sc_vector<T> &v, MemberType ptr) :
736        vec_(&v), ptr_(ptr)
737    {}
738
739    sc_vector<T> *vec_;
740    MemberType ptr_;
741};
742
743template <typename T, typename MT>
744sc_vector_assembly<T, MT>
745sc_assemble_vector(sc_vector<T> &v, MT (T::*ptr))
746{
747    return sc_vector_assembly<T, MT>(v, ptr);
748}
749
750} // namespace sc_core
751
752#endif  //__SYSTEMC_EXT_UTIL_SC_VECTOR_HH__
753