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

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

cpp: added complex (without some math functions)

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