├── cevelop-workspace └── PSsstTests │ ├── src │ ├── pssst.h │ ├── xxx.h │ ├── Degrees.h │ ├── OhmsLaw.h │ ├── BooleanTest.h │ ├── Consumption.h │ ├── DoubleErsatz.h │ ├── EnumOperators.h │ ├── SafeArithmetic.h │ ├── StringOperations.h │ ├── BitOperationsTest.h │ ├── ArraySizeDiffStrong.h │ ├── StrongWithConstructor.h │ ├── StrongWithEncapsulation.h │ ├── ArithmeticOperationsTest.h │ ├── ConsumptionWithoutStrong.h │ ├── xxx.cpp │ ├── DoubleErsatz.cpp │ ├── StringOperations.cpp │ ├── SafeArithmetic.cpp │ ├── StrongWithConstructor.cpp │ ├── OhmsLaw.cpp │ ├── ConsumptionWithoutStrong.cpp │ ├── StrongWithEncapsulation.cpp │ ├── pssst_enum_iter.h │ ├── EnumOperators.cpp │ ├── BitOperationsTest.cpp │ ├── Degrees.cpp │ ├── Consumption.cpp │ ├── pssst_static_tests.cpp │ ├── Test.cpp │ ├── ArithmeticOperationsTest.cpp │ ├── BooleanTest.cpp │ └── ArraySizeDiffStrong.cpp │ ├── .project │ ├── cute │ ├── cute_version.h │ ├── cute.h │ ├── cute_listener.h │ ├── cute_determine_version.h │ ├── cute_suite.h │ ├── cute_determine_traits.h │ ├── cute_suite_test.h │ ├── cute_determine_library.h │ ├── cute_repeated_test.h │ ├── cute_xml_file.h │ ├── cute_deprecated.h │ ├── cute_diff_values.h │ ├── cute_test.h │ ├── cute_throws.h │ ├── cute_counting_listener.h │ ├── cute_test_incarnate.h │ ├── ostream_listener.h │ ├── cute_range.h │ ├── cute_base.h │ ├── tap_listener.h │ ├── cute_integer_sequence.h │ ├── cute_relops.h │ ├── ide_listener.h │ ├── cute_testmember.h │ ├── xml_listener.h │ ├── cute_data_driven.h │ ├── cute_demangle.h │ ├── cute_runner.h │ ├── cute_equals.h │ └── cute_to_string.h │ └── .cproject ├── .gitignore ├── LICENSE └── README.md /cevelop-workspace/PSsstTests/src/pssst.h: -------------------------------------------------------------------------------- 1 | ../../../pssst.h -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/xxx.h: -------------------------------------------------------------------------------- 1 | #ifndef XXX_H_ 2 | #define XXX_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_xxx(); 7 | 8 | #endif /* XXX_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/Degrees.h: -------------------------------------------------------------------------------- 1 | #ifndef DEGREES_H_ 2 | #define DEGREES_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_Degrees(); 7 | 8 | #endif /* DEGREES_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/OhmsLaw.h: -------------------------------------------------------------------------------- 1 | #ifndef OHMSLAW_H_ 2 | #define OHMSLAW_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_OhmsLaw(); 7 | 8 | #endif /* OHMSLAW_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/BooleanTest.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOLEANTEST_H_ 2 | #define BOOLEANTEST_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_BooleanTest(); 7 | 8 | #endif /* BOOLEANTEST_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/Consumption.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSUMPTION_H_ 2 | #define CONSUMPTION_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_Consumption(); 7 | 8 | #endif /* CONSUMPTION_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/DoubleErsatz.h: -------------------------------------------------------------------------------- 1 | #ifndef DOUBLEERSATZ_H_ 2 | #define DOUBLEERSATZ_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_DoubleErsatz(); 7 | 8 | #endif /* DOUBLEERSATZ_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/EnumOperators.h: -------------------------------------------------------------------------------- 1 | #ifndef ENUMOPERATORS_H_ 2 | #define ENUMOPERATORS_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_EnumOperators(); 7 | 8 | #endif /* ENUMOPERATORS_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/SafeArithmetic.h: -------------------------------------------------------------------------------- 1 | #ifndef SAFEARITHMETIC_H_ 2 | #define SAFEARITHMETIC_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_SafeArithmetic(); 7 | 8 | #endif /* SAFEARITHMETIC_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/StringOperations.h: -------------------------------------------------------------------------------- 1 | #ifndef STRINGOPERATIONS_H_ 2 | #define STRINGOPERATIONS_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_StringOperations(); 7 | 8 | #endif /* STRINGOPERATIONS_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/BitOperationsTest.h: -------------------------------------------------------------------------------- 1 | #ifndef BITOPERATIONSTEST_H_ 2 | #define BITOPERATIONSTEST_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_BitOperationsTest(); 7 | 8 | #endif /* BITOPERATIONSTEST_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/ArraySizeDiffStrong.h: -------------------------------------------------------------------------------- 1 | #ifndef ARRAYSIZEDIFFSTRONG_H_ 2 | #define ARRAYSIZEDIFFSTRONG_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_ArraySizeDiffStrong(); 7 | 8 | #endif /* ARRAYSIZEDIFFSTRONG_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/StrongWithConstructor.h: -------------------------------------------------------------------------------- 1 | #ifndef STRONGWITHCONSTRUCTOR_H_ 2 | #define STRONGWITHCONSTRUCTOR_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_StrongWithConstructor(); 7 | 8 | #endif /* STRONGWITHCONSTRUCTOR_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/StrongWithEncapsulation.h: -------------------------------------------------------------------------------- 1 | #ifndef STRONGWITHENCAPSULATION_H_ 2 | #define STRONGWITHENCAPSULATION_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_StrongWithEncapsulation(); 7 | 8 | #endif /* STRONGWITHENCAPSULATION_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/ArithmeticOperationsTest.h: -------------------------------------------------------------------------------- 1 | #ifndef ARITHMETICOPERATIONSTEST_H_ 2 | #define ARITHMETICOPERATIONSTEST_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_ArithmeticOperationsTest(); 7 | 8 | #endif /* ARITHMETICOPERATIONSTEST_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/ConsumptionWithoutStrong.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSUMPTIONWITHOUTSTRONG_H_ 2 | #define CONSUMPTIONWITHOUTSTRONG_H_ 3 | 4 | #include "cute_suite.h" 5 | 6 | extern cute::suite make_suite_ConsumptionWithoutStrong(); 7 | 8 | #endif /* CONSUMPTIONWITHOUTSTRONG_H_ */ 9 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/xxx.cpp: -------------------------------------------------------------------------------- 1 | #include "xxx.h" 2 | #include "cute.h" 3 | 4 | void thisIsAxxxTest() { 5 | ASSERTM("start writing tests", true); 6 | } 7 | 8 | cute::suite make_suite_xxx() { 9 | cute::suite s { }; 10 | s.push_back(CUTE(thisIsAxxxTest)); 11 | return s; 12 | } 13 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/DoubleErsatz.cpp: -------------------------------------------------------------------------------- 1 | #include "DoubleErsatz.h" 2 | #include "cute.h" 3 | 4 | #include "pssst.h" 5 | 6 | using namespace pssst; 7 | 8 | struct Double:Arithmetic{}; 9 | 10 | void thisIsADoubleErsatzTest() { 11 | Double d{42}; 12 | ASSERT_EQUAL(d,Double{6}*Double{7}); 13 | 14 | } 15 | 16 | cute::suite make_suite_DoubleErsatz() { 17 | cute::suite s { }; 18 | s.push_back(CUTE(thisIsADoubleErsatzTest)); 19 | return s; 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | .DS_Store 35 | 36 | Release 37 | Debug 38 | .metadata/ 39 | .settings/ 40 | #.cproject 41 | *Test.xml 42 | .*.html 43 | cevelop-workspace/PSsstTests/PSsstTests.xml 44 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | PSsstTests 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | ch.hsr.ifs.cute.ui.cutenature 23 | org.eclipse.cdt.core.cnature 24 | org.eclipse.cdt.core.ccnature 25 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 26 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 27 | 28 | 29 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/StringOperations.cpp: -------------------------------------------------------------------------------- 1 | #include "StringOperations.h" 2 | #include "cute.h" 3 | #include "pssst.h" 4 | 5 | #include 6 | 7 | #include 8 | 9 | using namespace pssst; 10 | 11 | 12 | struct Word:strong{ 13 | }; 14 | Word operator"" _w(char const * const s, size_t l){ 15 | return Word{std::string{s,l}}; 16 | } 17 | Word operator"" _w(char c){ 18 | return Word{std::string{c}}; 19 | } 20 | 21 | 22 | void thisIsAStringOperationsTest() { 23 | Word const w { "hello" }; 24 | std::ostringstream out{}; 25 | out << w; 26 | ASSERT_EQUAL("hello",out.str()); 27 | } 28 | 29 | void testStringWrapperCompare(){ 30 | Word h{"Hello"}; 31 | Word w{"World"}; 32 | ASSERT_LESS(h,w); 33 | 34 | } 35 | 36 | void testStringAdditionWorks(){ 37 | Word w{}; 38 | w += "Hello"_w; 39 | w += ' '_w; 40 | w = w + "World!"_w; 41 | ASSERT_EQUAL("Hello World!"_w, w); 42 | } 43 | 44 | 45 | 46 | cute::suite make_suite_StringOperations() { 47 | cute::suite s { }; 48 | s.push_back(CUTE(thisIsAStringOperationsTest)); 49 | s.push_back(CUTE(testStringWrapperCompare)); 50 | s.push_back(CUTE(testStringAdditionWorks)); 51 | return s; 52 | } 53 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/SafeArithmetic.cpp: -------------------------------------------------------------------------------- 1 | #include "SafeArithmetic.h" 2 | #include "cute.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | // TODO more tests beyond principle 10 | 11 | // safe numerics do not save us from the wrong operations... try differently first. 12 | // but we can detect overflowing operations 13 | 14 | using safe_diff_t = boost::safe_numerics::safe< std::ptrdiff_t, boost::safe_numerics::automatic >; 15 | using safe_size_t = boost::safe_numerics::safe< size_t >; 16 | 17 | void thisIsASafeArithmeticTest() { 18 | safe_size_t const sz { 0 }; 19 | //static_assert(std::is_signed_v,"should be signed"); 20 | static_assert(std::is_same_v,"staying in the domain?"); 21 | ASSERT_THROWS(sz-1,std::exception); 22 | } 23 | void newTestFunction(){ 24 | // ASSERTM("show more usages with strong types", false); 25 | } 26 | 27 | 28 | cute::suite make_suite_SafeArithmetic() { 29 | cute::suite s { }; 30 | s.push_back(CUTE(thisIsASafeArithmeticTest)); 31 | s.push_back(CUTE(newTestFunction)); 32 | return s; 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_version.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2008-2018 Peter Sommerlad, Emanuel Graf, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_VERSION_H_ 27 | #define CUTE_VERSION_H_ 28 | 29 | #define CUTE_LIB_VERSION "2.2.6" 30 | 31 | #endif /*CUTE_VERSION_H_*/ 32 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2006-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_H_ 27 | #define CUTE_H_ 28 | // all CUTE includes for writing tests and suites 29 | #include "cute_base.h" 30 | #include "cute_equals.h" 31 | #include "cute_relops.h" 32 | #include "cute_data_driven.h" 33 | #include "cute_throws.h" 34 | #include "cute_suite.h" 35 | #include "cute_repeated_test.h" 36 | #include "cute_suite_test.h" 37 | #include "cute_test_incarnate.h" 38 | #include "cute_test.h" 39 | #include "cute_testmember.h" 40 | #include "cute_version.h" 41 | #endif /*CUTE_H_*/ 42 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/StrongWithConstructor.cpp: -------------------------------------------------------------------------------- 1 | #include "StrongWithConstructor.h" 2 | #include "cute.h" 3 | #include "pssst.h" 4 | #include 5 | #include 6 | using namespace pssst; 7 | 8 | // possible but not well suited, needs separate thing, because 9 | 10 | namespace StrongWithConstructor{ 11 | // affine space: degrees (K and C) 12 | struct degrees: Linear{}; 13 | 14 | struct Kelvin: affine_space_for { 15 | using base = affine_space_for; 16 | constexpr Kelvin(value_type v): base{v} { 17 | if(v < value_type{} ) throw std::logic_error{"can not have negative K temperature"}; 18 | } 19 | constexpr Kelvin(vector_space v): base{v} { 20 | if(v < vector_space{value_type{}}|| v > vector_space{value_type{50}}) { 21 | std::cerr << "throwing ctor" << std::endl; 22 | 23 | throw std::logic_error{"can not have negative K temperature"}; 24 | 25 | } 26 | } 27 | }; 28 | 29 | static_assert(sizeof(Kelvin) == sizeof(Kelvin::vector_space::value_type)); 30 | 31 | void thisIsAKelvinDegreesTest() { 32 | degrees hotter{20}; 33 | Kelvin spring{15}; 34 | auto x = spring+hotter; 35 | ASSERT_EQUAL(Kelvin{35},x); 36 | } 37 | 38 | void KelvinNegativeThrows() { 39 | ASSERT_THROWS(Kelvin{-1}, std::logic_error); 40 | } 41 | 42 | void KelvinNegativeAfterOperationThrows() { 43 | Kelvin k{1}; 44 | ASSERT_THROWS((k-degrees{2}), std::logic_error); 45 | } 46 | 47 | void KelvinTooPositiveAfterOperationThrows() { 48 | Kelvin k{1}; 49 | try { 50 | ASSERT_THROWS((k+=degrees{50}), std::logic_error); 51 | }catch(...){} 52 | } 53 | 54 | 55 | } 56 | 57 | cute::suite make_suite_StrongWithConstructor() { 58 | cute::suite s { }; 59 | s.push_back(CUTE(StrongWithConstructor::thisIsAKelvinDegreesTest)); 60 | s.push_back(CUTE(StrongWithConstructor::KelvinNegativeThrows)); 61 | s.push_back(CUTE(StrongWithConstructor::KelvinNegativeAfterOperationThrows)); 62 | s.push_back(CUTE(StrongWithConstructor::KelvinTooPositiveAfterOperationThrows)); 63 | return s; 64 | } 65 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_listener.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_LISTENER_H_ 27 | #define CUTE_LISTENER_H_ 28 | #include "cute_base.h" 29 | #include "cute_suite.h" 30 | namespace cute { 31 | struct null_listener{ // defines Contract of runner parameter 32 | void begin(suite const &, char const * /*info*/, size_t /*n_of_tests*/){} 33 | void end(suite const &, char const * /*info*/){} 34 | void start(test const &){} 35 | void success(test const &,char const * /*msg*/){} 36 | void failure(test const &,test_failure const &){} 37 | void error(test const &,char const * /*what*/){} 38 | }; 39 | } 40 | #endif /* CUTE_LISTENER_H_ */ 41 | 42 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_determine_version.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_DETERMINE_VERSION_H_ 27 | #define CUTE_DETERMINE_VERSION_H_ 28 | 29 | #if __cplusplus >= 201103L && ! defined (USE_STD11) 30 | #define USE_STD11 1 31 | #endif 32 | 33 | #if defined(__GNUG__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && ! defined(USE_TR1) && ! defined(USE_STD11) 34 | #define USE_STD11 1 35 | #endif 36 | 37 | #ifdef _MSC_VER 38 | #if (_MSC_VER >= 1400) 39 | #define USE_STD11 1 40 | #endif 41 | #endif 42 | 43 | #if __cplusplus >= 201402L 44 | #define USE_STD14 45 | #endif 46 | 47 | #if __cplusplus >= 201703L 48 | #define USE_STD17 49 | #endif 50 | #endif /*CUTE_DETERMINE_VERSION_H_*/ 51 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_suite.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2006-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_SUITE_H_ 27 | #define CUTE_SUITE_H_ 28 | 29 | #include "cute_test.h" 30 | 31 | #include 32 | 33 | namespace cute { 34 | typedef std::vector suite; 35 | // convenience operator for appending to suites, might not be right 36 | // deprecated, not supported by plug-in, not needed with Eclipse plug-in 37 | inline 38 | suite &operator+=(suite &left, suite const &right){ 39 | left.insert(left.end(),right.begin(),right.end()); 40 | return left; 41 | } 42 | inline 43 | suite &operator+=(suite &left, test const &right){ 44 | left.push_back(right); 45 | return left; 46 | } 47 | } 48 | 49 | #endif /*CUTE_SUITE_H_*/ 50 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_determine_traits.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2013-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_DETERMINE_TRAITS_H_ 27 | #define CUTE_DETERMINE_TRAITS_H_ 28 | #include "cute_determine_version.h" 29 | #if defined(USE_STD11) 30 | #include 31 | #elif defined(USE_TR1) 32 | #include 33 | #else 34 | #include 35 | #include 36 | #include 37 | #endif 38 | #if defined(USE_STD11) 39 | namespace impl_place_for_traits = std; 40 | #elif defined(USE_TR1) 41 | namespace impl_place_for_traits = std::tr1; 42 | #else 43 | namespace impl_place_for_traits = boost; 44 | #endif 45 | 46 | #endif /* CUTE_DETERMINE_TRAITS_H_ */ 47 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_suite_test.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2006-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_SUITE_TEST_H_ 27 | #define CUTE_SUITE_TEST_H_ 28 | #include "cute_suite.h" 29 | #include "cute_determine_library.h" 30 | 31 | #include 32 | namespace cute{ 33 | // make a whole suite a test, failure stops the suite's execution 34 | struct suite_test { 35 | suite theSuite; 36 | suite_test(suite const &s):theSuite(s){} 37 | void operator()(){ 38 | std::for_each(theSuite.begin(),theSuite.end(),boost_or_tr1::bind(&test::operator(),_1)); 39 | } 40 | }; 41 | } 42 | #define CUTE_SUITE_TEST(s) cute::test(cute::suite_test((s)),#s) 43 | #define CUTE_SUITE_TEST_NAME(s, name) cute::test(cute::suite_test((s)),name) 44 | #endif /*CUTE_SUITE_TEST_H_*/ 45 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_determine_library.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_DETERMINE_LIBRARY_H_ 27 | #define CUTE_DETERMINE_LIBRARY_H_ 28 | #include "cute_determine_version.h" 29 | #if defined(USE_TR1) 30 | #include 31 | // bind already given by in cute_test.h from cute_suite.h 32 | namespace boost_or_tr1 = std::tr1; 33 | namespace cute { 34 | using namespace boost_or_tr1::placeholders; 35 | } 36 | #elif defined(USE_STD11) 37 | #include 38 | namespace boost_or_tr1 = std; 39 | namespace cute { 40 | using namespace boost_or_tr1::placeholders; 41 | } 42 | #else 43 | #include 44 | #include 45 | namespace boost_or_tr1 = boost; 46 | #endif 47 | 48 | #endif /*CUTE_DETERMINE_LIBRARY_H_*/ 49 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/OhmsLaw.cpp: -------------------------------------------------------------------------------- 1 | #include "OhmsLaw.h" 2 | #include "pssst.h" 3 | #include "cute.h" 4 | 5 | using namespace pssst; 6 | 7 | struct Voltage:Linear{}; 8 | struct Current:Linear{}; 9 | struct Resistance:Linear{}; 10 | 11 | constexpr Voltage operator""_V(unsigned long long val){ 12 | return Voltage{static_cast(val)}; 13 | } 14 | constexpr Voltage operator""_V(long double val){ 15 | return Voltage{static_cast(val)}; 16 | } 17 | constexpr Current operator""_A(unsigned long long val){ 18 | return Current{static_cast(val)}; 19 | } 20 | constexpr Current operator""_A(long double val){ 21 | return Current{static_cast(val)}; 22 | } 23 | constexpr Resistance operator""_Ohm(unsigned long long val){ 24 | return Resistance{static_cast(val)}; 25 | } 26 | constexpr Resistance operator""_Ohm(long double val){ 27 | return Resistance{static_cast(val)}; 28 | } 29 | constexpr Current operator/(Voltage v, Resistance r){ 30 | auto [vv] = v; 31 | auto [rr] = r; 32 | return { vv / rr } ; 33 | } 34 | constexpr Resistance operator/(Voltage v, Current c){ 35 | auto [vv] = v; 36 | auto [cc] = c; 37 | return { vv / cc } ; 38 | } 39 | constexpr Voltage operator*(Resistance r, Current c){ 40 | auto [rr] = r; 41 | auto [cc] = c; 42 | return { rr * cc } ; 43 | } 44 | constexpr Voltage operator*(Current c, Resistance r){ 45 | auto [rr] = r; 46 | auto [cc] = c; 47 | return { rr * cc } ; 48 | } 49 | 50 | void thisIsAOhmsLawTest() { 51 | auto result = 10_V/100_Ohm; 52 | ASSERT_EQUAL(0.1_A, result); 53 | } 54 | void testVoltageOverResistance(){ 55 | auto result = 10_V/0.1_A; 56 | ASSERT_EQUAL(100_Ohm, result); 57 | } 58 | void testCurrentTimesResistance(){ 59 | auto result = 100_Ohm * 0.1_A; 60 | ASSERT_EQUAL(10_V, result); 61 | 62 | } 63 | 64 | 65 | 66 | cute::suite make_suite_OhmsLaw() { 67 | cute::suite s { }; 68 | s.push_back(CUTE(thisIsAOhmsLawTest)); 69 | s.push_back(CUTE(testVoltageOverResistance)); 70 | s.push_back(CUTE(testCurrentTimesResistance)); 71 | return s; 72 | } 73 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_repeated_test.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2006-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_REPEATED_TEST_H_ 27 | #define CUTE_REPEATED_TEST_H_ 28 | 29 | #include "cute_test.h" 30 | 31 | namespace cute{ 32 | struct repeated_test { 33 | repeated_test(test const &t,unsigned int n):theTest(t),repetitions(n){} 34 | void operator()(){ 35 | for (unsigned int i=0;i 30 | #include 31 | 32 | namespace cute { 33 | struct xml_file_opener { 34 | std::string filename; 35 | std::ofstream out; 36 | xml_file_opener(int argc, char const *const* argv) 37 | :filename(argc>0&&argv[0]?basename(argv[0]):"testresult.xml") 38 | ,out(filename.c_str()){} 39 | std::string basename(std::string path){ 40 | #if defined( _MSC_VER ) || defined(__MINGW32__) 41 | char const sep='\\'; 42 | #else 43 | char const sep='/'; 44 | #endif 45 | std::string::size_type pos=path.find_last_of(sep,path.size()-1); 46 | if (pos != std::string::npos) path.erase(0,pos+1); 47 | path+=".xml"; 48 | return path; 49 | } 50 | }; 51 | } 52 | 53 | #endif /* CUTE_XML_FILE_H_ */ 54 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_deprecated.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2016-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_DEPRECATED_H_ 27 | #define CUTE_DEPRECATED_H_ 28 | 29 | #if __cplusplus >= 201402L 30 | #define DEPRECATE(orig, repl) [[deprecated ("Use "#repl" instead.")]] inline void orig() {} 31 | #elif defined(__GNUG__) 32 | #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 33 | #if GCC_VERSION >= 40500 || defined(__clang__) 34 | #define DEPRECATE(orig, repl) __attribute__((deprecated("Use "#repl" instead."))) inline void orig() {} 35 | #else 36 | #define DEPRECATE(orig, repl) __attribute__((deprecated)) inline void orig() {} 37 | #endif 38 | #elif defined(_MSC_VER) 39 | #define DEPRECATE(orig, repl) __declspec(deprecated(#orig" is deprecated, use "#repl" instead.")) inline void orig() {} 40 | #endif 41 | 42 | #ifdef DEPRECATE 43 | #define DEPRECATED(name) name() 44 | #endif 45 | 46 | #endif /*CUTE_DEPRECATED_H_*/ 47 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_diff_values.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2013-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_DIFF_VALUES_H_ 27 | #define CUTE_DIFF_VALUES_H_ 28 | #include "cute_to_string.h" 29 | namespace cute { 30 | // you could provide your own overload for diff_values for your app-specific types 31 | // be sure to use tabs as given below, then the CUTE eclipse plug-in will parse correctly 32 | template 33 | std::string diff_values(ExpectedValue const &expected 34 | , ActualValue const & actual 35 | , char const *left="expected" 36 | , char const *right="but was"){ 37 | // construct a simple message...to be parsed by IDE support 38 | std::string res; 39 | res += ' '; 40 | res += left; 41 | res+=":\t" + cute_to_string::backslashQuoteTabNewline(cute_to_string::to_string(expected))+'\t'; 42 | res += right; 43 | res +=":\t"+cute_to_string::backslashQuoteTabNewline(cute_to_string::to_string(actual))+'\t'; 44 | return res; 45 | } 46 | } 47 | 48 | #endif /* CUTE_DIFF_VALUES_H_ */ 49 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_test.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, Emanuel Graf, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_TEST_H_ 27 | #define CUTE_TEST_H_ 28 | 29 | #include "cute_determine_library.h" 30 | #include "cute_demangle.h" 31 | 32 | // make plain functions as tests more 'cute': 33 | namespace cute { 34 | 35 | struct test{ 36 | void operator()()const{ theTest(); } 37 | std::string name()const{ return name_;} 38 | 39 | 40 | // (real) functor types can (almost) spell their name 41 | // but a name can also be given explicitely, e.g. for CUTE() macro 42 | // for simple test functions 43 | template 44 | test(VoidFunctor const &t, std::string sname = demangle(typeid(VoidFunctor).name())) 45 | :name_(sname),theTest(t){} 46 | // separate overload to allow nicer C++11 initializers with {"name",lambda} 47 | template 48 | test(std::string sname,VoidFunctor const &t) 49 | :name_(sname),theTest(t){} 50 | 51 | private: 52 | std::string name_; 53 | boost_or_tr1::function theTest; 54 | }; 55 | 56 | } 57 | 58 | #define CUTE(name) cute::test((&name),(#name)) 59 | 60 | #endif /*CUTE_TEST_H_*/ 61 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_throws.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_THROWS_H_ 27 | #define CUTE_THROWS_H_ 28 | 29 | #include "cute_base.h" 30 | 31 | // should we allow arbitrary code and remove the parentheses around the macro expansion? 32 | // not now, strange compilation side-effects might result. 33 | namespace cute { 34 | namespace do_not_use_this_namespace { 35 | struct assert_throws_failure_exception { 36 | struct cute::test_failure original; 37 | assert_throws_failure_exception(std::string const &r,char const *f, int line): 38 | original(r,f, line){} 39 | }; 40 | } 41 | } 42 | 43 | #define ASSERT_THROWSM(anuncommonmessagetextparametername,code,exc) \ 44 | do { \ 45 | try { \ 46 | { code ; } \ 47 | throw cute::do_not_use_this_namespace::assert_throws_failure_exception((anuncommonmessagetextparametername),__FILE__,__LINE__); \ 48 | } catch(exc const &){ \ 49 | } catch(cute::do_not_use_this_namespace::assert_throws_failure_exception const &atf){throw atf.original;} \ 50 | } while(0) 51 | #define ASSERT_THROWS(code,exc) ASSERT_THROWSM(" expecting " #code " to throw " #exc,code,exc) 52 | 53 | #endif /*CUTE_THROWS_H_*/ 54 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_counting_listener.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_COUNTING_LISTENER_H_ 27 | #define CUTE_COUNTING_LISTENER_H_ 28 | #include "cute_listener.h" 29 | namespace cute{ 30 | template 31 | struct counting_listener:Listener{ 32 | counting_listener() 33 | :Listener() 34 | ,numberOfTests(0),successfulTests(0),failedTests(0),errors(0),numberOfSuites(0),numberOfTestsInSuites(0){} 35 | 36 | counting_listener(Listener const &s) 37 | :Listener(s) 38 | ,numberOfTests(0),successfulTests(0),failedTests(0),errors(0),numberOfSuites(0),numberOfTestsInSuites(0){} 39 | 40 | void begin(suite const &s,char const *info, size_t n_of_tests){ 41 | ++numberOfSuites; 42 | numberOfTestsInSuites+=n_of_tests; 43 | Listener::begin(s,info, n_of_tests); 44 | } 45 | void start(test const &t){ 46 | ++numberOfTests; 47 | Listener::start(t); 48 | } 49 | void success(test const &t,char const *msg){ 50 | ++successfulTests; 51 | Listener::success(t,msg); 52 | } 53 | void failure(test const &t,test_failure const &e){ 54 | ++failedTests; 55 | Listener::failure(t,e); 56 | } 57 | void error(test const &t,char const *what){ 58 | ++errors; 59 | Listener::error(t,what); 60 | } 61 | size_t numberOfTests; 62 | size_t successfulTests; 63 | size_t failedTests; 64 | size_t errors; 65 | size_t numberOfSuites; 66 | size_t numberOfTestsInSuites; 67 | 68 | }; 69 | } 70 | #endif /*CUTE_COUNTING_LISTENER_H_*/ 71 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_test_incarnate.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2006-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_TEST_INCARNATE_H_ 27 | #define CUTE_TEST_INCARNATE_H_ 28 | 29 | #include "cute_test.h" 30 | 31 | // idea blatantly stolen from Aeryn 32 | namespace cute { 33 | template 34 | struct test_incarnate { 35 | void operator()(){ 36 | TestFunctor()(); 37 | } 38 | }; 39 | // TODO: check if there are problems with references. 40 | template 41 | struct test_incarnate_with_context { 42 | test_incarnate_with_context(ContextObject context):theContext(context) 43 | {} 44 | test_incarnate_with_context(test_incarnate_with_context const &other):theContext(other.theContext){} // provide copy-ctor in case compiler will define it deleted 45 | void operator()(){ 46 | TestFunctor t(theContext);// wouldn't create temporary to call with ()() 47 | t(); 48 | } 49 | ContextObject theContext; 50 | }; 51 | template 52 | test make_incarnate_with_context(ContextObject obj){ 53 | return test(test_incarnate_with_context(obj),demangle(typeid(TestFunctor).name())); 54 | } 55 | } 56 | 57 | #define CUTE_INCARNATE(TestFunctor) cute::test(cute::test_incarnate(),cute::demangle(typeid(TestFunctor).name())) 58 | #define CUTE_INCARNATE_WITH_CONTEXT(TestFunctor,contextObject) cute::make_incarnate_with_context(contextObject) 59 | 60 | #endif /*CUTE_TEST_INCARNATE_H_*/ 61 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/ostream_listener.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef OSTREAM_LISTENER_H_ 27 | #define OSTREAM_LISTENER_H_ 28 | 29 | #include "cute_listener.h" 30 | 31 | #include 32 | 33 | namespace cute { 34 | // a "root" listener displaying output, use it as an example on how to build your own, e.g., for XML output 35 | template 36 | struct ostream_listener:Listener 37 | { 38 | std::ostream &out; 39 | public: 40 | ostream_listener(std::ostream &os=std::cerr):out(os) {} 41 | void begin(suite const &t,char const *info, size_t n_of_tests){ 42 | out << "beginning: " << info << std::endl; 43 | Listener::begin(t,info, n_of_tests); 44 | } 45 | void end(suite const &t, char const *info){ 46 | out << "ending: " << info << std::endl; 47 | Listener::end(t,info); 48 | } 49 | void start(test const &t){ 50 | out << "starting: " << t.name() << std::endl; 51 | Listener::start(t); 52 | } 53 | void success(test const &t, char const *msg){ 54 | out << t.name() << " " << msg << std::endl; 55 | Listener::success(t,msg); 56 | } 57 | void failure(test const &t,test_failure const &e){ 58 | out << std::dec << e.filename << ":" << e.lineno << ": testcase failed: " << e.reason << " in " << t.name() << std::endl; 59 | Listener::failure(t,e); 60 | } 61 | void error(test const &t, char const *what){ 62 | out << what << " in " << t.name() << std::endl; 63 | Listener::error(t,what); 64 | } 65 | }; 66 | } 67 | 68 | #endif /*OSTREAM_LISTENER_H_*/ 69 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/ConsumptionWithoutStrong.cpp: -------------------------------------------------------------------------------- 1 | #include "ConsumptionWithoutStrong.h" 2 | #include "pssst.h" 3 | #include "cute.h" 4 | 5 | using namespace pssst; 6 | namespace without{ 7 | struct literGas 8 | : ops{ 9 | double liter; 10 | }; 11 | 12 | 13 | struct literPer100km 14 | : ops{ 15 | double consuption; 16 | }; 17 | 18 | struct X: Eq{ 19 | int val; 20 | constexpr 21 | X(int v):val{v}{} 22 | }; 23 | 24 | static_assert(X{42} != X{43} && X{42} == X{42} ); 25 | 26 | struct kmDriven:ops::apply>{ 27 | double km; 28 | }; 29 | 30 | static_assert(sizeof(double)==sizeof(kmDriven)); 31 | 32 | 33 | namespace myliterals { 34 | constexpr literGas operator"" _l(long double value){ 35 | return literGas{{},static_cast>(value)}; 36 | } 37 | constexpr literGas operator"" _l(unsigned long long value){ 38 | return literGas{{},static_cast>(value)}; 39 | } 40 | constexpr kmDriven operator"" _km(long double value){ 41 | return kmDriven{{},static_cast>(value)}; 42 | } 43 | constexpr kmDriven operator"" _km(unsigned long long value){ 44 | return kmDriven{{},static_cast>(value)}; 45 | } 46 | } 47 | 48 | 49 | literPer100km consumption(literGas l, kmDriven km) { 50 | return {{},value(l)/value(km/100.0)}; 51 | } 52 | 53 | void testConsumption1over1(){ 54 | literGas const l {{},1} ; 55 | kmDriven const km {{}, 1 } ; 56 | ASSERT_EQUAL((literPer100km{{},100.0}),consumption(l,km)); 57 | } 58 | 59 | void testConsumption40over500(){ 60 | literGas const l {{}, 40 }; 61 | kmDriven const km {{}, 500 }; 62 | ASSERT_EQUAL((literPer100km{{},8.0}),consumption(l,km)); 63 | } 64 | 65 | void testConsumtionWithLiterals(){ 66 | using namespace myliterals; 67 | ASSERT_EQUAL((literPer100km{{},8.0}),consumption(40._l,500_km)); 68 | } 69 | 70 | namespace { 71 | // try mix-in without strong... 72 | 73 | 74 | 75 | struct liter : ops{ 76 | // needs ctor to avoid need for extra {} below 77 | constexpr explicit liter(double lit):l{lit}{}; 78 | double l{}; 79 | }; 80 | static_assert(sizeof(liter)==sizeof(double)); // ensure empty bases are squashed 81 | static_assert(std::is_trivially_copyable_v); // ensure efficient argument passing 82 | 83 | 84 | void testLiterWithoutStrong(){ 85 | liter l1 {43. }; 86 | liter l2 {42.1 }; 87 | l2 += liter{0.8}; 88 | ASSERT_EQUAL_DELTA(l1,l2,liter{0.11}); 89 | } 90 | } 91 | 92 | } 93 | cute::suite make_suite_ConsumptionWithoutStrong() { 94 | cute::suite s { }; 95 | s.push_back(CUTE(without::testConsumption1over1)); 96 | s.push_back(CUTE(without::testConsumption40over500)); 97 | s.push_back(CUTE(without::testLiterWithoutStrong)); 98 | s.push_back(CUTE(without::testConsumtionWithLiterals)); 99 | return s; 100 | } 101 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_range.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2015-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_RANGE_H_ 27 | #define CUTE_RANGE_H_ 28 | 29 | #include "cute_determine_version.h" 30 | 31 | #include 32 | #include 33 | #ifdef USE_STD11 34 | #include 35 | #endif 36 | 37 | namespace cute{ 38 | template 39 | struct range { 40 | typedef ForwardIterator const_iterator; // for to_stream dispatch 41 | typedef typename std::iterator_traits::value_type value_type; 42 | const_iterator const b; 43 | const_iterator const e; 44 | range(ForwardIterator bb,ForwardIterator ee):b(bb),e(ee){} 45 | const_iterator begin() const { return b; } 46 | const_iterator end() const { return e; } 47 | template 48 | bool operator==(RangeOrContainer const &other) const{ 49 | #ifdef USE_STD14 50 | return std::equal(begin(),end(),other.begin(),other.end()); 51 | #else 52 | if (std::distance(begin(),end())==std::distance(other.begin(),other.end())){ 53 | return std::equal(begin(),end(),other.begin()); 54 | } 55 | return false; 56 | #endif 57 | } 58 | }; 59 | template 60 | range make_range(ForwardIterator b, ForwardIterator e){ 61 | return range(b,e); 62 | } 63 | 64 | #ifdef USE_STD11 65 | template 66 | range::iterator> 67 | make_range(std::initializer_list const &il){ 68 | return range::iterator>(il.begin(),il.end()); 69 | } 70 | #endif 71 | } 72 | 73 | #endif /* CUTE_RANGE_H_ */ 74 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_base.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_BASE_H_ 27 | #define CUTE_BASE_H_ 28 | 29 | #include "cute_to_string.h" 30 | #include "cute_determine_version.h" 31 | 32 | #include 33 | 34 | namespace cute { 35 | struct test_failure { 36 | std::string reason; 37 | std::string filename; 38 | int lineno; 39 | 40 | test_failure(std::string const &r,char const *f, int line) 41 | :reason(r),filename(f),lineno(line) 42 | { } 43 | char const * what() const { return reason.c_str(); } 44 | }; 45 | } 46 | 47 | #if defined(USE_STD11) && !defined(_MSC_VER) 48 | #define CUTE_FUNCNAME_PREFIX std::string(__func__)+": " 49 | #else 50 | #if defined( _MSC_VER ) || defined(__GNUG__) 51 | //#if defined(USE_STD11) 52 | //#define CUTE_FUNCNAME_PREFIX 53 | // workaround doesn't work namespace { char const __FUNCTION__ []="lambda";} 54 | // MSC can not use lambdas outside of function bodies for tests. 55 | //#endif 56 | // use -D CUTE_FUNCNAME_PREFIX if you want to use non-local lambdas with test macros 57 | #if !defined(CUTE_FUNCNAME_PREFIX) 58 | #define CUTE_FUNCNAME_PREFIX std::string(__FUNCTION__)+": " 59 | #endif 60 | #else // could provide #defines for other compiler-specific extensions... need to experiment, i.e., MS uses __FUNCTION__ 61 | #define CUTE_FUNCNAME_PREFIX std::string("") 62 | #endif 63 | #endif 64 | #define ASSERTM(msg,cond) do { if (!(cond)) throw cute::test_failure(CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg),__FILE__,__LINE__);} while(false) 65 | #define ASSERT(cond) ASSERTM(#cond,cond) 66 | #define FAIL() ASSERTM("FAIL()",false) 67 | #define FAILM(msg) ASSERTM(msg,false) 68 | #endif /*CUTE_BASE_H_*/ 69 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/StrongWithEncapsulation.cpp: -------------------------------------------------------------------------------- 1 | #include "StrongWithEncapsulation.h" 2 | #include "cute.h" 3 | #include "pssst.h" 4 | using namespace pssst; 5 | 6 | template 7 | struct Strong { // can not merge ops here, because of initializers required for bases depending on incomplete type 8 | static_assert(std::is_object_v,"must keep real values - no references or incomplete types allowed"); 9 | using value_type=V; 10 | Strong(value_type v):val{v}{} 11 | 12 | // providig all overloads of get() breaks encapsulation anyway 13 | template 14 | constexpr value_type get() const & noexcept { return val; static_assert(N==0); } 15 | template 16 | constexpr value_type& get() & noexcept { return val;static_assert(N==0);} 17 | template 18 | constexpr value_type&& get() && noexcept { return std::move(val);static_assert(N==0);} 19 | template 20 | constexpr value_type get() const && noexcept { return std::move(val);static_assert(N==0);} 21 | 22 | private: 23 | V val; 24 | }; 25 | 26 | // not very useful for any subclass of Strong: 27 | 28 | namespace std{ 29 | template 30 | struct tuple_size>:std::integral_constant{}; 31 | 32 | template 33 | struct tuple_element<0,Strong> { 34 | using type = V; 35 | }; 36 | } 37 | 38 | // nneed at least tuple_size and tuple_element specializtaionts for every strong type 39 | // argh, would require macros, naahhh. 40 | struct TestStrong: Strong, ops{}; 41 | 42 | // would be nice if we could inject namespace-level type definitions in a foreign namespace for non-functions 43 | namespace std{ 44 | template <> 45 | struct tuple_size:std::integral_constant{}; 46 | template <> 47 | struct tuple_element<0,TestStrong> { 48 | using type = TestStrong::value_type; 49 | }; 50 | } 51 | 52 | // is all the scaffolding in place? 53 | 54 | template 55 | decltype(auto) access(S && s){ 56 | auto &&[x] = s; 57 | return (x); 58 | } 59 | 60 | 61 | void thisIsAStrongWithEncapsulationTest() { 62 | Strong x{42}; 63 | auto&& y = access(x); 64 | ASSERT_EQUAL(42.0,y); 65 | y+=1; 66 | ASSERT_EQUAL(43,y); 67 | //ASSERT_EQUAL(y,x.get()); // doesn't work 68 | } 69 | void testTestStrongStructuredBinding(){ 70 | TestStrong x{42}; 71 | auto&&y = access(x); 72 | ASSERT_EQUAL(42.0,y); 73 | y+=1; 74 | ASSERT_EQUAL(43,y); 75 | //ASSERT_EQUAL(y,x.get()); // doesn't work 76 | } 77 | 78 | void testTestStrongStructuredBindingXValue(){ 79 | TestStrong x{42}; 80 | auto&&y = access(std::move(x)); 81 | ASSERT_EQUAL(42.0,y); 82 | ASSERT_EQUAL(y,x.get()); 83 | ASSERT_EQUAL(TestStrong{42},x); 84 | } 85 | 86 | 87 | 88 | cute::suite make_suite_StrongWithEncapsulation() { 89 | cute::suite s { }; 90 | s.push_back(CUTE(thisIsAStrongWithEncapsulationTest)); 91 | s.push_back(CUTE(testTestStrongStructuredBinding)); 92 | s.push_back(CUTE(testTestStrongStructuredBindingXValue)); 93 | return s; 94 | } 95 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/tap_listener.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2017-2018 Felix Morgner 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef TAP_LISTENER_H_ 27 | #define TAP_LISTENER_H_ 28 | 29 | #include 30 | #include 31 | 32 | #include "cute_listener.h" 33 | 34 | namespace cute { 35 | 36 | template 37 | struct tap_listener : Listener { 38 | tap_listener(std::ostream & out = std::cout) : out(out),nofTests(0) { } 39 | 40 | ~tap_listener() { 41 | if (nofTests) { 42 | out << "1.." << nofTests << '\n'; 43 | } 44 | } 45 | 46 | void begin(suite const & suite, char const * info, size_t n_of_tests) { 47 | out << "# Starting suite '" << info << "' containing " << n_of_tests << " tests\n"; 48 | Listener::begin(suite, info, n_of_tests); 49 | } 50 | 51 | void end(suite const & suite, char const * info) { 52 | out << "# Ending suite '" << info << "'\n"; 53 | Listener::end(suite, info); 54 | } 55 | 56 | void start(test const & test) { 57 | ++nofTests; 58 | Listener::start(test); 59 | } 60 | 61 | void success(test const & test, char const * msg) { 62 | out << "ok " << nofTests << ' ' << test.name() << '\n'; 63 | Listener::success(test, msg); 64 | } 65 | 66 | void failure(test const & test, test_failure const & reason) { 67 | out << "not ok " << nofTests << ' ' << test.name() << '\n'; 68 | out << "# Assertion failed: " << reason.what() << '\n'; 69 | Listener::failure(test, reason); 70 | } 71 | 72 | void error(test const & test, char const * what) { 73 | out << "not ok " << nofTests << ' ' << test.name() << '\n'; 74 | out << "# Unexpected exception: " << what << '\n'; 75 | Listener::error(test, what); 76 | } 77 | 78 | private: 79 | std::ostream & out; 80 | std::size_t nofTests; 81 | }; 82 | 83 | } 84 | 85 | #endif /* TAP_LISTENER_H_ */ 86 | 87 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_integer_sequence.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2016-2018 Felix Morgner 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_INTEGER_SEQUENCE_H_ 27 | #define CUTE_INTEGER_SEQUENCE_H_ 28 | 29 | #include "cute_determine_version.h" 30 | 31 | #ifdef USE_STD14 32 | #include 33 | namespace cute { 34 | using std::index_sequence; 35 | using std::index_sequence_for; 36 | } 37 | #else 38 | #include 39 | namespace cute { 40 | namespace do_not_use_this_namespace { 41 | template 42 | struct integer_sequence { 43 | using type = integer_sequence; 44 | using value_type = IntType; 45 | static constexpr std::size_t size() { return sizeof...(Ints); } 46 | }; 47 | 48 | template 49 | struct flatten; 50 | 51 | template 52 | struct flatten, integer_sequence> 53 | : integer_sequence {}; 54 | 55 | template 56 | struct make_integer_sequence; 57 | 58 | template 59 | struct make_integer_sequence 60 | : integer_sequence{}; 61 | 62 | template 63 | struct make_integer_sequence 64 | : integer_sequence{}; 65 | 66 | template 67 | struct make_integer_sequence 68 | : flatten::type, 69 | typename make_integer_sequence::type>::type {}; 70 | 71 | template 72 | using make_index_sequence = make_integer_sequence; 73 | } 74 | 75 | template 76 | using index_sequence = do_not_use_this_namespace::integer_sequence; 77 | 78 | template 79 | using index_sequence_for = do_not_use_this_namespace::make_index_sequence; 80 | } 81 | #endif 82 | 83 | #endif //CUTE_INTEGER_SEQUENCE_H_ 84 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_relops.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2013-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_RELOPS_H_ 27 | #define CUTE_RELOPS_H_ 28 | 29 | #include "cute_base.h" 30 | #include "cute_diff_values.h" 31 | #include 32 | 33 | namespace cute { 34 | 35 | namespace cute_relops_detail{ 36 | template 37 | std::string compare_values(LeftValue const &left 38 | , RightValue const & right){ 39 | return cute::diff_values(left,right,"left","right"); 40 | } 41 | } 42 | template class RELOP,typename TL, typename TR> 43 | void assert_relop(TL const &left 44 | , TR const &right 45 | ,std::string const &msg 46 | ,char const *file 47 | ,int line) { 48 | if (RELOP()(left,right)) return; 49 | throw test_failure(msg + cute_relops_detail::compare_values(left,right),file,line); 50 | } 51 | 52 | } 53 | #define ASSERT_LESSM(msg,left,right) cute::assert_relop((left),(right),\ 54 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg),__FILE__,__LINE__) 55 | #define ASSERT_LESS(left,right) ASSERT_LESSM(#left " < " #right, (left),(right)) 56 | #define ASSERT_LESS_EQUALM(msg,left,right) cute::assert_relop((left),(right),\ 57 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg),__FILE__,__LINE__) 58 | #define ASSERT_LESS_EQUAL(left,right) ASSERT_LESS_EQUALM(#left " <= " #right, (left),(right)) 59 | #define ASSERT_GREATERM(msg,left,right) cute::assert_relop((left),(right),\ 60 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg),__FILE__,__LINE__) 61 | #define ASSERT_GREATER(left,right) ASSERT_GREATERM(#left " > " #right, (left),(right)) 62 | #define ASSERT_GREATER_EQUALM(msg,left,right) cute::assert_relop((left),(right),\ 63 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg),__FILE__,__LINE__) 64 | #define ASSERT_GREATER_EQUAL(left,right) ASSERT_GREATER_EQUALM(#left " >= " #right, (left),(right)) 65 | #define ASSERT_NOT_EQUAL_TOM(msg,left,right) cute::assert_relop((left),(right),\ 66 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg),__FILE__,__LINE__) 67 | #define ASSERT_NOT_EQUAL_TO(left,right) ASSERT_NOT_EQUAL_TOM(#left " != " #right, (left),(right)) 68 | 69 | #endif /* CUTE_RELOPS_H_ */ 70 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/ide_listener.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef IDE_LISTENER_H_ 27 | #define IDE_LISTENER_H_ 28 | 29 | #include "cute_listener.h" 30 | 31 | #include 32 | #include 33 | #ifdef _MSC_VER 34 | #define WIN32_LEAN_AND_MEAN 35 | #include 36 | #include 37 | #endif 38 | 39 | namespace cute { 40 | template 41 | struct ide_listener: Listener 42 | { 43 | ide_listener(std::ostream &os=std::cout):out(os) {} 44 | void begin(suite const &t,char const *info, size_t n_of_tests){ 45 | out << std::dec << "\n#beginning " << info << " " << n_of_tests << '\n' << std::flush; 46 | Listener::begin(t,info,n_of_tests); 47 | } 48 | void end(suite const &t, char const *info){ 49 | out << "\n#ending " << info << '\n' << std::flush; 50 | Listener::end(t,info); 51 | } 52 | void start(test const &t){ 53 | out << "\n#starting " << t.name() << '\n' << std::flush; 54 | Listener::start(t); 55 | } 56 | void success(test const &t, char const *msg){ 57 | out << "\n#success " << maskBlanks(t.name()) << " " << msg << '\n' << std::flush; 58 | Listener::success(t,msg); 59 | } 60 | void failure(test const &t,test_failure const &e){ 61 | out << std::dec << "\n#failure " << maskBlanks(t.name()) << " " << e.filename << ":" << e.lineno << " " << (e.reason) << '\n' << std::flush; 62 | Listener::failure(t,e); 63 | #ifdef _MSC_VER 64 | std::ostringstream os; 65 | os << std::dec << e.filename << "(" << e.lineno << ") : failure: " < > 25 | struct enum_has_limit:std::false_type{}; 26 | template 27 | struct enum_has_limit< E, 28 | std::void_t 29 | >:std::is_enum{}; 30 | template > 31 | struct enum_has_start:std::false_type{}; 32 | template 33 | struct enum_has_start< E, 34 | std::void_t 35 | >:std::is_enum{}; 36 | 37 | template 38 | using ule = std::underlying_type_t; 39 | } 40 | namespace enum_iteration { 41 | template < typename E , typename = std::enable_if_t >> 42 | constexpr E operator++(E &e) noexcept { 43 | using namespace detail_; 44 | auto val=static_cast>(e); 45 | pssst_assert(val < std::numeric_limits::max()); 46 | ++val; 47 | if constexpr(enum_has_limit{}){ 48 | if (val > static_cast>(E::limit__)){ 49 | if constexpr (enum_has_start{}){ 50 | return e = E::start__; 51 | } else { 52 | val = 0; 53 | } 54 | } 55 | } 56 | e = static_cast(val); 57 | return e; 58 | } 59 | template < typename E , typename = std::enable_if_t>> 60 | constexpr E operator++(E & e, int) noexcept { 61 | auto res=e; 62 | ++e; 63 | return res; 64 | } 65 | template < typename E , typename = std::enable_if_t >> 66 | constexpr E operator--(E &e) noexcept { 67 | using namespace detail_; 68 | auto val=static_cast>(e); 69 | constexpr E begin = []{ 70 | if constexpr (enum_has_start{}) 71 | return E::start__ ; 72 | else 73 | return E{}; 74 | }(); 75 | 76 | if (e == begin){ // start is inclusive 77 | if constexpr(enum_has_limit{}){ 78 | return e = E::limit__; // limit is supposed to be inclusive 79 | } 80 | } 81 | if constexpr(std::is_signed_v) { 82 | pssst_assert(val > std::numeric_limits::min()); 83 | } 84 | --val; 85 | e = static_cast(val); 86 | return e; 87 | } 88 | template < typename E , typename = std::enable_if_t>> 89 | constexpr E operator--(E & e, int) noexcept { 90 | auto res=e; 91 | --e; 92 | return res; 93 | } 94 | namespace inner_detail_{ 95 | using ::pssst::enum_iteration::operator++; 96 | // not that easy, needs scaffolding to make it an iterator.... 97 | template{}>> 98 | struct enum_iterator 99 | :ops,Value,Inc,Dec,Eq>{ 100 | E val; 101 | constexpr E operator*()noexcept { 102 | return value(*this); 103 | } 104 | }; 105 | } 106 | template{}>> 107 | constexpr inner_detail_::enum_iterator begin(E e) noexcept { 108 | return detail_::retval>(e); 109 | } 110 | template{}>> 111 | constexpr inner_detail_::enum_iterator end(E ) noexcept { 112 | return detail_::retval>(E::limit__); 113 | } 114 | } // enum_iteration 115 | #undef pssst_assert 116 | 117 | } 118 | 119 | 120 | #endif /* SRC_PSSST_ENUM_ITER_H_ */ 121 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_testmember.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2006-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_TESTMEMBER_H_ 27 | #define CUTE_TESTMEMBER_H_ 28 | 29 | #include "cute_test.h" 30 | 31 | namespace cute { 32 | template 33 | test makeMemberFunctionTest(TestClass &t,void (TestClass::*fun)(),char const *name){ 34 | return test(boost_or_tr1::bind(fun,boost_or_tr1::ref(t)),demangle(typeid(TestClass).name())+"::"+name); 35 | } 36 | template 37 | test makeMemberFunctionTest(TestClass const &t,void (TestClass::*fun)()const,char const *name){ 38 | return test(boost_or_tr1::bind(fun,boost_or_tr1::cref(t)),demangle(typeid(TestClass).name())+"::"+name); 39 | } 40 | template 41 | struct incarnate_for_member_function { 42 | MemFun memfun; 43 | incarnate_for_member_function(MemFun f):memfun(f){} 44 | void operator()(){ 45 | TestClass t; 46 | (t.*memfun)(); 47 | } 48 | }; 49 | template 50 | test makeSimpleMemberFunctionTest(MemFun fun,char const *name){ 51 | return test(incarnate_for_member_function(fun),demangle(typeid(TestClass).name())+"::"+name); 52 | } 53 | template 54 | struct incarnate_for_member_function_with_context_object { 55 | MemFun memfun; 56 | Context context; 57 | incarnate_for_member_function_with_context_object(MemFun f,Context c) 58 | :memfun(f),context(c){} 59 | incarnate_for_member_function_with_context_object(incarnate_for_member_function_with_context_object const &other) 60 | :memfun(other.memfun),context(other.context){} // provide copy-ctor for std::function ctor requirement should be =default on C++11 61 | 62 | void operator()(){ 63 | TestClass t(context); 64 | (t.*memfun)(); 65 | } 66 | }; 67 | template 68 | test makeMemberFunctionTestWithContext(Context c,MemFun fun,char const *name){ 69 | return test(incarnate_for_member_function_with_context_object(fun,c),demangle(typeid(TestClass).name())+"::"+name); 70 | } 71 | } 72 | 73 | #define CUTE_MEMFUN(testobject,TestClass,MemberFunctionName) \ 74 | cute::makeMemberFunctionTest(testobject,\ 75 | &TestClass::MemberFunctionName,\ 76 | #MemberFunctionName) 77 | #define CUTE_SMEMFUN(TestClass,MemberFunctionName) \ 78 | cute::makeSimpleMemberFunctionTest(\ 79 | &TestClass::MemberFunctionName,\ 80 | #MemberFunctionName) 81 | #define CUTE_CONTEXT_MEMFUN(context_object,TestClass,MemberFunctionName) \ 82 | cute::makeMemberFunctionTestWithContext(\ 83 | context_object,\ 84 | &TestClass::MemberFunctionName,\ 85 | #MemberFunctionName) 86 | 87 | #endif /*CUTE_TESTMEMBER_H_*/ 88 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/EnumOperators.cpp: -------------------------------------------------------------------------------- 1 | #include "pssst_enum_iter.h" 2 | #include "EnumOperators.h" 3 | #include "cute.h" 4 | #include 5 | 6 | namespace test{ 7 | //using pssst::enum_iteration::begin; 8 | //using pssst::enum_iteration::end; 9 | enum class color { black, blue, green, cyan, red, magenta, yellow, white, limit__=white }; 10 | enum class coloroff:unsigned { black = 42, start__=black, blue, green, cyan, red, magenta, yellow, white, limit__=white }; 11 | enum class nocolor { black, gray, white }; 12 | namespace iter { 13 | enum class color { black, blue, green, cyan, red, magenta, yellow, white, limit__ }; 14 | enum class coloroff:unsigned { black = 42, start__=black, blue, green, cyan, red, magenta, yellow, white, limit__ }; 15 | 16 | // must import corresponding functions and operators for ADL 17 | using pssst::enum_iteration::begin; 18 | using pssst::enum_iteration::end; 19 | using pssst::enum_iteration::operator++; 20 | using pssst::enum_iteration::operator--; 21 | 22 | } 23 | // only for tests, otherwise too generic 24 | template < typename E > 25 | std::ostream & operator<<(std::ostream &os, E e){ 26 | return os << static_cast>(e); 27 | } 28 | } 29 | 30 | using namespace test; 31 | void thisIsAEnumOperatorsTest() { 32 | using namespace pssst::enum_iteration; 33 | color x = color::blue; 34 | ASSERT_EQUAL(color::blue, x++); 35 | } 36 | void testEnumOperatorsTest() { 37 | //using namespace pssst::enum_iteration; 38 | auto x = iter::color::blue; 39 | ASSERT_EQUAL(iter::color::green, ++x); 40 | } 41 | void testWrappingIncrement(){ 42 | using namespace pssst::enum_iteration; 43 | color x = color::white; 44 | ++x; 45 | ASSERT_EQUAL(color::black, x); 46 | } 47 | void testWrappingIncrementWithStart(){ 48 | using namespace pssst::enum_iteration; 49 | coloroff x = coloroff::white; 50 | ++x; 51 | ASSERT_EQUAL(coloroff::black, x); 52 | } 53 | 54 | void testNonWrappingIncrement(){ 55 | using namespace pssst::enum_iteration; 56 | nocolor x = nocolor::black; 57 | x++; x++ ; x++; 58 | ASSERT_EQUAL(3, static_cast>(x)); 59 | } 60 | 61 | void testDecrementSimple(){ 62 | using namespace pssst::enum_iteration; 63 | color x = color::blue; 64 | --x; 65 | ASSERT_EQUAL(color::black, x); 66 | } 67 | void testDecrementWrap(){ 68 | using namespace pssst::enum_iteration; 69 | auto x = coloroff::black; 70 | --x; 71 | ASSERT_EQUAL(coloroff::white,x); 72 | } 73 | void testDecrementWrapSimple(){ 74 | using namespace pssst::enum_iteration; 75 | auto x = color::black; 76 | --x; 77 | ASSERT_EQUAL(color::white,x); 78 | } 79 | 80 | void testRangeFor(){ 81 | using pssst::detail_::ule; 82 | 83 | int counter=0; 84 | 85 | auto b = begin(iter::color{}); 86 | // ASSERT_EQUAL(iter::color::black,*b); 87 | auto const e = end(iter::color{}); 88 | // ASSERT_EQUAL(iter::color::limit__, *e); 89 | auto it = e; 90 | do { 91 | --it; 92 | counter -= static_cast>(*it); 93 | } while (it != b); 94 | 95 | for(auto e:iter::color{}){ 96 | counter += static_cast>(e); 97 | } 98 | ASSERT_EQUAL(0,counter); // (7 * 8) 99 | } 100 | 101 | 102 | 103 | 104 | 105 | #if 0 // negative compile test for SFINAE 106 | struct fakeenum{ 107 | operator int() const { return 0;} 108 | fakeenum(int=0 ){} 109 | }; 110 | namespace std{ // cheat 111 | template <> 112 | struct underlying_type{ 113 | using type= int; 114 | }; 115 | } 116 | 117 | void testThatIncrementOnlyAppliesToEnums(){ 118 | using namespace pssst; 119 | fakeenum x; 120 | ++x; 121 | } 122 | #endif 123 | 124 | 125 | 126 | cute::suite make_suite_EnumOperators() { 127 | cute::suite s { }; 128 | s.push_back(CUTE(thisIsAEnumOperatorsTest)); 129 | s.push_back(CUTE(testRangeFor)); 130 | s.push_back(CUTE(testWrappingIncrement)); 131 | s.push_back(CUTE(testNonWrappingIncrement)); 132 | s.push_back(CUTE(testWrappingIncrementWithStart)); 133 | s.push_back(CUTE(testDecrementSimple)); 134 | s.push_back(CUTE(testDecrementWrap)); 135 | s.push_back(CUTE(testDecrementWrapSimple)); 136 | s.push_back(CUTE(testEnumOperatorsTest)); 137 | return s; 138 | } 139 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/BitOperationsTest.cpp: -------------------------------------------------------------------------------- 1 | #include "BitOperationsTest.h" 2 | #include "cute.h" 3 | #include "pssst.h" 4 | #include 5 | 6 | //#define USE_STRONG 7 | using namespace pssst; 8 | struct U_int16 : 9 | #ifdef USE_STRONG 10 | strong 15 | { 16 | #ifndef USE_STRONG 17 | constexpr explicit U_int16(std::uint16_t val={}) noexcept :value{val}{} 18 | std::uint16_t value{}; 19 | #endif 20 | }; 21 | static_assert(std::is_trivially_copyable_v); 22 | 23 | static_assert(static_cast(~42) == (~ U_int16{42} ).value); 24 | 25 | static_assert(10u == (U_int16{42} & U_int16{11}).value); 26 | static_assert(43u == (U_int16{42} | U_int16{11}).value); 27 | static_assert(43u == (U_int16{42} | U_int16{11}).value); 28 | static_assert(84u == (U_int16{21} << 2).value); 29 | static_assert(21u == (U_int16{42} >> 1).value); 30 | // fails as it should: static_assert(21u == (U_int16{42} >> 17).value); 31 | 32 | 33 | void testBitNegate(){ 34 | U_int16 ui{42}; 35 | uint16_t ui16{42}; 36 | ASSERT_EQUAL(static_cast(~ui16),(~ui).value); 37 | } 38 | 39 | void testBitAnd(){ 40 | U_int16 ui{42}; 41 | U_int16 const eleven { 11 }; 42 | ASSERT_EQUAL(10u,(ui & eleven).value); 43 | } 44 | void testBitAndAssign(){ 45 | U_int16 ui{42}; 46 | U_int16 const eleven { 11 }; 47 | ui &= eleven; 48 | ASSERT_EQUAL(10u,ui.value); 49 | } 50 | void testBitOr(){ 51 | U_int16 ui{42}; 52 | U_int16 const eleven { 11 }; 53 | ASSERT_EQUAL(43u,(ui | eleven).value); 54 | } 55 | void testBitOrAssign(){ 56 | U_int16 ui{42}; 57 | U_int16 const eleven { 11 }; 58 | ui |= eleven; 59 | ASSERT_EQUAL(43u,ui.value); 60 | } 61 | 62 | void testBitXor(){ 63 | U_int16 ui{42}; 64 | U_int16 const eleven { 11 }; 65 | ASSERT_EQUAL(33u,(ui ^ eleven).value); 66 | } 67 | void testBitXorAssign(){ 68 | U_int16 ui{42}; 69 | U_int16 const eleven { 11 }; 70 | ui ^= eleven; 71 | ASSERT_EQUAL(33u,ui.value); 72 | } 73 | 74 | void testBitShiftL(){ 75 | U_int16 ui { 42 }; 76 | ASSERT_EQUAL(42u<<5u,(ui << 5u).value); 77 | } 78 | void testBitShiftLAssign(){ 79 | U_int16 ui{42}; 80 | ui <<= 5u; 81 | ASSERT_EQUAL(42u<<5u,ui.value); 82 | } 83 | void testBitShiftLBits(){ 84 | U_int16 ui { 42 }; 85 | U_int16 bits { 5}; 86 | ASSERT_EQUAL(42u<< bits.value,(ui << bits).value); 87 | } 88 | void testBitShiftLAssignBits(){ 89 | U_int16 ui{42}; 90 | U_int16 const bits { 5}; 91 | 92 | ui <<= bits; 93 | ASSERT_EQUAL(42u<< bits.value,ui.value); 94 | } 95 | void testBitShiftLBeyond(){ 96 | U_int16 const ui { 42 }; 97 | ASSERT_THROWS(ui << 17u, std::logic_error); 98 | } 99 | 100 | void testBitShiftR(){ 101 | U_int16 const ui { 42 }; 102 | ASSERT_EQUAL(42u>>5u,(ui >> 5u).value); 103 | } 104 | void testBitShiftRAssign(){ 105 | U_int16 ui{42}; 106 | ui >>= 5u; 107 | ASSERT_EQUAL(42u>>5u,ui.value); 108 | } 109 | void testBitShiftRBits(){ 110 | U_int16 const ui { 42 }; 111 | U_int16 const bits { 5}; 112 | ASSERT_EQUAL(42u>> bits.value,(ui >> bits).value); 113 | } 114 | void testBitShiftRAssignBits(){ 115 | U_int16 ui{42}; 116 | U_int16 const bits { 5}; 117 | 118 | ui >>= bits; 119 | ASSERT_EQUAL(42u >> bits.value,ui.value); 120 | } 121 | void testBitShiftRBeyond(){ 122 | U_int16 const ui { 42 }; 123 | ASSERT_THROWS(ui >> 17u, std::logic_error); 124 | } 125 | 126 | 127 | 128 | 129 | cute::suite make_suite_BitOperationsTest() { 130 | cute::suite s { }; 131 | s.push_back(CUTE(testBitNegate)); 132 | s.push_back(CUTE(testBitAnd)); 133 | s.push_back(CUTE(testBitAndAssign)); 134 | s.push_back(CUTE(testBitOr)); 135 | s.push_back(CUTE(testBitOrAssign)); 136 | s.push_back(CUTE(testBitXor)); 137 | s.push_back(CUTE(testBitXorAssign)); 138 | s.push_back(CUTE(testBitShiftL)); 139 | s.push_back(CUTE(testBitShiftLAssign)); 140 | s.push_back(CUTE(testBitShiftLBits)); 141 | s.push_back(CUTE(testBitShiftLAssignBits)); 142 | s.push_back(CUTE(testBitShiftR)); 143 | s.push_back(CUTE(testBitShiftRAssign)); 144 | s.push_back(CUTE(testBitShiftRBits)); 145 | s.push_back(CUTE(testBitShiftRAssignBits)); 146 | s.push_back(CUTE(testBitShiftLBeyond)); 147 | s.push_back(CUTE(testBitShiftRBeyond)); 148 | return s; 149 | } 150 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/xml_listener.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef XML_LISTENER_H_ 27 | #define XML_LISTENER_H_ 28 | 29 | #include "cute_listener.h" 30 | #include "cute_xml_file.h" // for convenience 31 | 32 | #include 33 | 34 | namespace cute { 35 | template 36 | class xml_listener:public Listener 37 | { 38 | protected: 39 | std::string mask_xml_chars(std::string in){ 40 | std::string::size_type pos=0; 41 | while((pos=in.find_first_of("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\"&'<>", pos, 34))!=std::string::npos){ 42 | switch(in[pos]){ 43 | case '&': in.replace(pos,1,"&"); pos +=5; break; 44 | case '<': in.replace(pos,1,"<"); pos += 4; break; 45 | case '>': in.replace(pos,1,">"); pos += 4; break; 46 | case '"': in.replace(pos,1,"""); pos+=6; break; 47 | case '\'':in.replace(pos,1,"'"); pos+=6; break; 48 | default: 49 | char c = in[pos]; 50 | std::string replacement = "0x" + cute_to_string::hexit(c); 51 | in.replace(pos, 1, replacement); pos += replacement.size(); break; 52 | break; 53 | } 54 | } 55 | return in; 56 | } 57 | std::ostream &out; 58 | std::string current_suite; 59 | public: 60 | xml_listener(std::ostream &os):out(os) { 61 | out << "\n"; 62 | } 63 | ~xml_listener(){ 64 | out << "\n"<< std::flush; 65 | } 66 | 67 | void begin(suite const &t,char const *info, size_t n_of_tests){ 68 | current_suite=mask_xml_chars(info); 69 | out << std::dec << "\t\n"; 70 | Listener::begin(t,info, n_of_tests); 71 | } 72 | void end(suite const &t, char const *info){ 73 | out << "\t\n"; 74 | current_suite.clear(); 75 | Listener::end(t,info); 76 | } 77 | void start(test const &t){ 78 | out << "\t\t\n"; 83 | Listener::success(t,msg); 84 | } 85 | void failure(test const &t,test_failure const &e){ 86 | out << std::dec << ">\n\t\t\t\n"<\n\t\t\n"; 88 | Listener::failure(t,e); 89 | } 90 | void error(test const &t, char const *what){ 91 | out << ">\n\t\t\t\n"<\n\t\t\n"; 94 | Listener::error(t,what); 95 | } 96 | }; 97 | } 98 | 99 | #endif /*IDE_LISTENER_H_*/ 100 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_data_driven.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2013-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_DATA_DRIVEN_H_ 27 | #define CUTE_DATA_DRIVEN_H_ 28 | 29 | #include "cute_base.h" 30 | #include "cute_equals.h" 31 | #include "cute_relops.h" 32 | 33 | #define DDTM(msg) (cute::test_failure(cute::cute_to_string::backslashQuoteTabNewline(msg),__FILE__,__LINE__)) 34 | #define DDT() DDTM("") 35 | 36 | #define ASSERT_DDTM(cond,msg,failure) do{ \ 37 | if (!(cond)) \ 38 | throw cute::test_failure(CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg)+(failure).reason,\ 39 | (failure).filename.c_str(),(failure).lineno);\ 40 | } while (false) 41 | #define ASSERT_DDT(cond,failure) ASSERT_DDTM(cond,#cond,(failure)) 42 | 43 | #define ASSERT_EQUAL_DDTM(msg,expected,actual,failure) cute::assert_equal((expected),(actual),\ 44 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg)\ 45 | +(failure).reason,(failure).filename.c_str(),(failure).lineno) 46 | #define ASSERT_EQUAL_DDT(expected,actual,failure) ASSERT_EQUAL_DDTM(#expected " == " #actual, (expected),(actual),(failure)) 47 | #define ASSERT_EQUAL_DELTA_DDTM(msg,expected,actual,delta,failure) cute::assert_equal_delta((expected),(actual),(delta),\ 48 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg)\ 49 | +(failure).reason,(failure).filename.c_str(),(failure).lineno) 50 | #define ASSERT_EQUAL_DELTA_DDT(expected,actual,delta,failure) ASSERT_EQUAL_DELTA_DDTM(#expected " == " #actual " with error " #delta ,(expected),(actual),(delta),(failure)) 51 | 52 | #define ASSERT_LESS_DDTM(msg,left,right,failure) cute::assert_relop((left),(right),\ 53 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg)\ 54 | +(failure).reason,(failure).filename.c_str(),(failure).lineno) 55 | #define ASSERT_LESS_DDT(left,right,failure) ASSERT_LESS_DDTM(#left " < " #right, (left),(right),(failure)) 56 | 57 | #define ASSERT_LESS_EQUAL_DDTM(msg,left,right,failure) cute::assert_relop((left),(right),\ 58 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg)\ 59 | +(failure).reason,(failure).filename.c_str(),(failure).lineno) 60 | #define ASSERT_LESS_EQUAL_DDT(left,right,failure) ASSERT_LESS_EQUAL_DDTM(#left " <= " #right, (left),(right),(failure)) 61 | 62 | #define ASSERT_GREATER_DDTM(msg,left,right,failure) cute::assert_relop((left),(right),\ 63 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg)\ 64 | +(failure).reason,(failure).filename.c_str(),(failure).lineno) 65 | #define ASSERT_GREATER_DDT(left,right,failure) ASSERT_GREATER_DDTM(#left " > " #right, (left),(right),(failure)) 66 | 67 | #define ASSERT_GREATER_EQUAL_DDTM(msg,left,right,failure) cute::assert_relop((left),(right),\ 68 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg)\ 69 | +(failure).reason,(failure).filename.c_str(),(failure).lineno) 70 | #define ASSERT_GREATER_EQUAL_DDT(left,right,failure) ASSERT_GREATER_EQUAL_DDTM(#left " >= " #right, (left),(right),(failure)) 71 | 72 | #define ASSERT_NOT_EQUAL_TO_DDTM(msg,left,right,failure) cute::assert_relop((left),(right),\ 73 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg)\ 74 | +(failure).reason,(failure).filename.c_str(),(failure).lineno) 75 | #define ASSERT_NOT_EQUAL_TO_DDT(left,right,failure) ASSERT_NOT_EQUAL_TO_DDTM(#left " != " #right, (left),(right),(failure)) 76 | 77 | 78 | 79 | #endif /* CUTE_DATA_DRIVEN_H_ */ 80 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/Degrees.cpp: -------------------------------------------------------------------------------- 1 | #include "Degrees.h" 2 | #include "cute.h" 3 | #include "pssst.h" 4 | 5 | //#define USE_STRONG 6 | using namespace pssst; 7 | // vector space: degrees (K and C) 8 | struct degrees: 9 | #ifdef USE_STRONG 10 | Linear 11 | #else 12 | LinearOps{ 13 | explicit constexpr 14 | degrees(double val) noexcept 15 | :value{val}{} 16 | constexpr degrees() noexcept = default; 17 | double value{}; 18 | #endif 19 | 20 | }; 21 | 22 | static_assert(sizeof(double)==sizeof(degrees)); 23 | 24 | 25 | struct Kelvin:affine_space_for{ 26 | #ifndef USE_STRONG 27 | using base = affine_space_for; 28 | explicit constexpr 29 | Kelvin(degrees val) noexcept 30 | :base{val}{} 31 | explicit constexpr 32 | Kelvin(double val) noexcept 33 | :base{degrees{val}}{} 34 | constexpr Kelvin() noexcept = default; 35 | 36 | #endif 37 | 38 | }; 39 | 40 | static_assert(sizeof(double)==sizeof(Kelvin)); 41 | 42 | struct CelsiusZero{ 43 | constexpr degrees operator()() const noexcept{ 44 | return degrees{273.15}; 45 | } 46 | }; 47 | 48 | struct Celsius:affine_space_for { 49 | #ifndef USE_STRONG 50 | using base=affine_space_for; 51 | 52 | explicit constexpr 53 | Celsius(degrees val) noexcept 54 | :base{val}{} 55 | explicit constexpr 56 | Celsius(double val) noexcept 57 | :base{degrees{val}}{} 58 | constexpr Celsius() noexcept = default; 59 | 60 | #endif 61 | 62 | 63 | }; 64 | static_assert(sizeof(degrees)==sizeof(Celsius)); 65 | 66 | constexpr Celsius fromKelvin(Kelvin k) noexcept { 67 | return convertTo(k); 68 | } 69 | 70 | constexpr Kelvin fromCelsius(Celsius c)noexcept{ 71 | return convertTo(c); 72 | } 73 | 74 | struct otherdegrees:ops{ 75 | double d; 76 | }; 77 | 78 | degrees x{5}; 79 | 80 | void thisIsADegreesTest() { 81 | degrees hotter{20}; 82 | Celsius spring{15}; 83 | ASSERT_EQUAL(Celsius{35},spring+hotter); 84 | } 85 | void thisIsAKelvinDegreesTest() { 86 | degrees hotter{20}; 87 | Kelvin spring{15}; 88 | auto x = spring+hotter; 89 | ASSERT_EQUAL(Kelvin{35},x); 90 | } 91 | void testCelsiusFromKelvin(){ 92 | Kelvin zero{273.15}; 93 | zero += degrees{20}; 94 | ASSERT_EQUAL(Celsius{20},convertTo(zero)); 95 | } 96 | 97 | void testKelvinFromCelsius(){ 98 | Celsius boiling{100}; 99 | ASSERT_EQUAL(Kelvin{373.15},fromCelsius(boiling)); 100 | } 101 | 102 | void testConversion(){ 103 | Celsius mild{20}; 104 | Kelvin k{convertTo(mild)}; 105 | ASSERT_EQUAL(Kelvin{293.15},k); 106 | ASSERT_EQUAL(mild,convertTo(k)); 107 | } 108 | #if 0 109 | namespace talk { 110 | // vector space degrees for (K and °C) 111 | struct degrees: Linear{}; 112 | 113 | static_assert(sizeof(double)==sizeof(degrees)); 114 | 115 | 116 | struct Kelvin:affine_space_for{ 117 | static constexpr auto suffix="K"; 118 | }; 119 | 120 | static_assert(sizeof(double)==sizeof(Kelvin)); 121 | 122 | struct CelsiusZero{ 123 | constexpr degrees operator()() const noexcept{ 124 | return degrees{273.15}; 125 | } 126 | }; 127 | 128 | struct Celsius:affine_space_for { 129 | static constexpr auto suffix="°C"; 130 | //Unicode: U+00B0, UTF-8: C2 B0 131 | }; 132 | static_assert(sizeof(degrees)==sizeof(Celsius)); 133 | 134 | constexpr Celsius fromKelvin(Kelvin k) noexcept { 135 | return convertTo(k); 136 | } 137 | 138 | constexpr Kelvin fromCelsius(Celsius c)noexcept{ 139 | return convertTo(c); 140 | } 141 | 142 | void thisIsADegreesTest() { 143 | degrees hotter{20}; 144 | Celsius spring{15}; 145 | ASSERT_EQUAL(Celsius{35},spring+hotter); 146 | } 147 | void thisIsAKelvinDegreesTest() { 148 | degrees hotter{20}; 149 | Kelvin spring{15}; 150 | auto x = spring+hotter; 151 | ASSERT_EQUAL(Kelvin{35},x); 152 | } 153 | void testCelsiusFromKelvin(){ 154 | Kelvin zero{273.15}; 155 | zero += degrees{20}; 156 | ASSERT_EQUAL(Celsius{20},convertTo(zero)); 157 | } 158 | 159 | void testKelvinFromCelsius(){ 160 | Celsius boiling{100}; 161 | ASSERT_EQUAL(Kelvin{373.15},fromCelsius(boiling)); 162 | } 163 | 164 | void testConversion(){ 165 | Celsius mild{20}; 166 | Kelvin k{convertTo(mild)}; 167 | ASSERT_EQUAL(Kelvin{293.15},k); 168 | ASSERT_EQUAL(mild,convertTo(k)); 169 | } 170 | 171 | } 172 | #endif 173 | 174 | 175 | cute::suite make_suite_Degrees() { 176 | cute::suite s { }; 177 | s.push_back(CUTE(thisIsADegreesTest)); 178 | s.push_back(CUTE(thisIsAKelvinDegreesTest)); 179 | s.push_back(CUTE(testCelsiusFromKelvin)); 180 | s.push_back(CUTE(testKelvinFromCelsius)); 181 | s.push_back(CUTE(testConversion)); 182 | #if 0 183 | s.push_back(CUTE(talk::thisIsADegreesTest)); 184 | s.push_back(CUTE(talk::thisIsAKelvinDegreesTest)); 185 | s.push_back(CUTE(talk::testCelsiusFromKelvin)); 186 | s.push_back(CUTE(talk::testKelvinFromCelsius)); 187 | s.push_back(CUTE(talk::testConversion)); 188 | #endif 189 | return s; 190 | } 191 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_demangle.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2009-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_DEMANGLE_H_ 27 | #define CUTE_DEMANGLE_H_ 28 | #include 29 | // needs adaptation for different compilers 30 | // dependency to demangle is a given, 31 | // otherwise we have to use macros everywhere 32 | #ifdef __GNUG__ // also for clang... 33 | #include // __cxa_demangle 34 | #include // ::free() 35 | namespace cute { 36 | extern inline std::string demangle(char const *name); 37 | 38 | namespace cute_impl_demangle { 39 | inline std::string plain_demangle(char const *name){ 40 | if (!name) return "unknown"; 41 | char const *toBeFreed = abi::__cxa_demangle(name,0,0,0); 42 | std::string result(toBeFreed?toBeFreed:name); 43 | ::free(const_cast(toBeFreed)); 44 | return result; 45 | } 46 | #if defined(_LIBCPP_ABI_NAMESPACE) || defined(_LIBCPP_NAMESPACE) || defined(_GLIBCXX_USE_CXX11_ABI) 47 | inline void patch_library_namespace(std::string &mightcontaininlinenamespace) { 48 | // libc++ uses inline namespace std::_LIBCPP_NAMESPACE:: for its classes. This breaks the tests relying on meta information. re-normalize the names back to std:: 49 | // libstdc++ (at least in version 6.3.1) puts some STL classes into the inline namespace std::_GLIBCXX_NAMESPACE_CXX11 if in C++11 mode 50 | std::string::size_type pos=std::string::npos; 51 | #define XNS(X) #X 52 | #define NS(X) XNS(X) 53 | #if defined( _LIBCPP_NAMESPACE) 54 | #define TOREPLACE "::" NS(_LIBCPP_NAMESPACE) 55 | #elif defined(_LIBCPP_ABI_NAMESPACE) 56 | #define TOREPLACE "::" NS(_LIBCPP_ABI_NAMESPACE) 57 | #else 58 | #define TOREPLACE "::" NS(_GLIBCXX_NAMESPACE_CXX11) 59 | #endif 60 | std::string const nothing; 61 | while (std::string::npos != (pos= mightcontaininlinenamespace.find(TOREPLACE))) 62 | mightcontaininlinenamespace.erase(pos,sizeof(TOREPLACE)-1); 63 | #undef NS 64 | #undef XNS 65 | #undef TOREPLACE 66 | } 67 | inline void patchresultforstring(std::string& result) { 68 | static const std::string stringid=plain_demangle(typeid(std::string).name()); 69 | std::string::size_type pos=std::string::npos; 70 | while(std::string::npos != (pos=result.find(stringid))){ 71 | if (!result.compare(pos+stringid.size(),2," >",2)) result.erase(pos+stringid.size(),1); // makes templates look nice 72 | result.replace(pos,stringid.size(),"std::string"); 73 | } 74 | patch_library_namespace(result); 75 | } 76 | #endif 77 | 78 | } 79 | inline std::string demangle(char const *name){ 80 | if (!name) return "unknown"; 81 | std::string result(cute_impl_demangle::plain_demangle(name)); 82 | #if defined(_LIBCPP_ABI_NAMESPACE) || defined(_LIBCPP_NAMESPACE) || defined(_GLIBCXX_USE_CXX11_ABI) 83 | cute_impl_demangle::patchresultforstring(result); 84 | #endif 85 | return result; 86 | } 87 | } 88 | #else 89 | namespace cute { 90 | #ifdef _MSC_VER 91 | namespace cute_demangle_impl { 92 | 93 | inline void removeMSKeyword(std::string &name,std::string const &kw){ 94 | std::string::size_type pos=std::string::npos; 95 | while (std::string::npos != (pos= name.find(kw))) 96 | name.erase(pos,kw.size()); 97 | 98 | } 99 | inline void patchresultforstring(std::string& result) { 100 | static const std::string stringid=(typeid(std::string).name()); 101 | std::string::size_type pos=std::string::npos; 102 | while(std::string::npos != (pos=result.find(stringid))){ 103 | if (!result.compare(pos+stringid.size(),2," >",2)) result.erase(pos+stringid.size(),1); // makes templates look nice 104 | result.replace(pos,stringid.size(),"std::string"); 105 | } 106 | } 107 | 108 | inline void patchMSMangling(std::string &name){ 109 | patchresultforstring(name); 110 | removeMSKeyword(name,"class "); 111 | removeMSKeyword(name,"struct "); 112 | for (std::string::iterator i=name.begin(); i != name.end(); ++i){ 113 | if (*i==','){ i = name.insert(i+1,' ');} 114 | } 115 | std::string::size_type pos=0; 116 | while(std::string::npos !=(pos=name.find(" ,",pos))){ 117 | name.erase(pos,1); 118 | ++pos; 119 | } 120 | } 121 | } 122 | inline std::string demangle(char const *name){ 123 | std::string result(name?name:"unknown"); 124 | cute_demangle_impl::patchMSMangling(result); 125 | return result; 126 | } 127 | 128 | #else 129 | // this default works reasonably with MSVC71 and 8, hopefully for others as well 130 | inline std::string demangle(char const *name){ 131 | return std::string(name?name:"unknown"); 132 | } 133 | #endif 134 | } 135 | #endif 136 | 137 | #endif /* CUTE_DEMANGLE_H_ */ 138 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_runner.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2006-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_RUNNER_H_ 27 | #define CUTE_RUNNER_H_ 28 | 29 | #include "cute_test.h" 30 | #include "cute_suite.h" 31 | #include "cute_listener.h" 32 | #include "cute_determine_traits.h" 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | namespace cute { 40 | namespace runner_aux { 41 | struct prefixMatcher 42 | { 43 | prefixMatcher(std::string const &prefix):prefix(prefix){} 44 | bool operator()(std::string const &s) const { 45 | size_t found=s.find(prefix); 46 | return found==0 && (s.size()==prefix.size() || s[prefix.size()]=='#'); 47 | } 48 | private: 49 | std::string const prefix; 50 | }; 51 | struct prefixCutter 52 | { 53 | prefixCutter(std::string const &prefix):prefix(prefix){} 54 | std::string operator()(std::string s) const { 55 | size_t found=s.find(prefix); 56 | if ( found==0 && s.size()>prefix.size() && s[prefix.size()]=='#'){ 57 | s = s.substr(prefix.size()+1); 58 | } else { 59 | s.clear(); // either no match, or no individual test 60 | } 61 | return s; 62 | } 63 | private: 64 | std::string const prefix; 65 | }; 66 | class ArgvTestFilter 67 | { 68 | std::set match; 69 | bool shouldRunSuite(std::string const &info, std::vector const &args) 70 | { 71 | if(!args.size() || !info.size()) 72 | return true; 73 | if(args.end() != find_if(args.begin(), args.end(), prefixMatcher(info))){ 74 | std::transform(args.begin(), args.end(), std::inserter(match,match.begin()),prefixCutter(info)); 75 | match.erase(std::string()); // get rid of empty string 76 | return true; 77 | } 78 | return false; 79 | } 80 | public: 81 | bool const shouldrunsuite; 82 | ArgvTestFilter(std::string const &info, std::vector const &args) 83 | :shouldrunsuite(shouldRunSuite(info,args)){} 84 | bool shouldRun(const std::string & name) const 85 | { 86 | return match.empty() || match.count(name); 87 | } 88 | }; 89 | } // namespace runner_aux 90 | template 91 | struct runner{ 92 | Listener &listener; 93 | std::vector args; 94 | runner(Listener &l, int argc = 0, const char *const *argv = 0):listener(l){ 95 | if(needsFiltering(argc,argv)){ 96 | std::remove_copy_if(argv + 1, argv + argc,back_inserter(args),std::logical_not()); 97 | } 98 | } 99 | bool operator()(const test & t) const 100 | { 101 | return runit(t); 102 | } 103 | 104 | bool operator ()(suite const &s, const char *info = "") const 105 | { 106 | runner_aux::ArgvTestFilter filter(info,args); 107 | 108 | bool result = true; 109 | if(filter.shouldrunsuite){ 110 | listener.begin(s, info, (size_t) 111 | count_if(s.begin(),s.end(),boost_or_tr1::bind(&runner_aux::ArgvTestFilter::shouldRun,filter,boost_or_tr1::bind(&test::name,_1)))); 112 | for(suite::const_iterator it = s.begin();it != s.end();++it){ 113 | if (filter.shouldRun(it->name())) result = this->runit(*it) && result; 114 | } 115 | listener.end(s, info); 116 | } 117 | 118 | return result; 119 | } 120 | private: 121 | bool needsFiltering(int argc, const char *const *argv) const 122 | { 123 | return argc > 1 && argv ; 124 | } 125 | 126 | 127 | bool runit(const test & t) const 128 | { 129 | try { 130 | listener.start(t); 131 | t(); 132 | listener.success(t, "OK"); 133 | return true; 134 | } catch(const cute::test_failure & e){ 135 | listener.failure(t, e); 136 | } catch(const std::exception & exc){ 137 | listener.error(t, demangle(exc.what()).c_str()); 138 | } catch(std::string & s){ 139 | listener.error(t, s.c_str()); 140 | } catch(const char *&cs) { 141 | listener.error(t,cs); 142 | } catch(...) { 143 | listener.error(t,"unknown exception thrown"); 144 | } 145 | return false; 146 | } 147 | }; 148 | template 149 | runner makeRunner(Listener &s, int argc = 0, const char *const *argv = 0){ 150 | return runner(s,argc,argv); 151 | } 152 | } 153 | 154 | #endif /*CUTE_RUNNER_H_*/ 155 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/Consumption.cpp: -------------------------------------------------------------------------------- 1 | #include "Consumption.h" 2 | #include "pssst.h" 3 | #include "cute.h" 4 | 5 | #include 6 | 7 | using namespace pssst; 8 | 9 | struct literGas 10 | : strong{ 11 | constexpr static inline auto suffix=" l"; 12 | }; 13 | 14 | struct kmDriven:strong 15 | ,ScalarMultImpl,Out{ 16 | constexpr static inline auto prefix="driven "; 17 | constexpr static inline auto suffix=" km"; 18 | }; 19 | 20 | struct literPer100km 21 | :strong{ 22 | constexpr static inline auto suffix=" l/100km"; 23 | }; 24 | struct kmpl 25 | :strong{ 26 | constexpr static inline auto suffix=" km/l"; 27 | }; 28 | 29 | 30 | constexpr 31 | literPer100km operator/(literGas l, kmDriven km){ 32 | return {l.value/(km/100.0).value}; 33 | } 34 | 35 | constexpr 36 | kmpl operator/(kmDriven km, literGas l){ 37 | return {km.value/l.value}; 38 | } 39 | 40 | 41 | static_assert(sizeof(double)==sizeof(kmDriven)); 42 | 43 | 44 | namespace myliterals { 45 | constexpr literGas operator"" _l(long double value){ 46 | return literGas{static_cast(value)}; 47 | } 48 | constexpr literGas operator"" _l(unsigned long long value){ 49 | return literGas{static_cast(value)}; 50 | } 51 | constexpr kmDriven operator"" _km(long double value){ 52 | return kmDriven{static_cast(value)}; 53 | } 54 | constexpr kmDriven operator"" _km(unsigned long long value){ 55 | return kmDriven{static_cast(value)}; 56 | } 57 | } 58 | 59 | 60 | literPer100km consumption(literGas l, kmDriven km) { 61 | return l/km; 62 | } 63 | kmpl efficiency(literGas l, kmDriven km) { 64 | return km/l; 65 | } 66 | void testConsumptionVSEfficiency(){ 67 | using namespace myliterals; 68 | literGas const l { 0xA_l }; 69 | auto const km = 200_km; 70 | ASSERT_EQUAL(100/(l/km).value, (km/l).value); 71 | } 72 | 73 | 74 | void testConsumption1over1(){ 75 | literGas const l {1} ; 76 | kmDriven const km { 1 } ; 77 | ASSERT_EQUAL(literPer100km{100.0},consumption(l,km)); 78 | } 79 | void testEfficiency1over1(){ 80 | literGas const l {1} ; 81 | kmDriven const km { 1 } ; 82 | ASSERT_EQUAL(kmpl{1.0},efficiency(l, km)); 83 | } 84 | 85 | void testConsumption40over500(){ 86 | literGas const l { 40 }; 87 | kmDriven const km { 500 }; 88 | ASSERT_EQUAL(literPer100km{8.0},consumption(l,km)); 89 | } 90 | 91 | void testConsumtionWithLiterals(){ 92 | using namespace myliterals; 93 | ASSERT_EQUAL(literPer100km{8.0},consumption(40._l,500_km)); 94 | } 95 | void testConsumtionWithOutput(){ 96 | using namespace myliterals; 97 | std::ostringstream out{}; 98 | 99 | ASSERT_EQUAL(literPer100km{8.0},consumption(40._l,500_km)); 100 | } 101 | void testLiterOutputWithSuffix(){ 102 | literGas const l { 40 }; 103 | std::ostringstream out{}; 104 | out << l; 105 | ASSERT_EQUAL("40 l",out.str()); 106 | } 107 | void testKmOutputWithPrefixAndSuffix(){ 108 | kmDriven const k { 500 }; 109 | std::ostringstream out{}; 110 | out << k; 111 | ASSERT_EQUAL("driven 500 km",out.str()); 112 | } 113 | 114 | 115 | // try mix-in without strong... 116 | 117 | 118 | 119 | struct liter : ops{ 120 | // needs ctor to avoid need for extra {} 121 | constexpr explicit liter(double lit):l{lit}{}; 122 | double l{}; 123 | }; 124 | static_assert(sizeof(liter)==sizeof(double)); // ensure empty bases are squashed 125 | static_assert(std::is_trivially_copyable_v); // ensure efficient argument passing 126 | 127 | 128 | void testLiterWithoutStrong(){ 129 | liter l1 {43. }; 130 | liter l2 {42.1 }; 131 | l2 += liter{0.8}; 132 | ASSERT_EQUAL_DELTA(l1,l2,liter{0.11}); 133 | } 134 | 135 | 136 | namespace withoutpssst { 137 | struct literGas{ 138 | double value; 139 | }; 140 | struct kmDriven{ 141 | double value; 142 | }; 143 | struct literper100km{ 144 | double value; 145 | constexpr 146 | bool operator==(literper100km const & r) 147 | const & noexcept { // make it symmetric 148 | return value == r.value; // shady bc double 149 | } 150 | constexpr 151 | bool operator!=(literper100km const & r) 152 | const & noexcept { 153 | return ! (*this == r); 154 | } 155 | }; 156 | 157 | literper100km consumption(literGas liter, kmDriven km){ 158 | return {liter.value/(km.value/100)}; 159 | // braces needed (aggregate initialization) 160 | } 161 | void demonstrateStrongTypeProblem() { 162 | literGas consumed{40}; 163 | kmDriven distance{500}; 164 | ASSERT_EQUAL(literper100km{8}, consumption(consumed,distance)); 165 | // error: no match for 'operator==' 166 | } 167 | 168 | 169 | } 170 | 171 | namespace withsimplebool { 172 | 173 | template 174 | struct Eq{ 175 | friend constexpr 176 | bool 177 | operator==(U const &l, U const& r) noexcept { 178 | auto const &[vl]=l; 179 | auto const &[vr]=r; 180 | return vl == vr; 181 | } 182 | friend constexpr 183 | bool 184 | operator!=(U const &l, U const& r) noexcept { 185 | return !(l==r); 186 | } 187 | }; 188 | 189 | 190 | struct literGas{ 191 | double value; 192 | }; 193 | struct kmDriven{ 194 | double value; 195 | }; 196 | struct literper100km : Eq { 197 | double value; 198 | }; 199 | 200 | literper100km consumption(literGas liter, kmDriven km){ 201 | return {{},liter.value/(km.value/100)}; 202 | // braces needed (aggregate initialization) 203 | } 204 | void demonstrateStrongTypeProblem() { 205 | literGas consumed{40}; 206 | kmDriven distance{500}; 207 | ASSERT_EQUAL((literper100km{{},8}), consumption(consumed,distance)); 208 | // error: no match for 'operator==' 209 | } 210 | static_assert(std::is_arithmetic_v); 211 | 212 | constexpr literper100km l12{{},12}, l24{{},24}; 213 | 214 | // for c++now talk. gives warning. 215 | // static_assert(2 * (l12 != l24)); 216 | } 217 | 218 | cute::suite make_suite_Consumption() { 219 | cute::suite s { }; 220 | s.push_back(CUTE(testConsumption1over1)); 221 | s.push_back(CUTE(testConsumption40over500)); 222 | s.push_back(CUTE(testLiterWithoutStrong)); 223 | s.push_back(CUTE(testConsumtionWithLiterals)); 224 | s.push_back(CUTE(testLiterOutputWithSuffix)); 225 | s.push_back(CUTE(testKmOutputWithPrefixAndSuffix)); 226 | s.push_back(CUTE(testConsumtionWithOutput)); 227 | s.push_back(CUTE(testEfficiency1over1)); 228 | s.push_back(CUTE(testConsumptionVSEfficiency)); 229 | s.push_back(CUTE(withoutpssst::demonstrateStrongTypeProblem)); 230 | s.push_back(CUTE(withsimplebool::demonstrateStrongTypeProblem)); 231 | return s; 232 | } 233 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/pssst_static_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "pssst.h" 2 | namespace pssst { 3 | namespace testing___{ 4 | 5 | 6 | using ::pssst::underlying_value_type; 7 | static_assert(!detail_::needsbaseinit{},"needsbasinit for built-in"); 8 | 9 | struct Y {}; 10 | struct X:Y{int v;}; 11 | static_assert(detail_::needsbaseinit{},"needsbasinit with empty class false"); 12 | 13 | template 14 | struct is_vector_space : std::false_type{}; 15 | template 16 | struct is_vector_space> : std::true_type{}; 17 | template 18 | constexpr inline bool is_vector_space_v=is_vector_space::value; 19 | 20 | 21 | /// trying anti-compile tests... badly so far 22 | template 23 | struct doesnt_compile_less_twice:std::true_type{}; 24 | 25 | struct testless:strong{}; 26 | 27 | template 28 | struct doesnt_compile_less_twice>:std::false_type{}; 29 | 30 | #define expr(...) std::void_t 31 | 32 | #define dc(T,...) template struct doesnt_compile_less_twice:std::false_type{}; 33 | 34 | 35 | static_assert(doesnt_compile_less_twice{}); 36 | //---------- 37 | 38 | 39 | static_assert(!is_vector_space_v,"int is no absolute unit"); 40 | 41 | 42 | 43 | struct bla:Linear{}; 44 | static_assert(sizeof(bla)==sizeof(int)); 45 | static_assert(!is_vector_space_v,"bla is absolute?"); 46 | static_assert(0 == bla{0}.value, "check for subobject warning"); 47 | struct blu:affine_space_for{}; 48 | static_assert(sizeof(blu)==sizeof(int)); 49 | static_assert(is_vector_space_v,"blu should be vector space"); 50 | //static_assert(bool(blu::origin==blu{0}),"blu origin is zero"); 51 | static_assert(blu{42}.value==bla{42}, "rel accessible"); 52 | static_assert(std::is_same_v>,".."); 53 | 54 | constexpr bla x{42}; 55 | constexpr bla eightyfour{84}; 56 | static_assert(value(-x) == -value(x)); 57 | //static_assert(abs(-x) == abs(x)); // std::abs not yet constexpr 58 | static_assert(x == x); 59 | static_assert(x != -x); 60 | static_assert(x + x == eightyfour); 61 | static_assert(x - x == bla{0}); 62 | static_assert(x - -x == eightyfour); 63 | static_assert(x * 2 == eightyfour); 64 | static_assert(2 * x == eightyfour); 65 | static_assert(eightyfour / 2 == x); 66 | static_assert(eightyfour / x == 2); 67 | static_assert(x % 5 == bla{2}); 68 | 69 | // trait: is_ebo 70 | namespace detail{ 71 | template 72 | struct is_ebo_impl{ 73 | struct non_empty{ char x;}; 74 | struct test:std::conditional_t && !std::is_final_v,EBase,non_empty> { 75 | char c; 76 | }; 77 | static_assert(sizeof(non_empty)==sizeof(char),"structs should have optimal size"); 78 | static inline constexpr bool value{sizeof(test)==sizeof(non_empty)}; 79 | }; 80 | } 81 | template 82 | struct is_ebo: std::bool_constant::value>{}; 83 | 84 | template 85 | constexpr inline bool is_ebo_v=is_ebo::value; 86 | 87 | struct dummy{int i;}; 88 | static_assert(is_ebo_v>,"Add should be EBO enabled"); 89 | static_assert(is_ebo_v>,"Sub should be EBO enabled"); 90 | static_assert(is_ebo_v>,"Out should be EBO enabled"); 91 | static_assert(is_ebo_v>,"Eq should be EBO enabled"); 92 | static_assert(is_ebo_v>,"Order should be EBO enabled"); 93 | static_assert(is_ebo_v>,"BitOps should be EBO enabled"); 94 | static_assert(is_ebo_v>,"ShiftOps should be EBO enabled"); 95 | static_assert(is_ebo_v>,"Inc should be EBO enabled"); 96 | static_assert(is_ebo_v>,"Dec should be EBO enabled"); 97 | static_assert(is_ebo_v>,"UPlus should be EBO enabled"); 98 | static_assert(is_ebo_v>,"UMinus should be EBO enabled"); 99 | static_assert(is_ebo_v>,"Value should be EBO enabled"); 100 | static_assert(is_ebo_v>,"Rounding should be EBO enabled"); 101 | static_assert(is_ebo_v>,"Abs should be EBO enabled"); 102 | static_assert(is_ebo_v>,"ExpLog should be EBO enabled"); 103 | static_assert(is_ebo_v>,"Root should be EBO enabled"); 104 | static_assert(is_ebo_v>,"Trigonometric should be EBO enabled"); 105 | static_assert(is_ebo_v>,"ScalarModulo should be EBO enabled"); 106 | static_assert(is_ebo_v::apply>,"ScalarModulo should be EBO enabled"); 107 | static_assert(is_ebo_v::template apply>>,"ops should be EBO"); 112 | struct dummy_d:ops { 113 | double v; 114 | }; 115 | static_assert(sizeof(double)==sizeof(dummy_d),"dummy_d should be same size as double"); 116 | 117 | namespace test_ArithModulo{ 118 | 119 | struct wrong:strong,ArithMultImpl, Eq{}; 120 | static_assert(detail_::has_check_base_v); 121 | // fails to compile due to check that multiplication base is same as value type 122 | // static_assert(wrong{1} == wrong{1}/wrong{1}); 123 | // static_assert(wrong{1} == wrong{1}*wrong{1}); 124 | // static_assert(wrong{1} == wrong{1}%wrong{1}); 125 | enum bla:int{}; 126 | constexpr bla operator%(bla ,bla ){ return bla{};} 127 | static_assert(detail_::supports_modulo_v); 128 | 129 | } 130 | 131 | struct liter : ops{ 132 | // needs ctor to avoid need for extra {} below 133 | constexpr explicit liter(double lit):l{lit}{}; 134 | double l{}; 135 | }; 136 | static_assert(sizeof(liter)==sizeof(double)); // ensure empty bases are squashed 137 | static_assert(std::is_trivially_copyable_v); // ensure efficient argument passing 138 | static_assert(not detail_::needsbaseinit{},"does liter need base init?"); 139 | 140 | 141 | 142 | } 143 | 144 | namespace testWithEnum { 145 | 146 | enum ue : unsigned {}; 147 | constexpr 148 | ue operator |(ue l, ue r){ return ue{unsigned(l)|unsigned(r)}; } 149 | 150 | struct sue : strong{}; 151 | 152 | static_assert(0 == value(sue{} | sue{})); 153 | 154 | enum ie : int {}; 155 | constexpr 156 | ie operator |(ie l, ie r){ return ie{int(l)|int(r)}; } 157 | 158 | struct sie : strong{}; 159 | 160 | // fails to compile as expected: error: static assertion failed: bitops are only be enabled for unsigned types 161 | //static_assert(0 == value(sie{} | sie{})); 162 | 163 | } 164 | 165 | 166 | } 167 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/Test.cpp: -------------------------------------------------------------------------------- 1 | #include "pssst.h" 2 | 3 | #include "ArraySizeDiffStrong.h" 4 | #include "Degrees.h" 5 | #include "Consumption.h" 6 | #include "ConsumptionWithoutStrong.h" 7 | #include "StrongWithEncapsulation.h" 8 | #include "StrongWithConstructor.h" 9 | #include "SafeArithmetic.h" 10 | #include "StringOperations.h" 11 | #include "cute.h" 12 | #include "ide_listener.h" 13 | #include "xml_listener.h" 14 | #include "cute_runner.h" 15 | #include "BooleanTest.h" 16 | #include "BitOperationsTest.h" 17 | #include 18 | #include "EnumOperators.h" 19 | #include "ArithmeticOperationsTest.h" 20 | #include "DoubleErsatz.h" 21 | #include "OhmsLaw.h" 22 | #include "xxx.h" 23 | 24 | 25 | using namespace pssst; 26 | struct Int: strong{ 27 | }; 28 | 29 | namespace { 30 | Int dummy{42}; 31 | 32 | [[maybe_unused]]int &y = value_ref(dummy); 33 | 34 | } 35 | struct Size: strong { 36 | }; 37 | static_assert(sizeof(Size)==sizeof(unsigned),"no overhead"); 38 | static_assert(std::is_trivially_copyable_v,"should be trivial"); 39 | static_assert(std::is_aggregate_v); 40 | 41 | void testSizeworks(){ 42 | Size sz{42}; 43 | //ASSERT_EQUAL(42,sz);// doesn't compile 44 | //ASSERT_EQUAL(42u,sz);//doesn't compile 45 | ASSERT_EQUAL(Size{21}+Size{21},sz); 46 | } 47 | 48 | 49 | 50 | 51 | 52 | 53 | struct uptest:strong{}; 54 | 55 | 56 | void testUPlus(){ 57 | uptest one{1}; 58 | ASSERT_EQUAL(one.value,(+one).value); 59 | } 60 | void testUMinus(){ 61 | struct umtest:strong{}; 62 | umtest one{1}; 63 | ASSERT_EQUAL(-(one.value),(-one).value); 64 | } 65 | void testUInc(){ 66 | struct uinctest:strong{}; 67 | uinctest var{1}; 68 | ASSERT_EQUAL(2,(++var).value); 69 | ASSERT_EQUAL(2,(var++).value); 70 | ASSERT_EQUAL(3,var.value); 71 | } 72 | void testUDec(){ 73 | struct udtest:strong{}; 74 | udtest var{2}; 75 | ASSERT_EQUAL(1,(--var).value); 76 | ASSERT_EQUAL(1,(var--).value); 77 | ASSERT_EQUAL(0,var.value); 78 | } 79 | 80 | struct S:strong{}; 81 | 82 | void testWithStringBase(){ 83 | S s{"hello"}; 84 | ASSERT_EQUAL(S{"hello"},s); 85 | } 86 | 87 | void testMoveWithStringBase(){ 88 | S s{std::string(1000u,'a')}; // assume beyond SSO 89 | char const *data = value(s).data(); 90 | ASSERT_EQUAL(1000ul,value(s).size()); 91 | ASSERT_LESS_EQUAL(1000ul,value(s).capacity()); 92 | std::string other{value_consume(std::move(s))}; 93 | ASSERT_EQUAL(1000ul,other.size()); 94 | ASSERT_EQUAL(0ul,value_ref(s).size()); 95 | ASSERT_EQUAL(intptr_t(data),intptr_t(other.data())); 96 | } 97 | 98 | struct WaitC:strong{}; 99 | static_assert(sizeof(unsigned)==sizeof(WaitC)); 100 | void testWaitCounter(){ 101 | WaitC c{}; 102 | WaitC const one{1}; 103 | ASSERT_EQUAL(WaitC{0},c); 104 | ASSERT_EQUAL(one,++c); 105 | ASSERT_EQUAL(one,c++); 106 | ASSERT_EQUAL(2,c.value); 107 | } 108 | 109 | namespace p0109{ 110 | // model p0109 energy example 111 | 112 | struct energy: Linear{}; 113 | 114 | struct thermal : energy, LinearOps{}; 115 | 116 | struct kinetic: energy, LinearOps{}; 117 | 118 | void test_energy_expressions(){ 119 | energy e{1.23}; // okay; explicit 120 | //double d{e}; // error P0109 explicit 121 | double d{value(e)}; // pssst version of explicit 122 | // d = e; // error: cannot convert 'p0109::energy' to 'double' in assignment 123 | e = e + e; // okay 124 | //e = e * e; // error; call to deleted function 125 | // error: no match for 'operator*' (operand types are 'p0109::energy' and 'p0109::energy') 126 | e *= 2.71828; // okay 127 | 128 | thermal t{4.56}; 129 | kinetic k{7.89}; 130 | e = t; e = k; // both okay; public allows type adjustment 131 | //t = e; t = k; // both in error; the adjustment is only unidirectional 132 | // error: no match for 'operator=' (operand types are 'p0109::thermal' and 'p0109::energy') 133 | t=t+t; k=k+k; //okay; public implies default trampolines 134 | e = t + k; // okay; calls the underlying trampoline 135 | ASSERT_EQUAL(1.23,d); // dummy 136 | } 137 | 138 | } 139 | 140 | namespace demo_output_crtp { 141 | 142 | struct literper100km : Out { 143 | double value; 144 | constexpr static inline auto prefix="consumption "; 145 | constexpr static inline auto suffix=" l/100km"; 146 | }; 147 | 148 | void demo_output_crtp(){ 149 | literper100km consumed{{},9.5}; 150 | std::ostringstream out{}; 151 | out << consumed; 152 | ASSERT_EQUAL("consumption 9.5 l/100km", out.str()); 153 | } 154 | 155 | 156 | } 157 | 158 | 159 | 160 | bool runAllTests(int argc, char const *argv[]) { 161 | cute::suite s { }; 162 | //TODO add your test here 163 | s.push_back(CUTE(testWithStringBase)); 164 | s.push_back(CUTE(testSizeworks)); 165 | s.push_back(CUTE(testUPlus)); 166 | s.push_back(CUTE(testUMinus)); 167 | s.push_back(CUTE(testUInc)); 168 | s.push_back(CUTE(testUDec)); 169 | s.push_back(CUTE(testWaitCounter)); 170 | s.push_back(CUTE(testMoveWithStringBase)); 171 | cute::xml_file_opener xmlfile(argc, argv); 172 | cute::xml_listener> lis(xmlfile.out); 173 | auto const runner = cute::makeRunner(lis, argc, argv); 174 | bool success = runner(s, "AllTests"); 175 | cute::suite DoubleErsatz = make_suite_DoubleErsatz(); 176 | success &= runner(DoubleErsatz, "DoubleErsatz"); 177 | cute::suite BitOperationsTest = make_suite_BitOperationsTest(); 178 | success &= runner(BitOperationsTest, "BitOperationsTest"); 179 | cute::suite ArraySizeDiffStrong = make_suite_ArraySizeDiffStrong(); 180 | success = runner(ArraySizeDiffStrong, "ArraySizeDiffStrong") && success; 181 | cute::suite Degrees = make_suite_Degrees(); 182 | success = runner(Degrees, "Degrees") && success; 183 | cute::suite Consumption = make_suite_Consumption(); 184 | success = runner(Consumption, "Consumption") && success; 185 | cute::suite ConsumptionWithoutStrong = make_suite_ConsumptionWithoutStrong(); 186 | success = runner(ConsumptionWithoutStrong, "ConsumptionWithoutStrong") && success; 187 | cute::suite StrongWithEncapsulation = make_suite_StrongWithEncapsulation(); 188 | success = runner(StrongWithEncapsulation, "StrongWithEncapsulation") && success; 189 | cute::suite StrongWithConstructor = make_suite_StrongWithConstructor(); 190 | success = runner(StrongWithConstructor, "make_suite_StrongWithConstructor") && success; 191 | cute::suite SafeArithmetic = make_suite_SafeArithmetic(); 192 | success = runner(SafeArithmetic, "SafeArithmetic") && success; 193 | cute::suite StringOperations = make_suite_StringOperations(); 194 | success = runner(StringOperations, "StringOperations") && success; 195 | cute::suite BooleanTest = make_suite_BooleanTest(); 196 | success &= runner(BooleanTest, "BooleanTest"); 197 | cute::suite EnumOperators = make_suite_EnumOperators(); 198 | success &= runner(EnumOperators, "EnumOperators"); 199 | cute::suite ArithmeticOperationsTest = make_suite_ArithmeticOperationsTest(); 200 | ArithmeticOperationsTest.push_back(CUTE(p0109::test_energy_expressions)); 201 | ArithmeticOperationsTest.push_back(CUTE(demo_output_crtp::demo_output_crtp)); 202 | success &= runner(ArithmeticOperationsTest, "ArithmeticOperationsTest"); 203 | cute::suite OhmsLaw = make_suite_OhmsLaw(); 204 | success &= runner(OhmsLaw, "OhmsLaw"); 205 | cute::suite xxx = make_suite_xxx(); 206 | success &= runner(xxx, "xxx"); 207 | return success; 208 | } 209 | 210 | int main(int argc, char const *argv[]) { 211 | return runAllTests(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE; 212 | } 213 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PSsst 2 | Peter Sommerlad's Simple Strong Typing 3 | 4 | ```C++ 5 | struct Word:strong{}; 6 | Word operator"" _w(char const * const s, size_t l){ 7 | return Word{std::string{s,l}}; 8 | } 9 | void testStringAdditionWorks(){ 10 | Word w{}; 11 | w += "Hello "_w; 12 | w = w + "World!"_w; 13 | ASSERT_EQUAL("Hello World!"_w, w); 14 | } 15 | ``` 16 | 17 | 18 | 19 | Using user-defined types instead of the built-in types can greatly increase the usability and understandability of code. 20 | In addition it provides a compile-time safety net of accidental misuse. 21 | In C++ this is especially important, since the language mechanisms inherited from C allow one to easily mix up usages of numeric types including `bool` without producing compiler warnings. 22 | Such code is error prone due to data loss and can accidentally incur undefined behavior, e.g., operations on `uint16_t` values leading to signed integer overflow situations due to integral promotion to `int`. 23 | 24 | On the other hand, writing your own types with useful operations can be tedious as well, even if they just wrap a single value of one of the built-in types. 25 | For example, while it is beneficial to avoid misuse to limit the set of available operations in comparison to the built-in types, it is tedious to implement corresponding operator overloads to provide useful operations, e.g., comparisons. Having many such type wrappers will also incur code duplication. This has led to other strong typing frameworks and even suggestions for changing the C++ language (https://wg21.link/p0109). 26 | 27 | Nevertheless, using a simple `struct` wrapping a single value already provides most of the parameter safety, but it means to compute with such a value requires either to take and replace its guts, uglyfying the code, or to implement the required operator overloads. 28 | 29 | Based on the assumption that often such user-defined value types are representing a single value of built-in types and will be replacing the use of `int`, `double` or similar built-in types I created this framework/library to allow the simple creation of domain-specific wrappers for such types. 30 | Pre-defined mix-in base classes provide a set of consistently-defined operators, e.g., `Eq` for equality comparison, `Order` for relational operators, `Additive` for summing and differences, or `Linear` for types that also allow multiplications with a scalar. 31 | The `Out` mix-in base class provides a simple output operator overload that can be customized by optional static members `prefix` and `postfix` to provide some additional formatting. 32 | However, all those mix-in bases are templates parameterized by your type that they extend. If you intend to use several such mix-ins, spelling your own type name again and again is tedious. 33 | Therefore, a grouping mechanism is provided by the template `ops`. 34 | 35 | To allow such a generic implementation of operators we lose the ability to strictly encapsulate the wrapped value. 36 | But since this is created to replace usages of plain integers or floating point numbers not much is lost by that, for the gain of additional type safety. 37 | 38 | There are two options to provide the type and position of the wrapped value: 39 | 40 | 1. By using the class template `strong` as the first base class of your wrapper `mytype`, followed by the operations mix-ins. 41 | ```C++ 42 | struct literPer100km : strong { }; 43 | ``` 44 | This defines the type literPer100km with the ability to store a `double` value and having operators `== !=` as well as an `std::ostream` output operator defined. 45 | A value for that type can be created using `literPer100km{5.6}`. 46 | 47 | 2. By just having a single public non-static member variable and inheriting just from the operations mix-ins. 48 | ``` 49 | struct literPer100km : ops { 50 | double consuption{}; 51 | }; 52 | ``` 53 | This definition creates a type with the same operators than above, but it needs to be initialized with an extra pair of braces for its base class `literPer100km{{},5.6}`. This need can be eliminated by providing a constructor. However, defining such a constructor might eliminate the ability to detect narrowing conversions, unless unwanted conversion constructor overloads are defined as deleted. 54 | 55 | The first option allows the type to remain an aggregate, where the first part of the aggregate is the only one required to be intialized: `literPer100km{8}` 56 | 57 | The second option makes using the class a bit of a hassle, because the empty base-class requires an empty pair of braces whenever one constructs a value of the type: `literPer100km{{},8}` 58 | This extra pair of braces can be eliminated by providing a constructor in your class, but that is already boilerplate code I would like to reduce. 59 | 60 | The "trick" to achieve the desired code brevity are the C++17 features: 61 | * [Extension to aggregate initialization](https://wg21.link/p0017) 62 | * [Structured Bindings](https://wg21.link/p0144) 63 | 64 | For a C++14 version of the framework the lack of these features means that one needs to provide a constructor for each strong type and that to allow operator mix-in implementation that the sole data member must follow a specific naming convention (`.value`). Only the second form from the list above makes sense then. 65 | 66 | ```C++ 67 | // TODO example for C++14 branch 68 | ``` 69 | 70 | ### List of Mix-in Bases 71 | The following CRTP class templates provide operators that you can pick and choose for strong types with PSsst. NB, binary operators always include corresponding combined assignment operator: 72 | * Eq: `==` `!=` 73 | * Order: Eq and `< <= > >=` 74 | * UPlus: unary `+` (not useful for wrapped built-in types) 75 | * UMinus: unary `-`, negation 76 | * Inc: `++` increment (pre and post) 77 | * Dec: `--` decrement (pre and post) 78 | * BitOps: unary `~` binary `| & ^` underlying value type must be unsigned type 79 | * ShiftOps: `>>` `<<` default for rhs number of bits is `unsigned` 80 | * Add: binary `+` 81 | * Sub: binary `-` 82 | * Abs: calling std::abs or another abs function picked by ADL (allows wrapping a wrapper) 83 | * Rounding: provides `` functions converting floating points to integral values 84 | * ExpLog: provides `` functions for exponentiation and logarithms. result is corresponding floating point value 85 | * Root: provides `` `sqrt` and `cbrt`. result is corresponding floating point value 86 | * Trigonometric: provides `` `sin cos tan asin acos atan` functions, result is corresponding floating point value 87 | * Out: `std::ostream&` output operator. static members in strong type with names `prefix` and `suffix` can control formatting 88 | * ScalarMult: binary `* /` with a scalar value, `%` is provided if the scalar type is an integer. 89 | It is unchecked, if the scalar matches the type of the member, but highly recommended to do so. 90 | this is a bit tricky to use in general, because it has two template parameters, the second one for the scalar type. Using it in the list of operations templates looks like `ScalarMult::apply`. Therefore, aliases for the common cases are provided: 91 | * `ScalarMult_d= ScalarMultImpl;` 92 | * `ScalarMult_f= ScalarMultImpl;` 93 | * `ScalarMult_ld= ScalarMultImpl;` 94 | * `ScalarMult_i= ScalarMultImpl; 95 | * `ScalarMult_ll= ScalarMultImpl;` 96 | * ScalarModulo: `%` base class of ScalarMult if the scalar type is integral. same issue with ScalarMult about 2nd template argument handled there, no separate aliases for it. 97 | * Additive: `ops` 98 | * Linear: similar issue as with ScalarMult, since it needs to promote 99 | 100 | list of pre-combined aliases: 101 | 102 | 103 | 104 | ### A better `Bool` than `bool` -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/ArithmeticOperationsTest.cpp: -------------------------------------------------------------------------------- 1 | #include "ArithmeticOperationsTest.h" 2 | #include "cute.h" 3 | #include "pssst.h" 4 | 5 | #include 6 | 7 | using namespace pssst; 8 | 9 | namespace test_LinearOps { 10 | //Additive, detail__::bind2::template apply, Order, Value 11 | // Additive=ops 12 | struct td: Linear{}; 13 | 14 | void testValue(){ 15 | td const x{4.2}; 16 | ASSERT_EQUAL(4.2,value(x)); 17 | } 18 | 19 | void testValueRef(){ 20 | td x{4.2}; 21 | auto&& ref = value_ref(x); 22 | 23 | static_assert(std::is_lvalue_reference_v); 24 | 25 | ASSERT_EQUAL(reinterpret_cast(&x.value),reinterpret_cast(&ref)); 26 | } 27 | void testValueConsume(){ 28 | td x{4.2}; 29 | auto&& ref = value_consume(std::move(x)); 30 | static_assert(std::is_rvalue_reference_v); 31 | ASSERT_EQUAL(reinterpret_cast(&x.value),reinterpret_cast(&ref)); 32 | } 33 | 34 | void testUnaryMinus(){ 35 | td const x{4.2}; 36 | td const y{-x}; 37 | ASSERT_EQUAL(value(y),-value(x)); 38 | ASSERT_EQUAL(-value(y),value(x)); 39 | } 40 | 41 | void testAbs(){ 42 | td const x{4.2}; 43 | td const y{-x}; 44 | ASSERT_EQUAL(value(abs(y)),value(abs(x))); 45 | ASSERT_EQUAL(abs(y),abs(x)); 46 | } 47 | 48 | void testEqualityComparison(){ 49 | td const x{4.2}; 50 | ASSERT(x == x); 51 | ASSERT(x != td{0}); 52 | ASSERT(td{0} == td{0}); 53 | } 54 | 55 | void testAddBinary(){ 56 | td const expected{42}; 57 | td const res = td{20.5}+td{21.5}; 58 | ASSERT_EQUAL(value(expected),value(res)); 59 | ASSERT_EQUAL(expected,res); // implicitly tests operator== 60 | } 61 | 62 | void testAddAssign(){ 63 | td const expected{4.2}; 64 | td res{2.5}; 65 | res += td{1.7}; 66 | ASSERT_EQUAL(expected,res); 67 | } 68 | void testSubBinary(){ 69 | td const expected{42.2}; 70 | td const res = td{80.7} - td{38.5}; 71 | ASSERT_EQUAL(value(expected),value(res)); 72 | ASSERT_EQUAL(expected,res); // implicitly tests operator== 73 | } 74 | 75 | void testSubAssign(){ 76 | td const expected{4.2}; 77 | td res{5.9}; 78 | res -= td{1.7}; 79 | ASSERT_EQUAL(expected,res); 80 | } 81 | 82 | void testScalarMultFirst(){ 83 | td const expected{4.2}; 84 | ASSERT_EQUAL(expected,2 * td{2.1}); 85 | } 86 | void testScalarMultSecond(){ 87 | td const expected{4.2}; 88 | ASSERT_EQUAL(expected,td{10.5} * 0.4); 89 | } 90 | void testScalarMultBy(){ 91 | td x{100.0}; 92 | x *= 4.2/10; 93 | ASSERT_EQUAL_DELTA(td{42},x,td{0.000000001}); // auto detection of floating point not working on wrapped 94 | ASSERT_EQUAL(42., value(x)); 95 | } 96 | void testScalarMultDivBy(){ 97 | td const expected{4.2}; 98 | ASSERT_EQUAL(expected,td{10.5}/2.5); 99 | } 100 | void testScalarMultDivByAssign(){ 101 | td x{4.2}; 102 | x /= 0.1; 103 | ASSERT_EQUAL(td{42},x); 104 | } 105 | void testScalarMultDiv(){ 106 | ASSERT_EQUAL(4.2,td{10.5}/td{2.5}); 107 | } 108 | 109 | void testLessThan(){ 110 | ASSERT_LESS(td{0},td{0.00000000001}); 111 | } 112 | void testGreaterThan(){ 113 | ASSERT_GREATER(td{0.1},td{0.00000000001}); 114 | } 115 | void testLessEqualThan(){ 116 | ASSERT_LESS_EQUAL(td{0.0},td{-0.0}); 117 | } 118 | void testGreaterEqualThan(){ 119 | ASSERT_GREATER_EQUAL(td{-0.0},td{+0.0}); 120 | } 121 | 122 | } 123 | 124 | namespace test_arithmetic{ 125 | struct td: Arithmetic{}; 126 | void testValue(){ 127 | td const x{42}; 128 | ASSERT_EQUAL(42,value(x)); 129 | } 130 | 131 | void testValueRef(){ 132 | td x{42}; 133 | auto&& ref = value_ref(x); 134 | 135 | static_assert(std::is_lvalue_reference_v); 136 | 137 | ASSERT_EQUAL(reinterpret_cast(&x.value),reinterpret_cast(&ref)); 138 | } 139 | void testValueConsume(){ 140 | td x{42}; 141 | auto&& ref = value_consume(std::move(x)); 142 | static_assert(std::is_rvalue_reference_v); 143 | ASSERT_EQUAL(reinterpret_cast(&x.value),reinterpret_cast(&ref)); 144 | } 145 | 146 | void testUnaryMinus(){ 147 | td const x{42}; 148 | td const y{-x}; 149 | ASSERT_EQUAL(value(y),-value(x)); 150 | ASSERT_EQUAL(-value(y),value(x)); 151 | } 152 | 153 | void testAbs(){ 154 | td const x{42}; 155 | td const y{-x}; 156 | ASSERT_EQUAL(value(abs(y)),value(abs(x))); 157 | ASSERT_EQUAL(abs(y),abs(x)); 158 | } 159 | 160 | void testEqualityComparison(){ 161 | td const x{42}; 162 | ASSERT(x == x); 163 | ASSERT(x != td{0}); 164 | ASSERT(td{0} == td{0}); 165 | } 166 | 167 | void testAddBinary(){ 168 | td const expected{42}; 169 | td const res = td{20}+td{22}; 170 | ASSERT_EQUAL(value(expected),value(res)); 171 | ASSERT_EQUAL(expected,res); // implicitly tests operator== 172 | } 173 | 174 | void testAddAssign(){ 175 | td const expected{42}; 176 | td res{25}; 177 | res += td{17}; 178 | ASSERT_EQUAL(expected,res); 179 | } 180 | void testSubBinary(){ 181 | td const expected{422}; 182 | td const res = td{807} - td{385}; 183 | ASSERT_EQUAL(value(expected),value(res)); 184 | ASSERT_EQUAL(expected,res); // implicitly tests operator== 185 | } 186 | 187 | void testSubAssign(){ 188 | td const expected{42}; 189 | td res{59}; 190 | res -= td{17}; 191 | ASSERT_EQUAL(expected,res); 192 | } 193 | 194 | void testMult(){ 195 | td const expected{42}; 196 | ASSERT_EQUAL(expected,td{2} * td{21}); 197 | } 198 | void testMultAssign(){ 199 | td x{42}; 200 | x *= td{10}; 201 | ASSERT_EQUAL(td{420},x); 202 | } 203 | 204 | void testDiv(){ 205 | td const expected{42}; 206 | ASSERT_EQUAL(expected,td{1050}/td{25}); 207 | } 208 | void testDivAssign(){ 209 | td x{42}; 210 | x /= td{10}; 211 | ASSERT_EQUAL(td{4},x); 212 | } 213 | void testModulo(){ 214 | td const expected{25}; 215 | ASSERT_EQUAL(expected,td{1050+25}%td{42}); 216 | } 217 | void testModuloAssign(){ 218 | td x{42}; 219 | x %= td{10}; 220 | ASSERT_EQUAL(td{2},x); 221 | } 222 | 223 | void testLessThan(){ 224 | ASSERT_LESS(td{0},td{1}); 225 | } 226 | void testGreaterThan(){ 227 | ASSERT_GREATER(td{1},td{0}); 228 | } 229 | void testLessEqualThan(){ 230 | ASSERT_LESS_EQUAL(td{0},td{0}); 231 | } 232 | void testGreaterEqualThan(){ 233 | ASSERT_GREATER_EQUAL(td{0},td{0}); 234 | } 235 | 236 | } 237 | 238 | 239 | cute::suite make_suite_ArithmeticOperationsTest() { 240 | cute::suite s { }; 241 | s.push_back(CUTE(test_LinearOps::testValue)); 242 | s.push_back(CUTE(test_LinearOps::testValueRef)); 243 | s.push_back(CUTE(test_LinearOps::testValueConsume)); 244 | s.push_back(CUTE(test_LinearOps::testUnaryMinus)); 245 | s.push_back(CUTE(test_LinearOps::testAbs)); 246 | s.push_back(CUTE(test_LinearOps::testEqualityComparison)); 247 | s.push_back(CUTE(test_LinearOps::testAddBinary)); 248 | s.push_back(CUTE(test_LinearOps::testAddAssign)); 249 | s.push_back(CUTE(test_LinearOps::testSubBinary)); 250 | s.push_back(CUTE(test_LinearOps::testSubAssign)); 251 | s.push_back(CUTE(test_LinearOps::testScalarMultFirst)); 252 | s.push_back(CUTE(test_LinearOps::testScalarMultSecond)); 253 | s.push_back(CUTE(test_LinearOps::testScalarMultDivBy)); 254 | s.push_back(CUTE(test_LinearOps::testScalarMultDiv)); 255 | s.push_back(CUTE(test_LinearOps::testScalarMultBy)); 256 | s.push_back(CUTE(test_LinearOps::testScalarMultDivByAssign)); 257 | s.push_back(CUTE(test_LinearOps::testLessThan)); 258 | s.push_back(CUTE(test_LinearOps::testGreaterThan)); 259 | s.push_back(CUTE(test_LinearOps::testLessEqualThan)); 260 | s.push_back(CUTE(test_LinearOps::testGreaterEqualThan)); 261 | s.push_back(CUTE(test_arithmetic::testValue)); 262 | s.push_back(CUTE(test_arithmetic::testValueRef)); 263 | s.push_back(CUTE(test_arithmetic::testValueConsume)); 264 | s.push_back(CUTE(test_arithmetic::testUnaryMinus)); 265 | s.push_back(CUTE(test_arithmetic::testAbs)); 266 | s.push_back(CUTE(test_arithmetic::testEqualityComparison)); 267 | s.push_back(CUTE(test_arithmetic::testAddBinary)); 268 | s.push_back(CUTE(test_arithmetic::testAddAssign)); 269 | s.push_back(CUTE(test_arithmetic::testSubBinary)); 270 | s.push_back(CUTE(test_arithmetic::testSubAssign)); 271 | s.push_back(CUTE(test_arithmetic::testMult)); 272 | s.push_back(CUTE(test_arithmetic::testDiv)); 273 | s.push_back(CUTE(test_arithmetic::testDivAssign)); 274 | s.push_back(CUTE(test_arithmetic::testLessThan)); 275 | s.push_back(CUTE(test_arithmetic::testGreaterThan)); 276 | s.push_back(CUTE(test_arithmetic::testLessEqualThan)); 277 | s.push_back(CUTE(test_arithmetic::testGreaterEqualThan)); 278 | s.push_back(CUTE(test_arithmetic::testMultAssign)); 279 | s.push_back(CUTE(test_arithmetic::testModulo)); 280 | s.push_back(CUTE(test_arithmetic::testModuloAssign)); 281 | return s; 282 | } 283 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/BooleanTest.cpp: -------------------------------------------------------------------------------- 1 | #include "BooleanTest.h" 2 | #include "cute.h" 3 | #include 4 | #include 5 | #include "pssst.h" 6 | 7 | // a better Bool than bool, used for comparisons 8 | struct Bool { 9 | constexpr Bool() noexcept=default; 10 | constexpr Bool(bool const b) noexcept : 11 | val { b } { 12 | } 13 | friend constexpr Bool 14 | operator==(Bool const &l, Bool const& r) noexcept { 15 | return Bool{l.val == r.val}; 16 | } 17 | friend constexpr Bool 18 | operator!=(Bool const &l, Bool const& r) noexcept { 19 | return !(l==r); 20 | } 21 | friend constexpr Bool 22 | operator !(Bool const &l){ 23 | return Bool{! l.val}; 24 | } 25 | // convert from pointers 26 | template 27 | constexpr Bool(T * const x) noexcept : 28 | val { x!= nullptr }{ 29 | } 30 | constexpr Bool(std::nullptr_t) noexcept {} 31 | // other conversion attempts are not allowed 32 | template ::value 34 | && std::is_class_v< 35 | std::remove_cv_t> 36 | >> > 37 | constexpr Bool(T const &x) noexcept 38 | :Bool(static_cast(x)){} 39 | constexpr explicit operator bool() const noexcept { 40 | return val; 41 | } 42 | bool val{}; 43 | }; 44 | 45 | 46 | using namespace pssst; 47 | struct BoolTest { 48 | // test Bool properties 49 | static_assert(sizeof(Bool)==sizeof(bool)); 50 | static_assert(std::is_trivially_copyable_v); 51 | static_assert(std::is_trivially_destructible_v); 52 | 53 | 54 | constexpr static Bool const t { true }; 55 | constexpr static Bool const f { false }; 56 | void ConvertsTobool() const { 57 | ASSERTM("true is true", t); 58 | } 59 | void ConvertsFromStreamIndirectlyOnly() const { 60 | std::stringstream ss; 61 | ASSERT(Bool(ss)); 62 | } 63 | 64 | void OperatorNot() const { 65 | ASSERTM("not false is true", !f); 66 | } 67 | void DefaultIsFalse() const { 68 | ASSERTM("Default Bool{} is false", not Bool{}); 69 | } 70 | void OperatorNotTrue() const { 71 | ASSERTM("not true is false", not !t); 72 | } 73 | void OperatorOrTrueFalse() const { 74 | ASSERTM("true or false is true", t || f); 75 | } 76 | void OperatorOrFalseTrue() const { 77 | ASSERTM("true or false is true", t || f); 78 | } 79 | void OperatorOrFalse() const { 80 | ASSERTM("not(false or false)", not( f || f )); 81 | } 82 | void OperatorOrTrueTrue() const { 83 | ASSERTM("true or true", t || t); 84 | } 85 | void OperatorAndTrueTrue() const { 86 | ASSERTM("true and true", t && t); 87 | } 88 | void OperatorAndTrueFalse() const { 89 | ASSERTM("not(true and false)", not( t && f )); 90 | } 91 | void OperatorAndFalseTrue() const { 92 | ASSERTM("not(false and true)", not( f && t )); 93 | } 94 | void OperatorAndFalseFalse() const { 95 | ASSERTM("not(false and false)", not( f && f )); 96 | } 97 | void OperatorEqFalseFalse() const { 98 | ASSERTM("false == false", f == f); 99 | } 100 | void OperatorEqTrueTrue() const { 101 | ASSERTM("true == true", t == t); 102 | } 103 | void OperatorEqTrueFalse() const { 104 | ASSERTM("not(true == false)", not( t == f )); 105 | } 106 | void OperatorEqFalseTrue() const { 107 | ASSERTM("not(false == true)", not( f == t )); 108 | } 109 | void OperatorEqNotEqInequality() const { 110 | for(Bool const l:{f,t}) 111 | for(Bool const r:{f,t}) 112 | ASSERT_EQUAL((l==r), not(l != r)); 113 | } 114 | void TernaryOperatorWorksWithTrue() const { 115 | int i{}; 116 | i = t? i+1 : i; 117 | ASSERT_EQUAL(1,i); 118 | } 119 | void TernaryOperatorWorksWithFalse() const { 120 | int i{}; 121 | i = f? i : i + 1; 122 | ASSERT_EQUAL(1,i); 123 | } 124 | void OperatorOrShortCut() const { 125 | int i{}; 126 | t || ++i; 127 | ASSERT_EQUAL(0,i); 128 | } 129 | void OperatorOrShortCutPass() const { 130 | int i{}; 131 | f || ++i; 132 | ASSERT_EQUAL(1,i); 133 | } 134 | void OperatorAndShortCut() const { 135 | int i{}; 136 | f && ++i; 137 | ASSERT_EQUAL(0,i); 138 | } 139 | void OperatorAndShortCutPass() const { 140 | int i{}; 141 | t && ++i; 142 | ASSERT_EQUAL(1,i); 143 | } 144 | void OperatorBuiltInOrShortCutWithCast() const { 145 | int i{}; 146 | static_cast(t) || ++i; // select built-in || with cast to bool. 147 | ASSERT_EQUAL(0,i); 148 | } 149 | void OperatorBuiltInOrShortCutWithCastPass() const { 150 | int i{}; 151 | static_cast(f) || ++i; 152 | ASSERT_EQUAL(1,i); 153 | } 154 | void OperatorBuiltInAndShortCutWithCast() const { 155 | int i{}; 156 | static_cast(f) && ++i; 157 | ASSERT_EQUAL(0,i); 158 | } 159 | void OperatorBuiltInAndShortCutWithCastPass() const { 160 | int i{}; 161 | static_cast(t) && ++i; 162 | ASSERT_EQUAL(1,i); 163 | } 164 | 165 | struct Num: strong {}; 166 | 167 | static_assert(Num{3} == Num{3}); 168 | static_assert(not(Num{3} != Num{3})); 169 | static_assert(Num{3} <= Num{3}); 170 | static_assert(Num{3} >= Num{3}); 171 | static_assert(!(Num{3} < Num{3})); 172 | static_assert(!(Num{3} > Num{3})); 173 | // check for no arithmetic conversion 174 | template 175 | struct BoolDoesConvertFrom:std::false_type{}; 176 | template 177 | struct BoolDoesConvertFrom()})>>:std::true_type{}; 178 | template 179 | static constexpr bool BoolDoesConvertFrom_v = BoolDoesConvertFrom::value; 180 | 181 | static_assert(not BoolDoesConvertFrom_v); 182 | static_assert(not BoolDoesConvertFrom_v); 183 | static_assert(not BoolDoesConvertFrom_v); 184 | static_assert(BoolDoesConvertFrom_v); 185 | static_assert(BoolDoesConvertFrom_v); 186 | static_assert(BoolDoesConvertFrom_v); 187 | template > 188 | struct BoolDoesNotAddWith:std::true_type{}; 189 | template 190 | struct BoolDoesNotAddWith())>>:std::false_type{}; 191 | 192 | static_assert(BoolDoesNotAddWith{}); 193 | static_assert(BoolDoesNotAddWith{}); 194 | static_assert(BoolDoesNotAddWith{}); 195 | 196 | template > 197 | struct boolDoesNotAddWith:std::true_type{}; 198 | template 199 | struct boolDoesNotAddWith())>>:std::false_type{}; 200 | 201 | static_assert(not boolDoesNotAddWith{}); 202 | static_assert(not boolDoesNotAddWith{}); 203 | static_assert(boolDoesNotAddWith{}); 204 | static_assert(boolDoesNotAddWith{}); 205 | 206 | }; 207 | 208 | 209 | 210 | 211 | 212 | cute::suite make_suite_BooleanTest() { 213 | cute::suite s { }; 214 | s.push_back(CUTE_SMEMFUN(BoolTest, ConvertsTobool)); 215 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorNot)); 216 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorNotTrue)); 217 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorOrFalse)); 218 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorOrTrueTrue)); 219 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorAndTrueTrue)); 220 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorOrTrueFalse)); 221 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorOrFalseTrue)); 222 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorAndTrueFalse)); 223 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorAndFalseTrue)); 224 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorAndFalseFalse)); 225 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorEqFalseFalse)); 226 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorEqTrueTrue)); 227 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorEqTrueFalse)); 228 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorEqFalseTrue)); 229 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorEqNotEqInequality)); 230 | s.push_back(CUTE_SMEMFUN(BoolTest, DefaultIsFalse)); 231 | s.push_back(CUTE_SMEMFUN(BoolTest, TernaryOperatorWorksWithFalse)); 232 | s.push_back(CUTE_SMEMFUN(BoolTest, TernaryOperatorWorksWithTrue)); 233 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorBuiltInOrShortCutWithCast)); 234 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorBuiltInOrShortCutWithCastPass)); 235 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorBuiltInAndShortCutWithCast)); 236 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorBuiltInAndShortCutWithCastPass)); 237 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorOrShortCut)); 238 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorOrShortCutPass)); 239 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorAndShortCut)); 240 | s.push_back(CUTE_SMEMFUN(BoolTest, OperatorAndShortCutPass)); 241 | s.push_back(CUTE_SMEMFUN(BoolTest, ConvertsFromStreamIndirectlyOnly)); 242 | return s; 243 | } 244 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/src/ArraySizeDiffStrong.cpp: -------------------------------------------------------------------------------- 1 | #include "ArraySizeDiffStrong.h" 2 | #include "cute.h" 3 | #include "pssst.h" 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | 16 | namespace vec { 17 | // make a vector adapter with strongly typed ctors for demonstrating to Peter Dimov what I thought about. 18 | //using namespace pssst; 19 | struct Capacity{ size_t value;}; 20 | struct Size{ size_t value;}; 21 | namespace detail__{ 22 | 23 | template 24 | struct HasIteratorTraitImpl{ 25 | template static double e(...); 26 | template static char e(typename std::iterator_traits::iterator_category*); 27 | 28 | static inline constexpr bool value = sizeof(HasIteratorTraitImpl::e(nullptr))==sizeof(char); 29 | }; 30 | 31 | template 32 | constexpr bool HasIteratorTrait = HasIteratorTraitImpl::value; 33 | 34 | static_assert(!HasIteratorTrait); 35 | static_assert(HasIteratorTrait); 36 | 37 | 38 | 39 | template> 40 | constexpr bool isInputIterator = std::is_convertible_v::iterator_category,std::input_iterator_tag>; 41 | template 42 | constexpr bool isInputIterator = false; 43 | 44 | template> 45 | constexpr bool IteratorHasValueType = false; 46 | template 47 | constexpr bool IteratorHasValueType = std::is_constructible_v::value_type>; 48 | 49 | } 50 | 51 | 52 | template> 53 | struct Vec: std::vector{ 54 | using base=std::vector; 55 | using allocator_type = typename base::allocator_type; 56 | using value_type = typename base::value_type; 57 | 58 | Vec() noexcept = default; 59 | explicit Vec(allocator_type const &a) noexcept :base{a}{} 60 | explicit Vec(Size sz,allocator_type const &a=allocator_type{}) 61 | :base{sz.value,a}{} 62 | explicit Vec(Capacity cap,allocator_type const &a=allocator_type{}) 63 | :base{a}{base::reserve(cap.value);} 64 | Vec(Size sz, const value_type& value, 65 | const allocator_type& a = allocator_type()) 66 | :base{sz.value,value,a}{} 67 | template 68 | Vec(_InputIterator first, 69 | std::enable_if_t 70 | && detail__::IteratorHasValueType<_InputIterator,T>,_InputIterator> last, 71 | const allocator_type& a = allocator_type()) 72 | : base{first,last,a}{} 73 | 74 | }; 75 | 76 | template 77 | Vec(Size,T const &) -> Vec; 78 | 79 | template 80 | Vec(_InputIterator first, 81 | std::enable_if_t,_InputIterator> last) -> Vec::value_type>; 82 | 83 | 84 | void demonstrateVecWithCapacity(){ 85 | Vec v{Capacity{100}}; 86 | ASSERT_EQUAL(100u, v.capacity()); 87 | ASSERT_EQUAL(0u, v.size()); 88 | } 89 | 90 | void demonstrateVecWithSize(){ 91 | Vec v{Size{100},42}; 92 | ASSERT_EQUAL(100u, v.size()); 93 | } 94 | 95 | void checkOutputIteratorFailsWithVec(){ 96 | std::ostringstream out; 97 | std::ostream_iterator osi{out}; 98 | // Vec v{osi,osi}; // doesn't compile 99 | } 100 | 101 | void checkInputIteratorSameValueType(){ 102 | std::istringstream in{"1 2 3"}; 103 | std::istream_iterator ins{in},eof{}; 104 | static_assert(std::is_same_v::iterator_category>); 105 | static_assert(std::is_convertible_v::iterator_category,std::input_iterator_tag>); 106 | static_assert(detail__::HasIteratorTrait); 107 | static_assert(detail__::IteratorHasValueType); 108 | static_assert(detail__::isInputIterator>); 109 | Vec v{ins,eof}; 110 | static_assert(std::is_same_v, decltype(v)>); 111 | ASSERT_EQUAL(3u,v.size()); 112 | } 113 | 114 | 115 | } 116 | 117 | 118 | namespace test { 119 | using namespace pssst; 120 | struct Diff: Linear{ 121 | ~Diff()=default; 122 | }; 123 | struct Size: affine_space_for { 124 | constexpr Size() = default; 125 | constexpr Size(size_t val) 126 | :Size{Diff{static_cast(val)}}{} 127 | constexpr Size(Diff val) 128 | :affine_space_for{val}{ 129 | if (val < Diff{0}) 130 | throw std::logic_error{"size is too large"}; 131 | } 132 | }; 133 | 134 | template 135 | struct Pointer: ops,Order, Inc, Dec> { 136 | using value_type=T; 137 | using difference_type=Diff; 138 | using reference=value_type&; 139 | using const_reference= value_type const&; 140 | using pointer=value_type*; 141 | using const_pointer=const value_type*; 142 | constexpr reference operator*() const noexcept { return *a; } 143 | constexpr reference operator[]( difference_type pos ) const noexcept { return a[pos];} 144 | constexpr Pointer& operator+=( difference_type off ) noexcept { a += value(off); return *this; } 145 | constexpr Pointer operator+( difference_type off ) const noexcept { return Pointer{ a + value(off) }; } 146 | friend constexpr Pointer operator+( difference_type off, Pointer p ) noexcept { return Pointer{ p.a + value(off) }; } 147 | constexpr Pointer& operator-=( difference_type off ) noexcept { a -= value(off); return *this; } 148 | constexpr Pointer operator-( difference_type off ) const noexcept { return Pointer{ a - value(off) }; } 149 | 150 | constexpr difference_type operator-(Pointer const &right) const noexcept { return difference_type{a - right.a}; } 151 | 152 | constexpr Pointer() noexcept = default; 153 | explicit constexpr Pointer(T *a) noexcept : a{a}{} 154 | T* a{}; 155 | }; 156 | 157 | } 158 | namespace std{ 159 | template 160 | struct iterator_traits< test::Pointer > { 161 | using Pointer=test::Pointer; 162 | using difference_type=typename Pointer::difference_type; 163 | using value_type=typename Pointer::value_type; 164 | using pointer=Pointer; 165 | using reference=typename Pointer::reference; 166 | using iterator_category=std::random_access_iterator_tag; 167 | }; 168 | } namespace test { 169 | template 170 | struct array{ 171 | T a[N]; 172 | using size_type=Size; 173 | using value_type=T; 174 | using difference_type=Diff; 175 | using reference=value_type&; 176 | using const_reference= value_type const&; 177 | using pointer=Pointer; 178 | using const_pointer=Pointer; 179 | using iterator=pointer; 180 | using const_iterator=const_pointer; 181 | using reverse_iterator=std::reverse_iterator; 182 | using const_reverse_iterator=std::reverse_iterator; 183 | constexpr pointer data() noexcept { return a;} 184 | constexpr const_pointer data() const noexcept { return a;} 185 | constexpr reference at( size_type pos ) { if (pos < size()) return a[value(pos)]; throw std::out_of_range{"array::at"};} 186 | constexpr const_reference at( size_type pos ) const { if (pos < size()) return a[value(value(pos))]; throw std::out_of_range{"array::at"};} 187 | constexpr reference operator[]( size_type pos ) noexcept { return *(begin()+value(pos));} 188 | constexpr const_reference operator[]( size_type pos ) const noexcept { return *(begin()+value(pos)); } 189 | constexpr reference front() noexcept { return *a;} 190 | constexpr const_reference front() const noexcept { return *a;} 191 | constexpr reference back() noexcept { return a[N-1];} 192 | constexpr const_reference back() const noexcept { return a[N-1];} 193 | constexpr iterator begin() noexcept {return iterator{a};} 194 | constexpr const_iterator begin() const noexcept {return const_iterator{a};} 195 | constexpr const_iterator cbegin() const noexcept {return const_iterator{a};} 196 | constexpr iterator end() noexcept {return iterator{a+N};} 197 | constexpr const_iterator end() const noexcept {return const_iterator{a+N};} 198 | constexpr const_iterator cend() const noexcept {return const_iterator{a+N};} 199 | constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(end());} 200 | constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end());} 201 | constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end());} 202 | constexpr reverse_iterator rend() noexcept { return reverse_iterator(begin());} 203 | constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin());} 204 | constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin());} 205 | constexpr bool empty() const noexcept {return N !=0;} 206 | constexpr size_type size() const noexcept { return size_type{N};} 207 | constexpr size_type max_size() const noexcept { return size();} 208 | constexpr void fill( const T& value ) { std::fill(begin(),end(),value);} 209 | constexpr void swap( array& other ) noexcept(std::is_nothrow_swappable::value){ std::swap_ranges(begin(), end(), other.begin());} 210 | }; 211 | template 212 | array(T, U...) -> array; 213 | 214 | } 215 | 216 | using namespace test; 217 | void TooLargeSizeThrows(){ 218 | ASSERT_THROWS(Size{std::numeric_limits::max()}, std::logic_error); 219 | } 220 | void TooLargeSizeMinus1Throws(){ 221 | ASSERT_THROWS(Size{Diff{-1}}, std::logic_error); 222 | } 223 | void TooLargeSizePlus1Throws(){ 224 | ASSERT_THROWS(Size{size_t(std::numeric_limits::max()) +1}, std::logic_error); 225 | } 226 | 227 | void TestRangeForWithArray(){ 228 | array a{1,2,3,4,5}; 229 | int sum{}; 230 | for(auto elt:a){ 231 | sum += elt; 232 | } 233 | ASSERT_EQUAL(15,sum); 234 | } 235 | void TestRangeForWithConstArray(){ 236 | array const a{1,2,3,4,5,6}; 237 | int sum{}; 238 | for(auto elt:a){ 239 | sum += elt; 240 | } 241 | ASSERT_EQUAL(21,sum); 242 | } 243 | 244 | void TestInverseRangeAlgorithmWithArray(){ 245 | array a{1,2,3,4,5}; 246 | // auto pos = std::find(a.rbegin(),a.rend(),2); // STL relies on difference_type being integral... 247 | auto pos = a.rbegin(); 248 | while(pos != a.rend() && *pos != 2) ++pos; 249 | ASSERT_EQUAL(Diff{2},a.rend()-pos); 250 | } 251 | 252 | 253 | 254 | void TestOOBNegativeAccessThrows(){ 255 | array const a{1,2}; 256 | ASSERT_THROWS(a[-1],std::logic_error); // too large 257 | } 258 | void TestOOBLargeAccessThrows(){ 259 | array const a{1,2}; 260 | ASSERT_THROWS(a.at(2),std::out_of_range); // too large 261 | } 262 | 263 | 264 | 265 | 266 | // TODO: should put Size as vector space and Diff as its affine spaces 267 | // this will provide at least the correct typing for substraction 268 | // but current schema will have Size having the same range as Diff 269 | cute::suite make_suite_ArraySizeDiffStrong() { 270 | cute::suite s { }; 271 | s.push_back(CUTE(TooLargeSizeThrows)); 272 | s.push_back(CUTE(TooLargeSizeMinus1Throws)); 273 | s.push_back(CUTE(TooLargeSizePlus1Throws)); 274 | s.push_back(CUTE(TestRangeForWithArray)); 275 | s.push_back(CUTE(TestRangeForWithConstArray)); 276 | s.push_back(CUTE(TestOOBNegativeAccessThrows)); 277 | s.push_back(CUTE(TestOOBLargeAccessThrows)); 278 | s.push_back(CUTE(TestInverseRangeAlgorithmWithArray)); 279 | s.push_back(CUTE(vec::demonstrateVecWithCapacity)); 280 | s.push_back(CUTE(vec::demonstrateVecWithSize)); 281 | s.push_back(CUTE(vec::checkInputIteratorSameValueType)); 282 | return s; 283 | } 284 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_equals.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, Emanuel Graf, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_EQUALS_H_ 27 | #define CUTE_EQUALS_H_ 28 | #include "cute_base.h" 29 | #include "cute_diff_values.h" 30 | #include "cute_determine_traits.h" 31 | #include "cute_determine_version.h" 32 | #include "cute_deprecated.h" 33 | #include "cute_range.h" 34 | #include 35 | #include 36 | #include 37 | #ifdef USE_STD11 38 | #include 39 | #endif 40 | 41 | 42 | namespace cute { 43 | 44 | 45 | namespace cute_do_equals { 46 | // provide some template meta programming tricks to select "correct" comparison for floating point and integer types 47 | template 48 | bool do_equals_floating_with_delta(ExpectedValue const &expected 49 | ,ActualValue const &actual 50 | ,DeltaValue const &delta) { 51 | using std::abs; // allow for user-defined types with abs overload 52 | #pragma GCC diagnostic push 53 | #pragma GCC diagnostic ignored "-Wconversion" 54 | return bool(abs(delta) >= abs(expected-actual)); // Accommodate non-standard boolean type with explicit conversion 55 | #pragma GCC diagnostic pop 56 | } 57 | template 58 | bool do_equals_floating(ExpectedValue const &expected 59 | ,ActualValue const &actual,const impl_place_for_traits::integral_constant&){ 60 | return bool(expected==actual); // normal case for most types uses operator==!, accommodate non bool operator == 61 | } 62 | template 63 | bool do_equals_floating(ExpectedValue const &expected 64 | ,ActualValue const &actual,const impl_place_for_traits::true_type&){ 65 | const ExpectedValue automatic_delta_masking_last_significant_digit=(10*std::numeric_limits::epsilon())*expected; 66 | return do_equals_floating_with_delta(expected,actual,automatic_delta_masking_last_significant_digit); 67 | } 68 | // TMP-overload dispatch for floating points 2 bool params --> 4 overloads 69 | template 70 | bool do_equals(ExpectedValue const &expected 71 | ,ActualValue const &actual 72 | ,const impl_place_for_traits::integral_constant&/*exp_is_integral*/ 73 | ,const impl_place_for_traits::integral_constant&/*act_is_integral*/){ 74 | return do_equals_floating(expected,actual,impl_place_for_traits::is_floating_point()); 75 | } 76 | template 77 | bool do_equals(ExpectedValue const &expected 78 | ,ActualValue const &actual 79 | ,const impl_place_for_traits::false_type&,const impl_place_for_traits::false_type&){ 80 | return do_equals_floating(expected,actual,impl_place_for_traits::is_floating_point()); 81 | } 82 | template 83 | bool do_equals(ExpectedValue const &expected 84 | ,ActualValue const &actual 85 | ,const impl_place_for_traits::integral_constant&/*exp_is_integral*/ 86 | ,const impl_place_for_traits::true_type&){ 87 | return do_equals_floating(expected,actual,impl_place_for_traits::is_floating_point()); 88 | } 89 | template 90 | bool do_equals(ExpectedValue const &expected 91 | ,ActualValue const &actual 92 | ,const impl_place_for_traits::true_type&,const impl_place_for_traits::integral_constant&/*act_is_integral*/){ 93 | return do_equals_floating(expected,actual,impl_place_for_traits::is_floating_point()); 94 | } 95 | #ifdef USE_STD11 96 | template 97 | bool do_equals(std::tuple const &expected 98 | ,std::tuple const &actual,const std::integral_constant&){ 99 | return expected==actual; 100 | } 101 | #endif 102 | // can I get rid of the following complexity by doing a do_equals_integral 103 | // parameterized by is_signed==is_signed or nofBits < nofBits 104 | 105 | 106 | // this is an optimization for avoiding if and sign-extend overhead if both int types are the same as below 107 | template 108 | bool do_equals(IntType const &expected 109 | ,IntType const &actual 110 | ,const impl_place_for_traits::true_type&,const impl_place_for_traits::true_type&){ 111 | return expected==actual; 112 | } 113 | // bool cannot be made signed, therefore we need the following three overloads, also to avoid ambiguity 114 | template 115 | bool do_equals(bool const &expected 116 | ,IntType const &actual 117 | ,const impl_place_for_traits::true_type&,const impl_place_for_traits::true_type&){ 118 | return expected== !(!actual); // warning from VS 119 | } 120 | template 121 | bool do_equals(IntType const &expected 122 | ,bool const &actual 123 | ,const impl_place_for_traits::true_type&,const impl_place_for_traits::true_type&){ 124 | return !(!expected)==actual; // warning from VS 125 | } 126 | // do not forget the inline on a non-template overload! 127 | // this overload is needed to actually avoid ambiguity for comparing bool==bool as a best match 128 | inline bool do_equals(bool const &expected 129 | ,bool const &actual 130 | , const impl_place_for_traits::true_type&,const impl_place_for_traits::true_type&){ 131 | return expected==actual; 132 | } 133 | // overload for char const *, my test case failed because VC++ doesn't use string constant folding like g++/clang 134 | // a feature where we should do string comparison 135 | inline bool do_equals(char const *const &expected 136 | ,char const *const &actual 137 | , const impl_place_for_traits::false_type&,const impl_place_for_traits::false_type&){ 138 | return std::string(expected) == actual; 139 | } 140 | template 141 | size_t nof_bits(IntegralType const &){ 142 | return std::numeric_limits::digits; 143 | } 144 | #if defined(USE_STD11)||defined(USE_TR1) 145 | template 146 | bool do_equals_integral(ExpectedValue const &expected 147 | ,ActualValue const &actual 148 | ,const impl_place_for_traits::true_type&,const impl_place_for_traits::true_type&){ 149 | if (nof_bits(expected) < nof_bits(actual)) 150 | return static_cast(expected) == actual; 151 | else 152 | return expected == static_cast(actual); 153 | return false; 154 | } 155 | template 156 | bool do_equals_integral(ExpectedValue const &expected 157 | ,ActualValue const &actual 158 | ,const impl_place_for_traits::false_type&,const impl_place_for_traits::true_type&){ 159 | //TODO complicated case, one signed one unsigned type. since it is about equality casting to the longer should work? 160 | if (sizeof(ExpectedValue) > sizeof(ActualValue)) 161 | return expected==static_cast(actual); 162 | else 163 | return static_cast(expected) == actual; 164 | } 165 | template 166 | bool do_equals_integral(ExpectedValue const &expected 167 | ,ActualValue const &actual 168 | ,const impl_place_for_traits::true_type&,const impl_place_for_traits::false_type&){ 169 | //TODO 170 | if (sizeof(ExpectedValue) < sizeof(ActualValue)) 171 | return static_cast(expected)== actual; 172 | else 173 | return expected == static_cast(actual); 174 | } 175 | template 176 | bool do_equals_integral(ExpectedValue const &expected 177 | ,ActualValue const &actual 178 | ,const impl_place_for_traits::false_type&,const impl_place_for_traits::false_type&){ 179 | if (nof_bits(expected) < nof_bits(actual)) 180 | return static_cast(expected) == actual; 181 | else 182 | return expected == static_cast(actual); 183 | return false; 184 | } 185 | #endif 186 | // will not work if either type is bool, therefore the overloads above. 187 | template 188 | bool do_equals(ExpectedValue const &expected 189 | ,ActualValue const &actual 190 | ,const impl_place_for_traits::true_type&,const impl_place_for_traits::true_type&){ 191 | #if defined(USE_STD11) || defined(USE_TR1) 192 | return do_equals_integral(expected,actual, 193 | impl_place_for_traits::is_signed() 194 | ,impl_place_for_traits::is_signed()); 195 | #else 196 | //TODO: replace the following code with a dispatcher on signed/unsigned 197 | typedef typename impl_place_for_traits::make_signed::type ex_s; 198 | typedef typename impl_place_for_traits::make_signed::type ac_s; 199 | // need to sign extend with the longer type, should work... 200 | // might be done through more template meta prog tricks....but... 201 | if (nof_bits(expected) < nof_bits(actual)) 202 | return static_cast(expected) == static_cast(actual); 203 | else 204 | return static_cast(expected) == static_cast(actual); 205 | #endif 206 | } 207 | } // namespace equals_impl 208 | template 209 | void assert_equal(ExpectedValue const &expected 210 | ,ActualValue const &actual 211 | ,std::string const &msg 212 | ,char const *file 213 | ,int line) { 214 | // unfortunately there is no is_integral_but_not_bool_or_enum 215 | typedef typename impl_place_for_traits::is_integral exp_integral; 216 | typedef typename impl_place_for_traits::is_integral act_integral; 217 | if (cute_do_equals::do_equals(expected,actual,exp_integral(),act_integral())) 218 | return; 219 | throw test_failure(msg + diff_values(expected,actual),file,line); 220 | } 221 | 222 | template 223 | void assert_equal_delta(ExpectedValue const &expected 224 | ,ActualValue const &actual 225 | ,DeltaValue const &delta 226 | ,std::string const &msg 227 | ,char const *file 228 | ,int line) { 229 | if (cute_do_equals::do_equals_floating_with_delta(expected,actual,delta)) return; 230 | throw test_failure(msg + diff_values(expected,actual),file,line); 231 | } 232 | 233 | } 234 | 235 | #define ASSERT_EQUALM(msg,expected,actual) cute::assert_equal((expected),(actual),\ 236 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg),__FILE__,__LINE__) 237 | #define ASSERT_EQUAL(expected,actual) ASSERT_EQUALM(#expected " == " #actual, (expected),(actual)) 238 | #define ASSERT_EQUAL_DELTAM(msg,expected,actual,delta) cute::assert_equal_delta((expected),(actual),(delta),\ 239 | CUTE_FUNCNAME_PREFIX+cute::cute_to_string::backslashQuoteTabNewline(msg),__FILE__,__LINE__) 240 | #define ASSERT_EQUAL_DELTA(expected,actual,delta) ASSERT_EQUAL_DELTAM(#expected " == " #actual " with error " #delta ,(expected),(actual),(delta)) 241 | 242 | DEPRECATE(ASSERT_EQUAL_RANGES_M, ASSERT_EQUAL_RANGESM) 243 | #define ASSERT_EQUAL_RANGES_M(msg,expbeg,expend,actbeg,actend) DEPRECATED(ASSERT_EQUAL_RANGES_M), ASSERT_EQUALM(msg,cute::make_range(expbeg,expend),cute::make_range(actbeg,actend)) 244 | #define ASSERT_EQUAL_RANGESM(msg,expbeg,expend,actbeg,actend) ASSERT_EQUALM(msg,cute::make_range(expbeg,expend),cute::make_range(actbeg,actend)) 245 | #define ASSERT_EQUAL_RANGES(expbeg,expend,actbeg,actend) ASSERT_EQUAL_RANGESM("range{" #expbeg "," #expend "} == range{" #actbeg "," #actend "}",expbeg,expend,actbeg,actend) 246 | #endif /*CUTE_EQUALS_H_*/ 247 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/cute/cute_to_string.h: -------------------------------------------------------------------------------- 1 | /********************************************************************************* 2 | * This file is part of CUTE. 3 | * 4 | * Copyright (c) 2007-2018 Peter Sommerlad, IFS 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | *********************************************************************************/ 25 | 26 | #ifndef CUTE_TO_STRING_H_ 27 | #define CUTE_TO_STRING_H_ 28 | 29 | #include 30 | #include 31 | #ifdef USE_STD17 32 | #include 33 | #endif 34 | 35 | namespace cute { 36 | namespace cute_to_string { 37 | static inline std::string backslashQuoteTabNewline(std::string const &input){ 38 | std::string result; 39 | result.reserve(input.size()); 40 | for (std::string::size_type i=0; i < input.length() ; ++i){ 41 | switch(input[i]) { 42 | case '\n': result += "\\n"; break; 43 | case '\t': result += "\\t"; break; 44 | case '\\': result += "\\\\"; break; 45 | case '\r': result += "\\r"; break; 46 | default: result += input[i]; 47 | } 48 | } 49 | return result; 50 | } 51 | // common overloads of interface that work without an ostream 52 | static inline std::string to_string(char const *const &s){ 53 | return s; 54 | } 55 | static inline std::string to_string(std::string const &s){ 56 | return s; 57 | } 58 | template 59 | std::string hexit(T const &t){ // must be an unsigned type 60 | std::string hexed; 61 | if (t == 0) hexed+='0'; 62 | for (T x=t;x>0;x /= 16){ 63 | hexed += "0123456789ABCDEF"[x%16]; 64 | } 65 | reverse(hexed.begin(),hexed.end()); 66 | return hexed; 67 | } 68 | } 69 | } 70 | #ifndef DONT_USE_IOSTREAM 71 | #include 72 | #include 73 | #include 74 | #ifdef _MSC_VER 75 | #include 76 | #include 77 | #endif 78 | #include "cute_demangle.h" 79 | #include "cute_determine_version.h" 80 | #ifdef USE_STD11 81 | #include "cute_integer_sequence.h" 82 | #include 83 | #endif 84 | namespace cute { 85 | namespace cute_to_string { 86 | template 87 | std::ostream &to_stream(std::ostream &os,T const &t); // recursion needs forward 88 | #ifdef USE_STD17 89 | inline std::ostream &to_stream(std::ostream &os,std::byte t); // recursion needs forward 90 | #endif 91 | 92 | // the following code was stolen and adapted from Boost Exception library. 93 | // it avoids compile errors, if a type used with ASSERT_EQUALS doesn't provide an output shift operator 94 | namespace to_string_detail { 95 | template 96 | char operator<<( std::basic_ostream &, T const & ); 97 | template 98 | struct is_output_streamable_impl { 99 | static std::basic_ostream & f(); 100 | static T const & g(); 101 | enum e { value = (sizeof(char) != sizeof(f()< 105 | struct is_output_streamable_impl { 106 | static std::basic_ostream & f(); 107 | static T const * g(); 108 | enum e { value = (sizeof(char) != sizeof(f()< 111 | struct has_begin_end_const_member { 112 | template struct type_check; 113 | #ifdef USE_STD17 114 | template static typename C::const_iterator test( 115 | type_check*); 116 | #else 117 | template static typename C::const_iterator test( 118 | type_check*); 119 | #endif 120 | template static char test(...); 121 | enum e { value = (sizeof(char) != sizeof(test(0))) 122 | }; 123 | }; // this doesn't work with VS library for set/map due to implementation in parent 124 | // no useful workaround possible 125 | //-> internal compiler errors for VS2010/12/12CTP Nov 12 126 | } 127 | template > 128 | struct is_output_streamable { 129 | enum e { value=to_string_detail::is_output_streamable_impl::value }; 130 | }; 131 | // detect standard container conforming begin() end() iterator accessors. 132 | // might employ begin/end traits from c++0x for loop in the future. --> select_container 133 | template 134 | struct printItWithDelimiter 135 | { 136 | std::ostream &os; 137 | bool first; // allow use of for_each algorithm 138 | printItWithDelimiter(std::ostream &os):os(os),first(true){} 139 | void operator()(T const &t){ 140 | if (!first) os<<','; 141 | else first=false; 142 | os << '\n'; // use newlines so that CUTE's plug-in result viewer gives nice diffs 143 | cute_to_string::to_stream(os,t); 144 | } 145 | }; 146 | //try print_pair with specialization of template function instead: 147 | // the generic version prints about missing operator<< that is the last resort 148 | template 149 | std::ostream &print_pair(std::ostream &os,T const &){ 150 | return os << "no operator<<(ostream&, " < 154 | std::ostream &print_pair(std::ostream &os,std::pair const &p){ 155 | os << '[' ; 156 | cute_to_string::to_stream(os,p.first); 157 | os << " -> "; 158 | cute_to_string::to_stream(os,p.second); 159 | os << ']'; 160 | return os; 161 | } 162 | // overload for Arrays 163 | template 164 | std::ostream &print_pair(std::ostream &os,T const (&t)[N]){ 165 | printItWithDelimiter printer(os); 166 | os << cute::demangle(typeid(T).name()) <<'['< 173 | using size = std::integral_constant; 174 | struct empty { templateempty(Types const &...){} }; 175 | template 176 | std::ostream &print_tuple(std::ostream &os, std::tuple const &t, size<_> const, index_sequence){ 177 | empty{os << '\n' 178 | ,cute_to_string::to_stream(os, std::get(t)) 179 | ,(os << ",\n", cute_to_string::to_stream(os, std::get(t)))...}; 180 | return os; 181 | } 182 | template 183 | std::ostream &print_tuple(std::ostream &os, std::tuple const &t, size<_> const s) { 184 | return print_tuple(os, t, s, index_sequence_for{}); 185 | } 186 | template 187 | std::ostream &print_tuple(std::ostream &os, std::tuple<_...> const &t, size<1> const){ 188 | return os << '\n', cute_to_string::to_stream(os, std::get<0>(t)); 189 | } 190 | template 191 | std::ostream &print_tuple(std::ostream &os, std::tuple<_...> const &, size<0>){ 192 | return os; 193 | } 194 | // overload for std::tuple<...> 195 | template 196 | std::ostream &print_pair(std::ostream &os, std::tuple const &t){ 197 | os << cute::demangle(typeid(decltype(t)).name()) << '{'; 198 | auto olflags = os.flags(); 199 | os << std::boolalpha; 200 | print_tuple(os, t, size{}); 201 | os.flags(olflags); 202 | os << '}'; 203 | return os; 204 | } 205 | #endif 206 | template 207 | struct select_container { 208 | std::ostream &os; 209 | select_container(std::ostream &os):os(os){} 210 | std::ostream& operator()(T const &t){ 211 | printItWithDelimiter printer(os); 212 | os << cute::demangle(typeid(T).name()) << '{'; 213 | std::for_each(t.begin(),t.end(),printer); 214 | return os << '}'; 215 | } 216 | }; 217 | 218 | template 219 | struct select_container { 220 | std::ostream &os; 221 | select_container(std::ostream &os):os(os){} 222 | std::ostream & operator()(T const &t){ 223 | // look for std::pair. a future with tuple might be useful as well, but not now. 224 | return print_pair(os,t); // here a simple template function overload works. 225 | } 226 | }; 227 | 228 | template 229 | struct select_built_in_shift_if { 230 | std::ostream &os; 231 | select_built_in_shift_if(std::ostream &ros):os(ros){} 232 | std::ostream& operator()(T const &t){ 233 | return os << t ; // default uses operator<<(std::ostream&,T const&) if available 234 | } 235 | }; 236 | 237 | template 238 | struct select_built_in_shift_if { 239 | std::ostream &os; 240 | select_built_in_shift_if(std::ostream &ros):os(ros){} 241 | std::ostream & operator()(T const &t){ 242 | // if no operator<< is found, try if it is a container or std::pair 243 | return select_container::value) >(os)(t); 244 | } 245 | }; 246 | template 247 | std::ostream &to_stream(std::ostream &os,T const &t){ 248 | select_built_in_shift_if::value > out(os); 249 | return out(t); 250 | } 251 | #ifdef USE_STD17 252 | inline std::ostream &to_stream(std::ostream &os,std::byte b){ 253 | return os << "0x" << hexit(static_cast>(b)); 254 | } 255 | #endif 256 | #ifdef _MSC_VER 257 | // special overloads because VC can not detect begin/end 258 | inline std::ostream& to_stream(std::ostream &os,std::string const &s){ 259 | return os< class S, 262 | typename K, typename CMP, typename ALLOC> 263 | std::ostream &to_stream(std::ostream &os,S const &t){ 264 | printItWithDelimiter::value_type> printer(os); 265 | os << cute::demangle(typeid(S).name()) << '{'; 266 | std::for_each(t.begin(),t.end(),printer); 267 | return os << '}'; 268 | } 269 | template class M,typename K, typename V, typename CMP, typename ALLOC> 270 | std::ostream &to_stream(std::ostream &os,M const &t){ 271 | printItWithDelimiter::value_type> printer(os); 272 | os << cute::demangle(typeid(M).name()) << '{'; 273 | std::for_each(t.begin(),t.end(),printer); 274 | return os << '}'; 275 | } 276 | #endif 277 | 278 | // this is the interface: 279 | template 280 | std::string to_string(T const &t) { 281 | std::ostringstream os; 282 | to_stream(os,t); 283 | return os.str(); 284 | } 285 | } 286 | } 287 | #else 288 | #include "cute_determine_traits.h" 289 | #include 290 | // traits 291 | namespace cute{ 292 | namespace cute_to_string { 293 | template 294 | void adjust_long(T const &,std::string &to_adjust){ // assumes T is an integral type 295 | if (sizeof(T) <= sizeof(int)) return; // don't mark int sized integrals with L 296 | if (sizeof(T)>=sizeof(long)) to_adjust+='L'; 297 | if (sizeof(T)> sizeof(long)) to_adjust+='L'; // if there is support for (unsigned) long long 298 | } 299 | template 300 | std::string to_string_embedded_int_signed(T const &t, impl_place_for_traits::true_type ){ 301 | std::string convert; // t is an integral value 302 | T x=t; 303 | bool negative=t<0; 304 | bool minint=false; 305 | if (x == std::numeric_limits::min()){ // can not easily convert it, assuming 2s complement 306 | minint=true; 307 | x++; // add 1, but 1 might be incompatible type, so use ++ 308 | } 309 | if (x < 0) x = static_cast(-x); 310 | if (x == 0) convert += '0'; 311 | while (x > 0) { 312 | convert += "0123456789"[x%10]; 313 | x /= 10; 314 | } 315 | if (minint) ++ convert[0]; // adjust last digit 316 | if (negative) convert += '-'; 317 | reverse(convert.begin(),convert.end()); 318 | cute::cute_to_string::adjust_long(t,convert); 319 | return convert; 320 | } 321 | template 322 | std::string to_string_embedded_int_signed(T const &t, impl_place_for_traits::false_type ){ 323 | // manual hex conversion to avoid ostream dependency for unsigned values 324 | std::string hexed="0x"+cute::cute_to_string::hexit(t); 325 | cute::cute_to_string::adjust_long(t,hexed); 326 | return hexed; 327 | } 328 | template 329 | std::string to_string_embedded_int(T const &t, impl_place_for_traits::true_type ){ 330 | return to_string_embedded_int_signed(t,impl_place_for_traits::is_signed()); 331 | } 332 | template 333 | std::string to_string_embedded_int(T const &, impl_place_for_traits::false_type ){ 334 | return "no to_string"; 335 | } 336 | // convenience for pointers.... useful? 337 | template 338 | std::string to_string(T * const&t) { 339 | std::string result; 340 | if (sizeof(T *) <= sizeof(unsigned long)) 341 | result = cute::cute_to_string::hexit(reinterpret_cast(t)); 342 | else 343 | #if defined(USE_STD11) /* should allow for all compilers supporting ULL*/ 344 | result = cute::cute_to_string::hexit(reinterpret_cast(t)); 345 | #else 346 | return "no to_string"; 347 | #endif 348 | result.insert(0u,sizeof(T*)*2-result.size(),'0'); 349 | result.insert(0,1,'p'); 350 | return result; 351 | } 352 | 353 | // this is the interface: 354 | template 355 | std::string to_string(T const &t) { 356 | return to_string_embedded_int(t, impl_place_for_traits::is_integral()); 357 | } 358 | } 359 | } 360 | #endif 361 | #endif /* CUTE_TO_STRING_H_ */ 362 | -------------------------------------------------------------------------------- /cevelop-workspace/PSsstTests/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | 37 | 47 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 102 | 103 | 104 | 105 | 106 | 114 | 115 | 116 | 117 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | --------------------------------------------------------------------------------