]> Creatis software - bbtk.git/blob - kernel/src/bbtkRTTI.cxx
Initial revision
[bbtk.git] / kernel / src / bbtkRTTI.cxx
1 #include "bbtkRTTI.h"
2 #include "bbtkMessageManager.h"
3
4
5
6 namespace bbtk
7 {
8   // Adapted from https://savannah.cern.ch/support/download.php?file_id=1972
9   
10   // Something to which we can cast the void*s, to allow finding the
11   // dynamic typeid.
12   struct Dummy {
13     virtual ~Dummy() {}
14   };
15   
16
17  void*  run_time_up_or_down_cast( const std::type_info& target_type,
18                                const std::type_info& source_type,
19                                const void*  source_pointer
20                                )
21  {
22    return run_time_up_or_down_cast(target_type,
23                                    source_type,
24                                    const_cast<void*>(source_pointer));
25  }
26
27   void*   run_time_up_or_down_cast( const std::type_info& target_type,
28                                const std::type_info& source_type,
29                                void*  source_pointer
30                                )
31   {
32     bbtkDebugMessage("Data",5,
33                      "run_time_up_or_down_cast : Casting pointer to '" 
34                      << TypeName(typeid(*(Dummy*)source_pointer)) 
35                      << "' from " << TypeName(source_type) 
36                      << " to " << TypeName(target_type) << std::endl);
37
38     void* target_pointer = 0;
39 #if __GNUC__ > 3 ||                                     \
40   (__GNUC__ == 3 && (__GNUC_MINOR__ > 1 ||              \
41                      (__GNUC_MINOR__ == 1 &&            \
42                       __GNUC_PATCHLEVEL__ > 0)))
43     
44     const abi::__class_type_info* targetTI = 
45       (const abi::__class_type_info *)( &(target_type));
46     
47     bbtkDebugMessage("Data",7," * source   = "<<source_pointer<<std::endl);
48
49     void* tmp = source_pointer;
50     if (source_type.__do_upcast(targetTI,&tmp)) 
51       {
52         target_pointer = tmp;
53       }
54     else 
55       {
56         bbtkDebugMessage("Data",7,
57                          " * upcast failed : trying dynamic down cast"
58                          <<std::endl);
59         const abi::__class_type_info* sourceTI = 
60           (const abi::__class_type_info *)( &(source_type));
61         
62         
63         target_pointer = abi::__dynamic_cast(source_pointer, 
64                                              sourceTI, 
65                                              targetTI, 
66                                              -1);   
67       }
68     
69     bbtkDebugMessage("Data",7," * target   = "<<target_pointer<<std::endl);
70     
71 #else
72     bbtkWarning("run_time_up_or_down_cast not impl. on Win : to do");
73     // target_pointer = __RTDynamicCast(source_pointer, 0, source_type, target_type, 0);
74 #endif
75     return target_pointer;
76     
77   }
78
79 }
80