38 #ifndef VIGRA_UNIT_TEST_HPP
39 #define VIGRA_UNIT_TEST_HPP
52 #include "vigra/config.hxx"
53 #include "vigra/error.hxx"
55 #ifdef VIGRA_NO_WORKING_STRINGSTREAM
57 #define VIGRA_SSTREAM std::strstream
58 #define VIGRA_SSTREAM_STR(s) ((s << char()), std::string(s.str()))
61 #define VIGRA_SSTREAM std::basic_stringstream<char>
62 #define VIGRA_SSTREAM_STR(s) s.str()
85 #elif defined(__CYGWIN__)
87 #define VIGRA_CANT_CATCH_SIGNALS
89 #elif defined(__unix) || defined(unix)
93 #include <sys/signal.h>
98 #define VIGRA_CANT_CATCH_SIGNALS
102 #define VIGRA_TEST_CASE(function) vigra::create_test_case(function, #function "()")
104 #define testCase VIGRA_TEST_CASE
106 #define VIGRA_TEST_SUITE(testsuite) ( new testsuite )
108 #define VIGRA_CHECKPOINT(message) \
109 vigra::detail::checkpoint_impl(message, __FILE__, __LINE__)
111 #define VIGRA_ASSERT(predicate) \
112 vigra::detail::should_impl((predicate), #predicate, __FILE__, __LINE__)
114 #define VIGRA_ASSERT_NOT(predicate) \
115 vigra::detail::should_impl(!(predicate), "!(" #predicate ")", __FILE__, __LINE__)
117 #define should VIGRA_ASSERT
119 #define shouldNot VIGRA_ASSERT_NOT
121 #define VIGRA_ASSERT_MESSAGE(predicate, message) \
122 vigra::detail::should_impl((predicate), message, __FILE__, __LINE__)
124 #define shouldMsg VIGRA_ASSERT_MESSAGE
126 #define shouldMessage VIGRA_ASSERT_MESSAGE
128 #define shouldEqual(left, right) \
129 vigra::detail::equal_impl(left, right, #left " == " #right, __FILE__, __LINE__)
131 #define shouldEqualMessage(left, right, message) \
132 vigra::detail::equal_impl(left, right, message "\n" #left " == " #right, __FILE__, __LINE__)
134 #define shouldEqualTolerance(left, right, eps) \
135 vigra::detail::tolerance_equal_impl(left, right, eps, #left " == " #right, __FILE__, __LINE__)
137 #define shouldEqualToleranceMessage(left, right, eps, message) \
138 vigra::detail::tolerance_equal_impl(left, right, eps, message "\n" #left " == " #right, __FILE__, __LINE__)
140 #define shouldEqualSequence(begin1, end1, begin2) \
141 vigra::detail::sequence_equal_impl(begin1, end1, begin2, __FILE__, __LINE__)
143 #define shouldEqualSequenceTolerance(begin1, end1, begin2, eps) \
144 vigra::detail::sequence_equal_tolerance_impl(begin1, end1, begin2, eps, __FILE__, __LINE__)
146 #define VIGRA_ERROR(message) \
147 vigra::detail::should_impl(false, message, __FILE__, __LINE__)
149 #define failTest VIGRA_ERROR
152 #pragma GCC diagnostic push
153 #pragma GCC diagnostic ignored "-Wsign-compare"
162 typedef std::pair<std::string, int> CheckpointType;
167 std::string str() {
return VIGRA_SSTREAM_STR(buf); }
169 errstream & operator<<(T t) { buf << t;
return *
this; }
172 inline CheckpointType & exception_checkpoint()
174 static CheckpointType test_checkpoint_;
175 return test_checkpoint_;
179 inline void report_exception( detail::errstream & os,
180 const char * name,
const char * info )
182 os <<
"Unexpected " << name <<
" " << info <<
"\n";
183 if(exception_checkpoint().first.size() > 0)
185 os <<
" (occured after line " << exception_checkpoint().second <<
" in file '" << exception_checkpoint().first <<
"')\n";
190 unexpected_exception = -1,
192 memory_access_violation = -3,
193 destructor_failure = -4
196 inline bool critical_error(
int i)
197 {
return i <= memory_access_violation; }
199 inline bool unexpected_error(
int i)
202 #ifndef VIGRA_CANT_CATCH_SIGNALS
206 inline long handle_signal_here(
long code)
210 case EXCEPTION_ACCESS_VIOLATION:
211 case EXCEPTION_INT_DIVIDE_BY_ZERO:
212 return EXCEPTION_EXECUTE_HANDLER;
214 return EXCEPTION_CONTINUE_SEARCH;
218 template<
class Generator >
219 int catch_signals( Generator function_object, detail::errstream & err,
int timeout )
225 result = function_object();
227 __except (handle_signal_here(code = GetExceptionCode()))
231 case EXCEPTION_ACCESS_VIOLATION:
232 report_exception(err,
"operating system exception:",
"memory access violation");
233 result = memory_access_violation;
235 case EXCEPTION_INT_DIVIDE_BY_ZERO:
236 report_exception(err,
"operating system exception:",
"integer divide by zero");
237 result = os_exception;
240 report_exception(err,
"operating system exception:",
"unrecognized exception or signal");
241 result = os_exception;
249 #elif defined(__unix)
251 inline jmp_buf & unit_test_jump_buffer()
253 static jmp_buf unit_test_jump_buffer_;
254 return unit_test_jump_buffer_;
257 static void unit_test_signal_handler(
int sig)
259 longjmp(unit_test_jump_buffer(), sig);
262 template<
class Generator >
263 int catch_signals( Generator function_object, detail::errstream & err,
int timeout)
265 volatile int sigtype;
268 #if defined(linux) || defined(__linux)
269 signal(SIGFPE, &unit_test_signal_handler);
270 signal(SIGTRAP, &unit_test_signal_handler);
271 signal(SIGSEGV, &unit_test_signal_handler);
272 signal(SIGBUS, &unit_test_signal_handler);
274 sigset(SIGFPE, &unit_test_signal_handler);
275 sigset(SIGTRAP, &unit_test_signal_handler);
276 sigset(SIGSEGV, &unit_test_signal_handler);
277 sigset(SIGBUS, &unit_test_signal_handler);
282 #if defined(linux) || defined(__linux)
283 signal(SIGALRM, &unit_test_signal_handler);
285 sigset(SIGALRM, &unit_test_signal_handler);
290 sigtype = setjmp(unit_test_jump_buffer());
293 result = function_object();
300 report_exception(err,
"signal:",
"SIGALRM (timeout while executing function)");
301 result = os_exception;
304 report_exception(err,
"signal:",
"SIGTRAP (perhaps integer divide by zero)");
305 result = os_exception;
308 report_exception(err,
"signal:",
"SIGFPE (arithmetic exception)");
309 result = os_exception;
313 report_exception(err,
"signal:",
"memory access violation");
314 result = memory_access_violation;
317 report_exception(err,
"signal:",
"unrecognized signal");
318 result = os_exception;
325 #if defined(linux) || defined(__linux)
331 #if defined(linux) || defined(__linux)
346 template<
class Generator >
347 int catch_signals( Generator function_object, detail::errstream & err ,
int)
349 return function_object();
356 template<
class Generator >
357 int catch_exceptions( Generator function_object, detail::errstream & err,
int timeout )
359 int result = detail::unexpected_exception;
363 result = detail::catch_signals(function_object, err, timeout);
374 catch ( vigra::ContractViolation & ex )
375 { detail::report_exception( err,
"Contract exception: ", ex.what() ); }
376 catch (
const char * ex )
377 { detail::report_exception( err,
"string exception: ", ex ); }
378 catch (
const std::string & ex )
379 { detail::report_exception( err,
"string exception: ", ex.c_str() ); }
382 catch (
const std::bad_alloc & ex )
383 { detail::report_exception( err,
"exception: std::bad_alloc:", ex.what() ); }
385 # if !defined(__BORLANDC__) || __BORLANDC__ > 0x0551
386 catch (
const std::bad_cast & ex )
387 { detail::report_exception( err,
"exception: std::bad_cast:", ex.what() ); }
388 catch (
const std::bad_typeid & ex )
389 { detail::report_exception( err,
"exception: std::bad_typeid:", ex.what() ); }
391 catch (
const std::bad_cast & ex )
392 { detail::report_exception( err,
"exception: std::bad_cast",
"" ); }
393 catch (
const std::bad_typeid & ex )
394 { detail::report_exception( err,
"exception: std::bad_typeid",
"" ); }
397 catch (
const std::bad_exception & ex )
398 { detail::report_exception( err,
"exception: std::bad_exception:", ex.what() ); }
399 catch (
const std::domain_error & ex )
400 { detail::report_exception( err,
"exception: std::domain_error:", ex.what() ); }
401 catch (
const std::invalid_argument & ex )
402 { detail::report_exception( err,
"exception: std::invalid_argument:", ex.what() ); }
403 catch (
const std::length_error & ex )
404 { detail::report_exception( err,
"exception: std::length_error:", ex.what() ); }
405 catch (
const std::out_of_range & ex )
406 { detail::report_exception( err,
"exception: std::out_of_range:", ex.what() ); }
407 catch (
const std::range_error & ex )
408 { detail::report_exception( err,
"exception: std::range_error:", ex.what() ); }
409 catch (
const std::overflow_error & ex )
410 { detail::report_exception( err,
"exception: std::overflow_error:", ex.what() ); }
411 catch (
const std::underflow_error & ex )
412 { detail::report_exception( err,
"exception: std::underflow_error:", ex.what() ); }
413 catch (
const std::logic_error & ex )
414 { detail::report_exception( err,
"exception: std::logic_error:", ex.what() ); }
415 catch (
const std::runtime_error & ex )
416 { detail::report_exception( err,
"exception: std::runtime_error:", ex.what() ); }
417 catch (
const std::exception & ex )
418 { detail::report_exception( err,
"exception: std::exception:", ex.what() ); }
422 detail::report_exception( err,
"unknown exception",
"" );
429 template<
class Generator >
431 int catch_exceptions( Generator function_object, detail::errstream & err)
433 return catch_exceptions(function_object, err, 0);
438 struct unit_test_failed
439 :
public std::exception
441 unit_test_failed(std::string
const & message)
445 virtual ~unit_test_failed() throw()
449 virtual const char * what()
const throw()
451 return what_.c_str();
458 checkpoint_impl(
const char * file,
int line)
460 exception_checkpoint().first = file;
461 exception_checkpoint().second = line;
465 should_impl(
bool predicate,
const char * message,
const char * file,
int line)
467 checkpoint_impl(file, line);
470 detail::errstream buf;
471 buf << message <<
" (" << file <<
":" << line <<
")";
472 throw unit_test_failed(buf.str());
477 should_impl(
bool predicate, std::string
const & message,
const char * file,
int line)
479 should_impl(predicate, message.c_str(), file, line);
482 template <
class Iter1,
class Iter2>
484 sequence_equal_impl(Iter1 i1, Iter1 end1, Iter2 i2,
const char * file,
int line)
486 checkpoint_impl(file, line);
487 for(
int counter = 0; i1 != end1; ++i1, ++i2, ++counter)
491 detail::errstream buf;
492 buf <<
"Sequences differ at index " << counter <<
493 " ["<< *i1 <<
" != " << *i2 <<
"]";
494 should_impl(
false, buf.str().c_str(), file, line);
503 struct ScalarType {};
504 struct VectorType {};
509 typedef VectorType ScalarOrVector;
513 struct FloatTraits<float>
515 typedef ScalarType ScalarOrVector;
516 static float epsilon() {
return FLT_EPSILON; }
517 static float smallestPositive() {
return FLT_MIN; }
518 static float min() {
return -FLT_MAX; }
519 static float max() {
return FLT_MAX; }
523 struct FloatTraits<double>
525 typedef ScalarType ScalarOrVector;
526 static double epsilon() {
return DBL_EPSILON; }
527 static double smallestPositive() {
return DBL_MIN; }
528 static double min() {
return -DBL_MAX; }
529 static double max() {
return DBL_MAX; }
533 struct FloatTraits<long double>
535 typedef ScalarType ScalarOrVector;
536 static long double epsilon() {
return LDBL_EPSILON; }
537 static long double smallestPositive() {
return LDBL_MIN; }
538 static long double min() {
return -LDBL_MAX; }
539 static long double max() {
return LDBL_MAX; }
544 FPT fpt_abs( FPT
arg )
546 return arg < 0 ? -arg :
arg;
555 FPT safe_fpt_division( FPT f1, FPT f2 )
567 return ((f2 < 1) && (f1 > (f2 * FloatTraits<FPT>::max()))) ?
568 FloatTraits<FPT>::max() :
569 ((((f2 > 1) && (f1 < (f2 * FloatTraits<FPT>::smallestPositive())))
570 || (f1 == 0)) ? 0 : f1/f2 );
579 class close_at_tolerance {
581 explicit close_at_tolerance( FPT tolerance,
bool strong_test =
true )
582 : m_strong_test( strong_test ),
583 m_tolerance( tolerance ) {}
585 explicit close_at_tolerance(
int number_of_rounding_errors,
bool strong_test =
true )
586 : m_strong_test( strong_test ),
587 m_tolerance( FloatTraits<FPT>::epsilon() * number_of_rounding_errors / 2.0 ) {}
589 bool operator()( FPT left, FPT right )
const
591 if (left == 0 && right != 0)
593 return (fpt_abs(right) <= m_tolerance);
595 if (right == 0 && left != 0)
597 return (fpt_abs(left) <= m_tolerance);
599 FPT diff = fpt_abs( left - right );
600 FPT d1 = safe_fpt_division( diff, fpt_abs( right ) );
601 FPT d2 = safe_fpt_division( diff, fpt_abs( left ) );
603 return m_strong_test ? (d1 <= m_tolerance && d2 <= m_tolerance)
604 : (d1 <= m_tolerance || d2 <= m_tolerance);
614 template <
class T1,
class T2,
class T3>
616 tolerance_equal_impl(T1 left, T2 right, T3 epsilon,
617 const char * message,
const char * file,
int line, ScalarType, std::ptrdiff_t index = -1)
619 checkpoint_impl(file, line);
620 close_at_tolerance<T3> fcomparator( epsilon );
621 if (!fcomparator((T3)left, (T3)right))
623 detail::errstream buf;
625 buf <<
"Sequences differ at index " << index;
626 buf << message <<
" [" << std::setprecision(17) << left <<
" != " << right <<
" at tolerance " << epsilon <<
"]";
627 should_impl(
false, buf.str().c_str(), file, line);
631 template <
class T1,
class T2,
class T3>
633 tolerance_equal_impl(T1 left, T2 right, T3 epsilon,
634 const char * message,
const char * file,
int line, VectorType, std::ptrdiff_t index = -1)
636 checkpoint_impl(file, line);
637 for(
unsigned int i=0; i<epsilon.size(); ++i)
639 close_at_tolerance<typename T3::value_type> fcomparator( epsilon[i] );
640 if (!fcomparator(left[i], right[i]))
642 detail::errstream buf;
645 buf <<
"Sequences differ at index " << index <<
", element " << i;
649 buf <<
"Vectors differ at element " << i;
651 buf << message <<
" [" << std::setprecision(17) << left <<
" != " << right <<
" at tolerance " << epsilon <<
"]";
652 should_impl(
false, buf.str().c_str(), file, line);
657 template <
class T1,
class T2,
class T3>
659 tolerance_equal_impl(T1 left, T2 right, T3 epsilon,
const char * message,
const char * file,
int line)
661 tolerance_equal_impl(left, right, epsilon,
662 message, file, line,
typename FloatTraits<T3>::ScalarOrVector());
665 template <
class Iter1,
class Iter2,
class T>
667 sequence_equal_tolerance_impl(Iter1 i1, Iter1 end1, Iter2 i2, T epsilon,
const char * file,
int line)
669 for(
int counter = 0; i1 != end1; ++i1, ++i2, ++counter)
671 tolerance_equal_impl(*i1, *i2, epsilon,
"", file, line,
typename FloatTraits<T>::ScalarOrVector(), counter);
675 template <
class Left,
class Right>
677 equal_impl(Left left, Right right,
const char * message,
const char * file,
int line)
679 checkpoint_impl(file, line);
682 detail::errstream buf;
683 buf << message <<
" [" << left <<
" != " << right <<
"]";
684 should_impl(
false, buf.str().c_str(), file, line);
688 template <
class Left,
class Right>
690 equal_impl(Left * left, Right * right,
const char * message,
const char * file,
int line)
692 checkpoint_impl(file, line);
695 detail::errstream buf;
696 buf << message <<
" [" << (
void*)left <<
" != " << (
void*)right << "]";
697 should_impl(false, buf.str().c_str(), file, line);
702 equal_impl(
double left,
double right, const
char * message, const
char * file,
int line)
704 tolerance_equal_impl(left, right, 1.0e-16, message, file, line);
708 equal_impl(
float left,
float right,
const char * message,
const char * file,
int line)
710 tolerance_equal_impl(left, right, 1.0e-6f, message, file, line);
714 equal_impl(
float left,
double right,
const char * message,
const char * file,
int line)
716 tolerance_equal_impl(left, right, 1.0e-6f, message, file, line);
720 equal_impl(
double left,
float right,
const char * message,
const char * file,
int line)
722 tolerance_equal_impl(left, right, 1.0e-6f, message, file, line);
729 test_case(
char const * name =
"Unnamed")
730 : name_(name), timeout(0)
733 virtual ~test_case() {}
735 virtual int run() {
return run(std::vector<std::string>()); }
736 virtual int run(std::vector<std::string>
const & testsToBeRun) = 0;
737 virtual void do_init() {}
738 virtual void do_run() {}
739 virtual void do_destroy() {}
741 virtual char const * name() {
return name_.c_str(); }
742 virtual int size()
const {
return 1; }
744 virtual int numberOfTestsToRun(std::vector<std::string>
const & testsToBeRun)
const
746 if(testsToBeRun.empty())
748 for(
unsigned int k=0; k<testsToBeRun.size(); ++k)
749 if(this->name_.find(testsToBeRun[k]) != std::string::npos)
762 std::vector<std::string> testsToBeExecuted(
int argc,
char ** argv)
764 std::vector<std::string> res;
765 for(
int i=1; i < argc; ++i)
766 res.push_back(std::string(argv[i]));
771 :
public detail::test_case
774 using detail::test_case::run;
776 test_suite(
char const * name =
"TopLevel")
777 : detail::test_case(name),
781 virtual ~test_suite()
783 for(
unsigned int i=0; i != testcases_.size(); ++i)
784 delete testcases_[i];
787 virtual void add(detail::test_case * t,
int timeout = 0)
789 t->timeout = timeout;
790 testcases_.push_back(t);
794 virtual int run(std::vector<std::string>
const & testsToBeRun)
796 int size = numberOfTestsToRun(testsToBeRun);
798 std::vector<std::string> testsToBeRunRecursive =
801 : std::vector<std::string>();
804 report_ = std::string(
"Entering test suite ") + name() +
"\n";
806 for(
unsigned int i=0; i != testcases_.size(); ++i)
808 int result = testcases_[i]->run(testsToBeRunRecursive);
809 report_ += testcases_[i]->report_;
811 if(detail::critical_error(result))
813 report_ += std::string(
"\nFatal error - aborting test suite ") + name() +
".\n";
816 else if(detail::unexpected_error(result))
824 detail::errstream buf;
825 buf <<
"\n" << failed <<
" of " << size <<
826 " tests failed in test suite " << name() <<
"\n";
827 report_ += buf.str();
831 detail::errstream buf;
832 buf <<
"All (" << size <<
833 ") tests passed in test suite " << name() <<
"\n";
834 report_ += buf.str();
837 report_ += std::string(
"Leaving test suite ") + name() +
"\n";
842 virtual int numberOfTestsToRun(std::vector<std::string>
const & testsToBeRun)
const
844 if(detail::test_case::numberOfTestsToRun(testsToBeRun) > 0)
847 for(
unsigned int i=0; i != testcases_.size(); ++i)
848 size += testcases_[i]->numberOfTestsToRun(testsToBeRun);
852 virtual int size()
const {
return size_; }
853 virtual std::string report() {
return report_; }
855 std::vector<detail::test_case *> testcases_;
861 struct test_case_init_functor
863 detail::errstream & buf_;
864 test_case * test_case_;
866 test_case_init_functor(detail::errstream & b, test_case * tc)
867 : buf_(b), test_case_(tc)
874 test_case_->do_init();
877 catch(unit_test_failed & e)
879 buf_ <<
"Assertion failed: " << e.what() <<
"\n";
885 struct test_case_run_functor
887 detail::errstream & buf_;
888 test_case * test_case_;
890 test_case_run_functor(detail::errstream & b, test_case * tc)
891 : buf_(b), test_case_(tc)
898 test_case_->do_run();
901 catch(unit_test_failed & e)
903 buf_ <<
"Assertion failed: " << e.what() <<
"\n";
909 struct test_case_destroy_functor
911 detail::errstream & buf_;
912 test_case * test_case_;
914 test_case_destroy_functor(detail::errstream & b, test_case * tc)
915 : buf_(b), test_case_(tc)
922 test_case_->do_destroy();
925 catch(unit_test_failed & e)
927 buf_ <<
"Assertion failed: " << e.what() <<
"\n";
933 template <
class TESTCASE>
934 class class_test_case
938 using test_case::run;
940 class_test_case(
void (TESTCASE::*fct)(),
char const * name)
946 virtual ~class_test_case()
951 virtual void do_init()
953 testcase_ =
new TESTCASE;
958 exception_checkpoint().first =
"";
962 detail::errstream buf;
963 buf <<
"\nFailure in initialization of " << name() <<
"\n";
966 buf <<
"Test case failed to clean up after previous run.\n";
971 failed = catch_exceptions(
972 detail::test_case_init_functor(buf,
this), buf, timeout);
977 report_ += buf.str();
983 virtual void do_run()
986 (testcase_->*fct_)();
989 virtual int run(std::vector<std::string>
const & testsToBeRun)
991 if(numberOfTestsToRun(testsToBeRun) == 0)
999 detail::errstream buf;
1000 buf <<
"\nFailure in " << name() <<
"\n";
1002 failed = catch_exceptions(
1003 detail::test_case_run_functor(buf,
this), buf, timeout);
1005 report_ += buf.str();
1007 if(critical_error(failed))
1010 int destruction_failed = destroy();
1012 return destruction_failed ?
1013 destruction_failed :
1017 virtual void do_destroy()
1025 detail::errstream buf;
1026 buf <<
"\nFailure in destruction of " <<
"\n";
1028 int failed = catch_exceptions(
1029 detail::test_case_destroy_functor(buf,
this), buf, timeout);
1032 report_ += buf.str();
1033 return destructor_failure;
1041 void (TESTCASE::*fct_)();
1042 TESTCASE * testcase_;
1045 class function_test_case
1049 using test_case::run;
1051 function_test_case(
void (*fct)(),
char const * name)
1056 virtual void do_run()
1061 virtual int run(std::vector<std::string>
const & testsToBeRun)
1063 if(numberOfTestsToRun(testsToBeRun) == 0)
1067 exception_checkpoint().first =
"";
1069 detail::errstream buf;
1070 buf <<
"\nFailure in " << name() <<
"\n";
1072 int failed = catch_exceptions(
1073 detail::test_case_run_functor(buf,
this), buf, timeout);
1076 report_ += buf.str();
1085 template <
class FCT>
1088 virtual ~test_functor() {}
1089 virtual void operator()() = 0;
1092 {
return FCT(static_cast<FCT const &>(*
this)); }
1095 template <
class FCT>
1096 class functor_test_case
1100 using test_case::run;
1102 functor_test_case(FCT
const & fct,
char const * name)
1107 virtual void do_run()
1112 virtual int run(std::vector<std::string>
const & testsToBeRun)
1114 if(numberOfTestsToRun(testsToBeRun) == 0)
1118 exception_checkpoint().first =
"";
1120 detail::errstream buf;
1121 buf <<
"\nFailure in " << name() <<
"\n";
1123 int failed = catch_exceptions(
1124 detail::test_case_run_functor(buf,
this), buf, timeout);
1127 report_ += buf.str();
1138 template <
class TESTCASE>
1141 create_test_case(
void (TESTCASE::*fct)(),
char const * name)
1143 if(*name ==
'&') ++name;
1144 return new detail::class_test_case<TESTCASE>(fct, name);
1149 create_test_case(
void (*fct)(),
char const * name)
1151 if(*name ==
'&') ++name;
1152 return new detail::function_test_case(fct, name);
1155 template <
class FCT>
1158 create_test_case(detail::test_functor<FCT>
const & fct,
char const * name)
1160 if(*name ==
'&') ++name;
1161 return new detail::functor_test_case<FCT>(fct.clone(), name);
1167 #if !defined(__GNUC__) || __GNUC__ >= 3
1171 template <
class E,
class T,
class V>
1173 std::basic_ostream<E,T> & operator,(std::basic_ostream<E,T> & o, V
const & t)
1175 return (o <<
' ' << t);
1178 template <
class E,
class T>
1180 std::basic_ostream<E,T> & operator,(std::basic_ostream<E,T> & o,
1181 std::basic_ostream<E,T> & (*t)(std::basic_ostream<E,T> &))
1190 std::ostream & operator,(std::ostream & o, V
const & t)
1192 return (o <<
' ' << t);
1196 std::ostream & operator,(std::ostream & o,
1197 std::ostream & (*t)(std::ostream &))
1205 #pragma GCC diagnostic pop
R arg(const FFTWComplex< R > &a)
phase
Definition: fftw3.hxx:1009
void add(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r, FixedPoint< IntBits3, FracBits3 > &result)
addition with enforced result type.
Definition: fixedpoint.hxx:561