source: mainline/uspace/lib/cpp/include/impl/complex.hpp@ 937de98

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 937de98 was 937de98, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: fixed bug found by complex tests

  • Property mode set to 100644
File size: 23.3 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_COMPLEX
30#define LIBCPP_COMPLEX
31
32#include <iosfwd>
33#include <sstream>
34
35namespace std
36{
37 template<class T>
38 class complex
39 {
40 public:
41 using value_type = T;
42
43 constexpr complex(const value_type& re = value_type{},
44 const value_type& im = value_type{})
45 : real_{re}, imag_{im}
46 { /* DUMMY BODY */ }
47
48 constexpr complex(const complex& other)
49 : real_{other.real_}, imag_{other.imag_}
50 { /* DUMMY BODY */ }
51
52 template<class U>
53 constexpr complex(const complex<U>& other)
54 : real_(other.real()), imag_(other.imag())
55 { /* DUMMY BODY */ }
56
57 constexpr value_type real() const
58 {
59 return real_;
60 }
61
62 void real(value_type val)
63 {
64 real_ = val;
65 }
66
67 constexpr value_type imag() const
68 {
69 return imag_;
70 }
71
72 void imag(value_type val)
73 {
74 imag_ = val;
75 }
76
77 complex& operator=(const value_type& val)
78 {
79 real_ = val;
80 imag_ = value_type{};
81
82 return *this;
83 }
84
85 complex& operator+=(const value_type& val)
86 {
87 real_ += val;
88
89 return *this;
90 }
91
92 complex& operator-=(const value_type& val)
93 {
94 real_ -= val;
95
96 return *this;
97 }
98
99 complex& operator*=(const value_type& val)
100 {
101 real_ *= val;
102 imag_ *= val;
103
104 return *this;
105 }
106
107 complex& operator/=(const value_type& val)
108 {
109 real_ /= val;
110 imag_ /= val;
111
112 return *this;
113 }
114
115 complex& operator=(const complex& other)
116 {
117 real_ = other.real_;
118 imag_ = other.imag_;
119
120 return *this;
121 }
122
123 template<class U>
124 complex& operator=(const complex<U>& rhs)
125 {
126 real_ = rhs.real_;
127 imag_ = rhs.imag_;
128
129 return *this;
130 }
131
132 template<class U>
133 complex& operator+=(const complex<U>& rhs)
134 {
135 real_ += rhs.real_;
136 imag_ += rhs.imag_;
137
138 return *this;
139 }
140
141 template<class U>
142 complex& operator-=(const complex<U>& rhs)
143 {
144 real_ -= rhs.real_;
145 imag_ -= rhs.imag_;
146
147 return *this;
148 }
149
150 template<class U>
151 complex& operator*=(const complex<U>& rhs)
152 {
153 auto old_real = real_;
154 real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
155 imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
156
157 return *this;
158 }
159
160 template<class U>
161 complex& operator/=(const complex<U>& rhs)
162 {
163 auto old_real = real_;
164 real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
165 / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
166 imag_ = (imag_ * rhs.real_ - old_real * rhs.imag_)
167 / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
168
169 return *this;
170 }
171
172 private:
173 value_type real_;
174 value_type imag_;
175 };
176
177 template<>
178 class complex<float>
179 {
180 public:
181 using value_type = float;
182
183 constexpr complex(const value_type& re = value_type{},
184 const value_type& im = value_type{})
185 : real_{re}, imag_{im}
186 { /* DUMMY BODY */ }
187
188 constexpr complex(const complex& other)
189 : real_{other.real_}, imag_{other.imag_}
190 { /* DUMMY BODY */ }
191
192 template<class U>
193 constexpr complex(const complex<U>& other)
194 : real_(other.real()), imag_(other.imag())
195 { /* DUMMY BODY */ }
196
197 constexpr value_type real() const
198 {
199 return real_;
200 }
201
202 void real(value_type val)
203 {
204 real_ = val;
205 }
206
207 constexpr value_type imag() const
208 {
209 return imag_;
210 }
211
212 void imag(value_type val)
213 {
214 imag_ = val;
215 }
216
217 complex& operator=(const value_type& val)
218 {
219 real_ = val;
220 imag_ = value_type{};
221
222 return *this;
223 }
224
225 complex& operator+=(const value_type& val)
226 {
227 real_ += val;
228
229 return *this;
230 }
231
232 complex& operator-=(const value_type& val)
233 {
234 real_ -= val;
235
236 return *this;
237 }
238
239 complex& operator*=(const value_type& val)
240 {
241 real_ *= val;
242 imag_ *= val;
243
244 return *this;
245 }
246
247 complex& operator/=(const value_type& val)
248 {
249 real_ /= val;
250 imag_ /= val;
251
252 return *this;
253 }
254
255 complex& operator=(const complex& other)
256 {
257 real_ = other.real_;
258 imag_ = other.imag_;
259
260 return *this;
261 }
262
263 template<class U>
264 complex& operator=(const complex<U>& rhs)
265 {
266 real_ = rhs.real_;
267 imag_ = rhs.imag_;
268
269 return *this;
270 }
271
272 template<class U>
273 complex& operator+=(const complex<U>& rhs)
274 {
275 real_ += rhs.real_;
276 imag_ += rhs.imag_;
277
278 return *this;
279 }
280
281 template<class U>
282 complex& operator-=(const complex<U>& rhs)
283 {
284 real_ -= rhs.real_;
285 imag_ -= rhs.imag_;
286
287 return *this;
288 }
289
290 template<class U>
291 complex& operator*=(const complex<U>& rhs)
292 {
293 auto old_real = real_;
294 real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
295 imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
296
297 return *this;
298 }
299
300 template<class U>
301 complex& operator/=(const complex<U>& rhs)
302 {
303 auto old_real = real_;
304 real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
305 / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
306 imag_ = (imag_ * rhs.real_ - old_real * rhs.imag_)
307 / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
308
309 return *this;
310 }
311
312 private:
313 value_type real_;
314 value_type imag_;
315 };
316
317 template<>
318 class complex<double>
319 {
320 public:
321 using value_type = double;
322
323 constexpr complex(const value_type& re = value_type{},
324 const value_type& im = value_type{})
325 : real_{re}, imag_{im}
326 { /* DUMMY BODY */ }
327
328 constexpr complex(const complex& other)
329 : real_{other.real_}, imag_{other.imag_}
330 { /* DUMMY BODY */ }
331
332 template<class U>
333 constexpr complex(const complex<U>& other)
334 : real_(other.real()), imag_(other.imag())
335 { /* DUMMY BODY */ }
336
337 constexpr value_type real() const
338 {
339 return real_;
340 }
341
342 void real(value_type val)
343 {
344 real_ = val;
345 }
346
347 constexpr value_type imag() const
348 {
349 return imag_;
350 }
351
352 void imag(value_type val)
353 {
354 imag_ = val;
355 }
356
357 complex& operator=(const value_type& val)
358 {
359 real_ = val;
360 imag_ = value_type{};
361
362 return *this;
363 }
364
365 complex& operator+=(const value_type& val)
366 {
367 real_ += val;
368
369 return *this;
370 }
371
372 complex& operator-=(const value_type& val)
373 {
374 real_ -= val;
375
376 return *this;
377 }
378
379 complex& operator*=(const value_type& val)
380 {
381 real_ *= val;
382 imag_ *= val;
383
384 return *this;
385 }
386
387 complex& operator/=(const value_type& val)
388 {
389 real_ /= val;
390 imag_ /= val;
391
392 return *this;
393 }
394
395 complex& operator=(const complex& other)
396 {
397 real_ = other.real_;
398 imag_ = other.imag_;
399
400 return *this;
401 }
402
403 template<class U>
404 complex& operator=(const complex<U>& rhs)
405 {
406 real_ = rhs.real_;
407 imag_ = rhs.imag_;
408
409 return *this;
410 }
411
412 template<class U>
413 complex& operator+=(const complex<U>& rhs)
414 {
415 real_ += rhs.real_;
416 imag_ += rhs.imag_;
417
418 return *this;
419 }
420
421 template<class U>
422 complex& operator-=(const complex<U>& rhs)
423 {
424 real_ -= rhs.real_;
425 imag_ -= rhs.imag_;
426
427 return *this;
428 }
429
430 template<class U>
431 complex& operator*=(const complex<U>& rhs)
432 {
433 auto old_real = real_;
434 real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
435 imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
436
437 return *this;
438 }
439
440 template<class U>
441 complex& operator/=(const complex<U>& rhs)
442 {
443 auto old_real = real_;
444 real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
445 / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
446 imag_ = (imag_ * rhs.real_ - old_real * rhs.imag_)
447 / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
448
449 return *this;
450 }
451
452 private:
453 value_type real_;
454 value_type imag_;
455 };
456
457 template<>
458 class complex<long double>
459 {
460 public:
461 using value_type = long double;
462
463 constexpr complex(const value_type& re = value_type{},
464 const value_type& im = value_type{})
465 : real_{re}, imag_{im}
466 { /* DUMMY BODY */ }
467
468 constexpr complex(const complex& other)
469 : real_{other.real_}, imag_{other.imag_}
470 { /* DUMMY BODY */ }
471
472 template<class U>
473 constexpr complex(const complex<U>& other)
474 : real_(other.real()), imag_(other.imag())
475 { /* DUMMY BODY */ }
476
477 constexpr value_type real() const
478 {
479 return real_;
480 }
481
482 void real(value_type val)
483 {
484 real_ = val;
485 }
486
487 constexpr value_type imag() const
488 {
489 return imag_;
490 }
491
492 void imag(value_type val)
493 {
494 imag_ = val;
495 }
496
497 complex& operator=(const value_type& val)
498 {
499 real_ = val;
500 imag_ = value_type{};
501
502 return *this;
503 }
504
505 complex& operator+=(const value_type& val)
506 {
507 real_ += val;
508
509 return *this;
510 }
511
512 complex& operator-=(const value_type& val)
513 {
514 real_ -= val;
515
516 return *this;
517 }
518
519 complex& operator*=(const value_type& val)
520 {
521 real_ *= val;
522 imag_ *= val;
523
524 return *this;
525 }
526
527 complex& operator/=(const value_type& val)
528 {
529 real_ /= val;
530 imag_ /= val;
531
532 return *this;
533 }
534
535 complex& operator=(const complex& other)
536 {
537 real_ = other.real_;
538 imag_ = other.imag_;
539
540 return *this;
541 }
542
543 template<class U>
544 complex& operator=(const complex<U>& rhs)
545 {
546 real_ = rhs.real_;
547 imag_ = rhs.imag_;
548
549 return *this;
550 }
551
552 template<class U>
553 complex& operator+=(const complex<U>& rhs)
554 {
555 real_ += rhs.real_;
556 imag_ += rhs.imag_;
557
558 return *this;
559 }
560
561 template<class U>
562 complex& operator-=(const complex<U>& rhs)
563 {
564 real_ -= rhs.real_;
565 imag_ -= rhs.imag_;
566
567 return *this;
568 }
569
570 template<class U>
571 complex& operator*=(const complex<U>& rhs)
572 {
573 auto old_real = real_;
574 real_ = real_ * rhs.real_ - imag_ * rhs.imag_;
575 imag_ = old_real * rhs.imag_ + imag_ * rhs.real_;
576
577 return *this;
578 }
579
580 template<class U>
581 complex& operator/=(const complex<U>& rhs)
582 {
583 auto old_real = real_;
584 real_ = (real_ * rhs.real_ + imag_ * rhs.imag_)
585 / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
586 imag_ = (imag_ * rhs.real_ - old_real* rhs.imag_)
587 / (rhs.real_ * rhs.real_ + rhs.imag_ * rhs.imag_);
588
589 return *this;
590 }
591
592 private:
593 value_type real_;
594 value_type imag_;
595 };
596
597 /**
598 * 26.4.6, operators:
599 */
600
601 template<class T>
602 complex<T> operator+(const complex<T>& lhs, const complex<T>& rhs)
603 {
604 return complex<T>{lhs} += rhs;
605 }
606
607 template<class T>
608 complex<T> operator+(const complex<T>& lhs, const T& rhs)
609 {
610 return complex<T>{lhs} += rhs;
611 }
612
613 template<class T>
614 complex<T> operator+(const T& lhs, const complex<T>& rhs)
615 {
616 return complex<T>{lhs} += rhs;
617 }
618
619 template<class T>
620 complex<T> operator-(const complex<T>& lhs, const complex<T>& rhs)
621 {
622 return complex<T>{lhs} -= rhs;
623 }
624
625 template<class T>
626 complex<T> operator-(const complex<T>& lhs, const T& rhs)
627 {
628 return complex<T>{lhs} -= rhs;
629 }
630
631 template<class T>
632 complex<T> operator-(const T& lhs, const complex<T>& rhs)
633 {
634 return complex<T>{lhs} -= rhs;
635 }
636
637 template<class T>
638 complex<T> operator*(const complex<T>& lhs, const complex<T>& rhs)
639 {
640 return complex<T>{lhs} *= rhs;
641 }
642
643 template<class T>
644 complex<T> operator*(const complex<T>& lhs, const T& rhs)
645 {
646 return complex<T>{lhs} *= rhs;
647 }
648
649 template<class T>
650 complex<T> operator*(const T& lhs, const complex<T>& rhs)
651 {
652 return complex<T>{lhs} *= rhs;
653 }
654
655 template<class T>
656 complex<T> operator/(const complex<T>& lhs, const complex<T>& rhs)
657 {
658 return complex<T>{lhs} /= rhs;
659 }
660
661 template<class T>
662 complex<T> operator/(const complex<T>& lhs, const T& rhs)
663 {
664 return complex<T>{lhs} /= rhs;
665 }
666
667 template<class T>
668 complex<T> operator/(const T& lhs, const complex<T>& rhs)
669 {
670 return complex<T>{lhs} /= rhs;
671 }
672
673 template<class T>
674 complex<T> operator+(const complex<T>& c)
675 {
676 return complex<T>{c};
677 }
678
679 template<class T>
680 complex<T> operator-(const complex<T>& c)
681 {
682 return complex<T>{-c.real(), -c.imag()};
683 }
684
685 template<class T>
686 constexpr bool operator==(const complex<T>& lhs, const complex<T>& rhs)
687 {
688 return lhs.real() == rhs.real() && lhs.imag() == rhs.imag();
689 }
690
691 template<class T>
692 constexpr bool operator==(const complex<T>& lhs, const T& rhs)
693 {
694 return lhs.real() == rhs && lhs.imag() == T{};
695 }
696
697 template<class T>
698 constexpr bool operator==(const T& lhs, const complex<T>& rhs)
699 {
700 return lhs == rhs.real() && T{} == rhs.imag();
701 }
702
703 template<class T>
704 constexpr bool operator!=(const complex<T>& lhs, const complex<T>& rhs)
705 {
706 return lhs.real() != rhs.real() || lhs.imag() != rhs.imag();
707 }
708
709 template<class T>
710 constexpr bool operator!=(const complex<T>& lhs, const T& rhs)
711 {
712 return lhs.real() != rhs || lhs.imag() != T{};
713 }
714
715 template<class T>
716 constexpr bool operator!=(const T& lhs, const complex<T>& rhs)
717 {
718 return lhs != rhs.real() || T{} != rhs.imag();
719 }
720
721 template<class T, class Char, class Traits>
722 basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is,
723 const complex<T>& c)
724 {
725 // TODO: implement
726 }
727
728 template<class T, class Char, class Traits>
729 basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os,
730 const complex<T>& c)
731 {
732 basic_ostringstream<Char, Traits> oss{};
733 oss.flags(os.flags());
734 oss.imbue(os.getloc());
735 oss.precision(os.precision());
736
737 oss << "(" << c.real() << "," << c.imag() << ")";
738
739 return os << oss.str();
740 }
741
742 /**
743 * 26.4.7, values:
744 */
745
746 template<class T>
747 constexpr T real(const complex<T>& c)
748 {
749 return c.real();
750 }
751
752 template<class T>
753 constexpr T imag(const complex<T>& c)
754 {
755 return c.imag();
756 }
757
758 template<class T>
759 T abs(const complex<T>& c)
760 {
761 return c.real() * c.real() + c.imag() * c.imag();
762 }
763
764 template<class T>
765 T arg(const complex<T>& c)
766 {
767 // TODO: implement
768 return c;
769 }
770
771 template<class T>
772 T norm(const complex<T>& c)
773 {
774 return abs(c) * abs(c);
775 }
776
777 template<class T>
778 complex<T> conj(const complex<T>& c)
779 {
780 // TODO: implement
781 return c;
782 }
783
784 template<class T>
785 complex<T> proj(const complex<T>& c)
786 {
787 // TODO: implement
788 return c;
789 }
790
791 template<class T>
792 complex<T> polar(const T&, const T& = T{})
793 {
794 // TODO: implement
795 return complex<T>{};
796 }
797
798 /**
799 * 26.4.8, transcendentals:
800 */
801
802 template<class T>
803 complex<T> acos(const complex<T>& c)
804 {
805 // TODO: implement
806 return c;
807 }
808
809 template<class T>
810 complex<T> asin(const complex<T>& c)
811 {
812 // TODO: implement
813 return c;
814 }
815
816 template<class T>
817 complex<T> atan(const complex<T>& c)
818 {
819 // TODO: implement
820 return c;
821 }
822
823 template<class T>
824 complex<T> acosh(const complex<T>& c)
825 {
826 // TODO: implement
827 return c;
828 }
829
830 template<class T>
831 complex<T> asinh(const complex<T>& c)
832 {
833 // TODO: implement
834 return c;
835 }
836
837 template<class T>
838 complex<T> atanh(const complex<T>& c)
839 {
840 // TODO: implement
841 return c;
842 }
843
844 template<class T>
845 complex<T> cos(const complex<T>& c)
846 {
847 // TODO: implement
848 return c;
849 }
850
851 template<class T>
852 complex<T> cosh(const complex<T>& c)
853 {
854 // TODO: implement
855 return c;
856 }
857
858 template<class T>
859 complex<T> exp(const complex<T>& c)
860 {
861 // TODO: implement
862 return c;
863 }
864
865 template<class T>
866 complex<T> log(const complex<T>& c)
867 {
868 // TODO: implement
869 return c;
870 }
871
872 template<class T>
873 complex<T> log10(const complex<T>& c)
874 {
875 // TODO: implement
876 return c;
877 }
878
879 template<class T>
880 complex<T> pow(const complex<T>& base, const T& exp)
881 {
882 // TODO: implement
883 return base;
884 }
885
886 template<class T>
887 complex<T> pow(const complex<T>& base, const complex<T>& exp)
888 {
889 // TODO: implement
890 return base;
891 }
892
893 template<class T>
894 complex<T> pow(const T& base, const complex<T>& exp)
895 {
896 // TODO: implement
897 return complex<T>{base};
898 }
899
900 template<class T>
901 complex<T> sin(const complex<T>& c)
902 {
903 // TODO: implement
904 return c;
905 }
906
907 template<class T>
908 complex<T> sinh(const complex<T>& c)
909 {
910 // TODO: implement
911 return c;
912 }
913
914 template<class T>
915 complex<T> sqrt(const complex<T>& c)
916 {
917 // TODO: implement
918 return c;
919 }
920
921 template<class T>
922 complex<T> tan(const complex<T>& c)
923 {
924 // TODO: implement
925 return c;
926 }
927
928 template<class T>
929 complex<T> tanh(const complex<T>& c)
930 {
931 // TODO: implement
932 return c;
933 }
934
935 /**
936 * 26.4.10, complex literals:
937 */
938
939#pragma GCC diagnostic push
940#pragma GCC diagnostic ignored "-Wliteral-suffix"
941inline namespace literals {
942inline namespace complex_literals
943{
944 constexpr complex<long double> operator ""il(long double val)
945 {
946 return complex<long double>{0.0L, val};
947 }
948
949 constexpr complex<long double> operator ""il(unsigned long long val)
950 {
951 return complex<long double>{0.0L, static_cast<long double>(val)};
952 }
953
954 constexpr complex<double> operator ""i(long double val)
955 {
956 return complex<double>{0.0, static_cast<double>(val)};
957 }
958
959 constexpr complex<double> operator ""i(unsigned long long val)
960 {
961 return complex<double>{0.0, static_cast<double>(val)};
962 }
963
964 constexpr complex<float> operator ""if(long double val)
965 {
966 return complex<float>{0.0f, static_cast<float>(val)};
967 }
968
969 constexpr complex<float> operator ""if(unsigned long long val)
970 {
971 return complex<float>{0.0f, static_cast<float>(val)};
972 }
973}}
974#pragma GCC diagnostic pop
975}
976
977#endif
Note: See TracBrowser for help on using the repository browser.