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