source: mainline/uspace/lib/cpp/include/__bits/complex.hpp@ a95e75e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a95e75e was ad40b74b, checked in by Jaroslav Jindrak <dzejrou@…>, 6 years ago

cpp: abort and report when an unimplemented function is called

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