00001
00002
00008 #if !defined(__ArrayContainer_h__)
00009 #define __ArrayContainer_h__
00010
00011
00012 #if defined(DEBUG_ads) && !defined(DEBUG_ArrayContainer)
00013 #define DEBUG_ArrayContainer
00014 #endif
00015
00016 #include "ArrayTypes.h"
00017
00018
00019 #include "../../third-party/loki/TypeManip.h"
00020
00021 #include <iosfwd>
00022 #include <iostream>
00023 #include <numeric>
00024 #include <algorithm>
00025 #include <limits>
00026
00027 #include <cassert>
00028 #include <cmath>
00029
00030 BEGIN_NAMESPACE_ADS
00031
00033
00040 template<typename T = double, bool A = true>
00041 class ArrayContainer
00042 {
00043 private:
00044
00045
00046
00047
00048
00049 typedef ArrayTypes<T> types;
00050
00051 public:
00052
00053
00054
00055
00056
00058 typedef typename types::value_type value_type;
00060
00063 typedef typename types::parameter_type parameter_type;
00065
00068 typedef typename types::unqualified_value_type unqualified_value_type;
00069
00071 typedef typename types::pointer pointer;
00073 typedef typename types::const_pointer const_pointer;
00074
00076 typedef typename types::iterator iterator;
00078 typedef typename types::const_iterator const_iterator;
00079
00081 typedef typename types::reference reference;
00083 typedef typename types::const_reference const_reference;
00084
00086
00092 typedef typename types::size_type size_type;
00094 typedef typename types::difference_type difference_type;
00095
00096 private:
00097
00098
00099
00100
00101
00102
00103 pointer _start;
00104
00105 pointer _finish;
00106
00107 size_type _size;
00108
00109 protected:
00110
00111
00113
00114
00116 ArrayContainer() :
00117 _start(0),
00118 _finish(0),
00119 _size(0)
00120 {}
00121
00122
00127 ArrayContainer(const ArrayContainer& x) :
00128 _start(0),
00129 _finish(0),
00130 _size(0) {
00131 copy(x);
00132 }
00133
00134
00139 template<typename T2, bool A2>
00140 ArrayContainer(const ArrayContainer<T2,A2>& x) :
00141 _start(0),
00142 _finish(0),
00143 _size(0) {
00144 copy(x);
00145 }
00146
00148
00152 ArrayContainer&
00153 operator=(const ArrayContainer& other) {
00154 if (&other != this) {
00155 copy(other);
00156 }
00157 return *this;
00158 }
00159
00161
00165 template<typename T2, bool A2>
00166 ArrayContainer&
00167 operator=(const ArrayContainer<T2,A2>& x) {
00168
00169 copy(x);
00170 return *this;
00171 }
00172
00174
00177 template<typename ForwardIterator>
00178 ArrayContainer(ForwardIterator start, ForwardIterator finish) :
00179 _start(0),
00180 _finish(0),
00181 _size(0) {
00182 copy_range(start, finish);
00183 }
00184
00186
00189 template<typename ForwardIterator>
00190 void
00191 rebuild(ForwardIterator start, ForwardIterator finish) {
00192 copy_range(start, finish);
00193 }
00194
00196
00199 template<typename Type>
00200 ArrayContainer(Type* start, Type* finish) :
00201 _start(0),
00202 _finish(0),
00203 _size(0) {
00204 copy_range(start, finish);
00205 }
00206
00208
00211 template<typename Type>
00212 void
00213 rebuild(Type* start, Type* finish) {
00214 copy_range(start, finish);
00215 }
00216
00218
00221 explicit
00222 ArrayContainer(const size_type size) :
00223 _start(0),
00224 _finish(0),
00225 _size(size) {
00226 allocate();
00227 _finish = _start + _size;
00228 }
00229
00231
00234 void
00235 rebuild(const size_type size) {
00236 _size = size;
00237 allocate();
00238 _finish = _start + _size;
00239 }
00240
00242 void
00243 swap(ArrayContainer& other) {
00244 if (&other != this) {
00245 std::swap(_start, other._start);
00246 std::swap(_finish, other._finish);
00247 std::swap(_size, other._size);
00248 }
00249 }
00250
00252 void
00253 resize(const size_type size) {
00254 resize(size, Loki::Int2Type<A>());
00255 }
00256
00258 ~ArrayContainer() {
00259 destroy();
00260 }
00261
00262
00263
00264 public:
00265
00266
00268
00269
00271 size_type
00272 size() const {
00273 return _size;
00274 }
00275
00277 bool
00278 empty() const {
00279 return _size == 0;
00280 }
00281
00283 size_type
00284 max_size() const {
00285 return std::numeric_limits<int>::max() / sizeof(value_type);
00286 }
00287
00289 const_iterator
00290 begin() const {
00291 return _start;
00292 }
00293
00295 const_iterator
00296 end() const {
00297 return _finish;
00298 }
00299
00301
00306 pointer
00307 data() const {
00308 return _start;
00309 }
00310
00312
00317 parameter_type
00318 operator[](const int i) const {
00319 #ifdef DEBUG_ArrayContainer
00320 assert(0 <= i && i < _size);
00321 #endif
00322 return _start[i];
00323 }
00324
00326
00329 size_type
00330 getMemoryUsage() const {
00331 return sizeof(ArrayContainer) + size() * sizeof(value_type);
00332 }
00333
00334
00335
00337
00338
00340 iterator
00341 begin() {
00342 return _start;
00343 }
00344
00346 iterator
00347 end() {
00348 return _finish;
00349 }
00350
00352 pointer
00353 data() {
00354 return _start;
00355 }
00356
00358
00363 reference
00364 operator[](const int i) {
00365 #ifdef DEBUG_ArrayIndexing
00366 assert(0 <= i && i < size());
00367 #endif
00368 return _start[i];
00369 }
00370
00372 void
00373 negate();
00374
00376 void
00377 fill(parameter_type value);
00378
00379
00380
00382
00383
00385 ArrayContainer&
00386 operator=(parameter_type x);
00387
00388
00389
00391
00392
00393
00395 template<typename T2, bool A2>
00396 bool
00397 operator==(const ArrayContainer<T2,A2>& x) const {
00398
00399 if (size() != x.size()) {
00400 return false;
00401 }
00402
00403 return std::equal(begin(), end(), x.begin());
00404 }
00405
00407 template<typename T2, bool A2>
00408 bool
00409 operator!=(const ArrayContainer<T2,A2>& x) const {
00410 return ! operator==(x);
00411 }
00412
00413
00414
00416
00417
00419 void
00420 put(std::ostream& out) const {
00421 for (const_iterator iter = begin(); iter != end(); ++iter) {
00422 out << *iter << '\n';
00423 }
00424 }
00425
00427 void
00428 get(std::istream& in) {
00429 for (iterator iter = begin(); iter != end(); ++iter) {
00430 in >> *iter;
00431 }
00432 }
00433
00435 void
00436 write(std::ostream& out) const {
00437 out.write(reinterpret_cast<const char*>(begin()),
00438 size() * sizeof(value_type));
00439 }
00440
00442 void
00443 write_elements_ascii(std::ostream& out) const {
00444 put(out);
00445 }
00446
00448 void
00449 write_elements_binary(std::ostream& out) const {
00450 write(out);
00451 }
00452
00454 void
00455 read(std::istream& in) {
00456 in.read(reinterpret_cast<char*>(begin()),
00457 size() * sizeof(value_type));
00458 assert(in.gcount() == size_type(size() * sizeof(value_type)));
00459 }
00460
00462 void
00463 read_elements_ascii(std::istream& in) {
00464 get(in);
00465 }
00466
00468 void
00469 read_elements_binary(std::istream& in) {
00470 read(in);
00471 }
00472
00473
00474
00475 private:
00476
00477
00478
00479
00480
00481 void
00482 resize(const size_type size, Loki::Int2Type<true>) {
00483
00484 if (_size != size) {
00485
00486 destroy();
00487
00488 _size = size;
00489
00490 allocate();
00491 }
00492
00493 _finish = _start + _size;
00494 }
00495
00496 template<typename T2, bool A2>
00497 void
00498 copy(const ArrayContainer<T2,A2>& x) {
00499 copy_range(x.data(), x.data() + x.size());
00500 }
00501
00502 template<typename ForwardIterator>
00503 void
00504 copy_range(ForwardIterator start, ForwardIterator finish) {
00505 copy_range(start, finish, Loki::Int2Type<A>());
00506 }
00507
00508 template<typename ForwardIterator>
00509 void
00510 copy_range(ForwardIterator start, ForwardIterator finish,
00511 Loki::Int2Type<true>) {
00512
00513 resize(std::distance(start, finish));
00514
00515 std::copy(start, finish, _start);
00516 }
00517
00518 template<typename RandomAccessIterator>
00519 void
00520 copy_range(RandomAccessIterator start, RandomAccessIterator finish,
00521 Loki::Int2Type<false>) {
00522 _start = start;
00523 _finish = finish;
00524 _size = size_type(finish - start);
00525 }
00526
00527 void
00528 allocate() {
00529 allocate(Loki::Int2Type<A>());
00530 }
00531
00532
00533 void
00534 allocate(Loki::Int2Type<true>) {
00535 if (_size == 0) {
00536 _start = 0;
00537 }
00538 else {
00539 _start = new value_type[_size];
00540 }
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 void
00562 destroy() {
00563 deallocate();
00564 _start = 0;
00565 _finish = 0;
00566 _size = 0;
00567 }
00568
00569 void
00570 deallocate() {
00571 deallocate(Loki::Int2Type<A>());
00572 }
00573
00574
00575 void
00576 deallocate(Loki::Int2Type<true>) {
00577 if (_size != 0) {
00578 delete[] _start;
00579 }
00580 }
00581
00582
00583 void
00584 deallocate(Loki::Int2Type<false>)
00585 {}
00586 };
00587
00588
00589
00592
00593
00594
00595
00596
00598
00602 template<typename T, bool A>
00603 inline
00604 T
00605 computeSum(const ArrayContainer<T,A>& x) {
00606 return std::accumulate(x.begin(), x.end(), T(0));
00607 }
00608
00610
00614 template<typename T, bool A>
00615 inline
00616 T
00617 computeProduct(const ArrayContainer<T,A>& x) {
00618 return std::accumulate(x.begin(), x.end(), T(1), std::multiplies<T>());
00619 }
00620
00622
00626 template<typename T, bool A>
00627 inline
00628 T
00629 computeMinimum(const ArrayContainer<T,A>& x) {
00630
00631
00632 if (x.empty()) {
00633 return std::numeric_limits<T>::max();
00634 }
00635 return *std::min_element(x.begin(), x.end());
00636 }
00637
00639
00643 template<typename T, bool A>
00644 inline
00645 T
00646 computeMaximum(const ArrayContainer<T,A>& x) {
00647
00648
00649 if (x.empty()) {
00650 return - std::numeric_limits<T>::max();
00651 }
00652 return *std::max_element(x.begin(), x.end());
00653 }
00654
00655
00656
00657
00658
00659
00661
00665 template<typename T, bool A>
00666 inline
00667 void
00668 applyAbs(ArrayContainer<T,A>* x) {
00669 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00670 ++i) {
00671 *i = std::abs(*i);
00672 }
00673 }
00674
00676
00680 template<typename T, bool A>
00681 inline
00682 void
00683 applyAcos(ArrayContainer<T,A>* x) {
00684 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00685 ++i) {
00686 *i = std::acos(*i);
00687 }
00688 }
00689
00691
00695 template<typename T, bool A>
00696 inline
00697 void
00698 applyAsin(ArrayContainer<T,A>* x) {
00699 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00700 ++i) {
00701 *i = std::asin(*i);
00702 }
00703 }
00704
00706
00710 template<typename T, bool A>
00711 inline
00712 void
00713 applyAtan(ArrayContainer<T,A>* x) {
00714 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00715 ++i) {
00716 *i = std::atan(*i);
00717 }
00718 }
00719
00721
00725 template<typename T, bool A>
00726 inline
00727 void
00728 applyCeil(ArrayContainer<T,A>* x) {
00729 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00730 ++i) {
00731 *i = std::ceil(*i);
00732 }
00733 }
00734
00736
00740 template<typename T, bool A>
00741 inline
00742 void
00743 applyCos(ArrayContainer<T,A>* x) {
00744 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00745 ++i) {
00746 *i = std::cos(*i);
00747 }
00748 }
00749
00751
00755 template<typename T, bool A>
00756 inline
00757 void
00758 applyCosh(ArrayContainer<T,A>* x) {
00759 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00760 ++i) {
00761 *i = std::cosh(*i);
00762 }
00763 }
00764
00766
00770 template<typename T, bool A>
00771 inline
00772 void
00773 applyExp(ArrayContainer<T,A>* x) {
00774 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00775 ++i) {
00776 *i = std::exp(*i);
00777 }
00778 }
00779
00781
00785 template<typename T, bool A>
00786 inline
00787 void
00788 applyFloor(ArrayContainer<T,A>* x) {
00789 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00790 ++i) {
00791 *i = std::floor(*i);
00792 }
00793 }
00794
00796
00800 template<typename T, bool A>
00801 inline
00802 void
00803 applyLog(ArrayContainer<T,A>* x) {
00804 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00805 ++i) {
00806 *i = std::log(*i);
00807 }
00808 }
00809
00811
00815 template<typename T, bool A>
00816 inline
00817 void
00818 applyLog10(ArrayContainer<T,A>* x) {
00819 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00820 ++i) {
00821 *i = std::log10(*i);
00822 }
00823 }
00824
00826
00830 template<typename T, bool A>
00831 inline
00832 void
00833 applySin(ArrayContainer<T,A>* x) {
00834 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00835 ++i) {
00836 *i = std::sin(*i);
00837 }
00838 }
00839
00841
00845 template<typename T, bool A>
00846 inline
00847 void
00848 applySinh(ArrayContainer<T,A>* x) {
00849 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00850 ++i) {
00851 *i = std::sinh(*i);
00852 }
00853 }
00854
00856
00860 template<typename T, bool A>
00861 inline
00862 void
00863 applySqrt(ArrayContainer<T,A>* x) {
00864 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00865 ++i) {
00866 *i = std::sqrt(*i);
00867 }
00868 }
00869
00871
00875 template<typename T, bool A>
00876 inline
00877 void
00878 applyTan(ArrayContainer<T,A>* x) {
00879 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00880 ++i) {
00881 *i = std::tan(*i);
00882 }
00883 }
00884
00886
00890 template<typename T, bool A>
00891 inline
00892 void
00893 applyTanh(ArrayContainer<T,A>* x) {
00894 for (typename ArrayContainer<T,A>::iterator i = x->begin(); i != x->end();
00895 ++i) {
00896 *i = std::tanh(*i);
00897 }
00898 }
00899
00900
00901
00902
00903
00905 template<typename T, bool A>
00906 ArrayContainer<T,A>&
00907 operator+=(ArrayContainer<T,A>& array,
00908 typename ArrayContainer<T,A>::parameter_type x);
00909
00911 template<typename T, bool A>
00912 ArrayContainer<T,A>&
00913 operator-=(ArrayContainer<T,A>& array,
00914 typename ArrayContainer<T,A>::parameter_type x);
00915
00917 template<typename T, bool A>
00918 ArrayContainer<T,A>&
00919 operator*=(ArrayContainer<T,A>& array,
00920 typename ArrayContainer<T,A>::parameter_type x);
00921
00923 template<typename T, bool A>
00924 ArrayContainer<T,A>&
00925 operator/=(ArrayContainer<T,A>& array,
00926 typename ArrayContainer<T,A>::parameter_type x);
00927
00929 template<typename T, bool A>
00930 ArrayContainer<T,A>&
00931 operator%=(ArrayContainer<T,A>& array,
00932 typename ArrayContainer<T,A>::parameter_type x);
00933
00935 template<typename T, bool A>
00936 ArrayContainer<T*,A>&
00937 operator+=(ArrayContainer<T*,A>& array,
00938 typename ArrayContainer<T*,A>::difference_type x);
00939
00941 template<typename T, bool A>
00942 ArrayContainer<T*,A>&
00943 operator-=(ArrayContainer<T*,A>& array,
00944 typename ArrayContainer<T*,A>::difference_type x);
00945
00946
00947
00948
00949
00951 template<typename T1, bool A1, typename T2, bool A2>
00952 ArrayContainer<T1,A1>&
00953 operator+=(ArrayContainer<T1,A1>& x, const ArrayContainer<T2,A2> & y);
00954
00956 template<typename T1, bool A1, typename T2, bool A2>
00957 ArrayContainer<T1,A1>&
00958 operator-=(ArrayContainer<T1,A1>& x, const ArrayContainer<T2,A2> & y);
00959
00961 template<typename T1, bool A1, typename T2, bool A2>
00962 ArrayContainer<T1,A1>&
00963 operator*=(ArrayContainer<T1,A1>& x, const ArrayContainer<T2,A2> & y);
00964
00966 template<typename T1, bool A1, typename T2, bool A2>
00967 ArrayContainer<T1,A1>&
00968 operator/=(ArrayContainer<T1,A1>& x, const ArrayContainer<T2,A2> & y);
00969
00971 template<typename T1, bool A1, typename T2, bool A2>
00972 ArrayContainer<T1,A1>&
00973 operator%=(ArrayContainer<T1,A1>& x, const ArrayContainer<T2,A2> & y);
00974
00975
00976
00977
00978
00979
00980 #if 0
00981
00982
00983 template<typename T1, typename T2, bool A1, bool A2>
00984 bool
00985 operator==(const ArrayContainer<T1,A1>& a, const ArrayContainer<T2,A2>& b) {
00986 return a.operator==(b);
00987 }
00988
00990
00991 template<typename T1, typename T2, bool A1, bool A2>
00992 inline
00993 bool
00994 operator!=(const ArrayContainer<T1,A1>& a, const ArrayContainer<T2,A2>& b) {
00995 return !(a == b);
00996 }
00997 #endif
00998
01000
01001 END_NAMESPACE_ADS
01002
01003 #define __ArrayContainer_ipp__
01004 #include "ArrayContainer.ipp"
01005 #undef __ArrayContainer_ipp__
01006
01007 #endif