mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-30 20:51:41 +00:00 
			
		
		
		
	 66fb5a29bb
			
		
	
	66fb5a29bb
	
	
	
		
			
			Apply the pre-commit hook whitespace fixes to all files in the repo. (Line endings, blank lines at end of file, trailing whitespace)
		
			
				
	
	
		
			101 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* C++ run-time type info (RTTI) example
 | |
| 
 | |
|    This example code is in the Public Domain (or CC0 licensed, at your option.)
 | |
| 
 | |
|    Unless required by applicable law or agreed to in writing, this
 | |
|    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 | |
|    CONDITIONS OF ANY KIND, either express or implied.
 | |
| */
 | |
| 
 | |
| #include <iostream>
 | |
| #include <memory>
 | |
| #include <vector>
 | |
| #include <algorithm>
 | |
| #include <cxxabi.h>
 | |
| 
 | |
| using std::cout;
 | |
| using std::endl;
 | |
| using std::string;
 | |
| using std::shared_ptr;
 | |
| using std::make_shared;
 | |
| 
 | |
| class Base;
 | |
| class DerivedA;
 | |
| class DerivedB;
 | |
| 
 | |
| static string demangle(const char* name);
 | |
| 
 | |
| class Base
 | |
| {
 | |
| public:
 | |
|     virtual ~Base() {} ;
 | |
|     virtual string name() = 0;
 | |
|     static shared_ptr<Base> make_random_derived();
 | |
| };
 | |
| 
 | |
| class DerivedA : public Base
 | |
| {
 | |
| public:
 | |
|     string name() override { return "DerivedA"; }
 | |
| };
 | |
| 
 | |
| class DerivedB : public Base
 | |
| {
 | |
| public:
 | |
|     string name() override { return "DerivedB"; }
 | |
| };
 | |
| 
 | |
| /* Creates either DerivedA or DerivedB, depending on a random number */
 | |
| shared_ptr<Base> Base::make_random_derived()
 | |
| {
 | |
|     if (std::rand() % 2 == 0) {
 | |
|         return make_shared<DerivedA>();
 | |
|     } else {
 | |
|         return make_shared<DerivedB>();
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* Inside a .cpp file, app_main function must be declared with C linkage */
 | |
| extern "C" void app_main()
 | |
| {
 | |
|     /* Demonstrate typeid().name() */
 | |
|     cout << "Type names of a few objects:" << endl << '\t';
 | |
|     cout << "Type name of std::cout is: " << demangle(typeid(std::cout).name()) << endl << '\t';
 | |
|     cout << "Type name of std::cin is: "  << demangle(typeid(std::cin).name()) << endl << '\t';
 | |
|     cout << "Type of app_main is: " << demangle(typeid(app_main).name()) << endl << '\t';
 | |
|     auto sum = [](int x, int y) -> int { return x + y; };
 | |
|     cout << "Type name of a lambda function is: "  << demangle(typeid(sum).name()) << endl << endl;
 | |
| 
 | |
|     /* Demonstrate dynamic_cast */
 | |
|     std::vector<shared_ptr<Base>> objects(5);
 | |
|     cout << "Generating " << objects.size() << " random objects and printing their types:" << endl;
 | |
|     std::generate(objects.begin(), objects.end(), Base::make_random_derived);
 | |
|     for (auto &obj: objects) {
 | |
|         cout << "obj->name() is: " << obj->name() << endl << '\t';
 | |
|         cout << "typeid(*obj).name() is: " << demangle(typeid(*obj).name()) << endl << '\t';
 | |
| 
 | |
|         const DerivedA* cast_to_derived_a = dynamic_cast<DerivedA*>(obj.get());
 | |
|         const DerivedB* cast_to_derived_b = dynamic_cast<DerivedB*>(obj.get());
 | |
| 
 | |
|         cout << "dynamic_cast<DerivedA*>(obj)=" << static_cast<const void*>(cast_to_derived_a) << endl << '\t';
 | |
|         cout << "dynamic_cast<DerivedB*>(obj)=" << static_cast<const void*>(cast_to_derived_b) << endl << endl;
 | |
|     }
 | |
| 
 | |
|     cout << "Example finished." << endl;
 | |
| }
 | |
| 
 | |
| /* Helper function which converts typeid().name() to a human-readable type name */
 | |
| static std::string demangle(const char* name)
 | |
| {
 | |
|     int status = 0;
 | |
|     char* result = abi::__cxa_demangle(name, NULL, NULL, &status);
 | |
|     string str_result;
 | |
|     if (status == 0) {
 | |
|         str_result = result;
 | |
|     } else {
 | |
|         str_result = name;
 | |
|     }
 | |
|     free(result);
 | |
|     return str_result;
 | |
| }
 |