diff --git a/src/lib/access-casted.hpp b/src/lib/access-casted.hpp index 1880f3709..eff197e4b 100644 --- a/src/lib/access-casted.hpp +++ b/src/lib/access-casted.hpp @@ -54,25 +54,22 @@ namespace util { using std::remove_pointer; using std::remove_reference; + namespace error = lumiera::error; + + template + using PlainType = typename remove_pointer< + typename remove_reference::type>::type; template struct has_RTTI { - using PlainType = typename remove_pointer< - typename remove_reference::type>::type; - - static constexpr bool value = std::is_polymorphic::value; + static constexpr bool value = std::is_polymorphic>::value; }; template struct can_downcast { - using PlainSRC = typename remove_pointer< - typename remove_reference::type>::type; - using PlainTAR = typename remove_pointer< - typename remove_reference::type>::type; - - static constexpr bool value = std::is_base_of::value; + static constexpr bool value = std::is_base_of, PlainType>::value; }; template @@ -88,6 +85,20 @@ namespace util { : std::is_convertible { }; + template + struct can_take_address + { + static constexpr bool value = !std::is_pointer::type>::value + && std::is_pointer::type>::value; + }; + + template + struct can_dereference + { + static constexpr bool value = !std::is_pointer::type>::value + && std::is_pointer::type>::value; + }; + template struct if_can_use_dynamic_downcast @@ -98,6 +109,16 @@ namespace util { struct if_can_use_conversion : std::enable_if< can_use_conversion::value, TAR> { }; + + template + struct if_can_take_address + : std::enable_if< can_take_address::value, TAR> + { }; + + template + struct if_can_dereference + : std::enable_if< can_dereference::value, TAR> + { }; @@ -121,6 +142,26 @@ namespace util { std::cerr << "convert-"<()<<" && ->"<()< (elem); } + + template + static typename if_can_take_address::type + access (SRC&& elem) + { + std::cerr << "address-"<()<<" && ->"<()<::access (&elem); + } + + template + static typename if_can_dereference::type + access (SRC&& elem) + { + std::cerr << "deref-"<()<<" && ->"<()<::access (*elem); + } }; diff --git a/tests/library/meta/access-casted-test.cpp b/tests/library/meta/access-casted-test.cpp index d1b4be725..931c52706 100644 --- a/tests/library/meta/access-casted-test.cpp +++ b/tests/library/meta/access-casted-test.cpp @@ -34,6 +34,9 @@ using std::move; using std::string; using std::ostream; using std::cout; +using std::endl; + +using lumiera::error::LUMIERA_ERROR_BOTTOM_VALUE; namespace util { @@ -94,61 +97,77 @@ namespace test { E* pE = &f; D* pDE = pE; - cout << "can_downcast = " << can_downcast::value << "\n"; - cout << "can_downcast = " << can_downcast::value << "\n"; - cout << "can_downcast = " << can_downcast::value << "\n"; - cout << "can_downcast = " << can_downcast::value << "\n"; - cout << "can_downcast = " << can_downcast::value << "\n"; - cout << "can_downcast = " << can_downcast::value << "\n"; - cout << "can_downcast = " << can_downcast::value << "\n"; + cout << "can_downcast = " << can_downcast::value < = " << can_downcast::value < = " << can_downcast::value < = " << can_downcast::value < = " << can_downcast::value < = " << can_downcast::value < = " << can_downcast::value < = " << can_downcast::value << "\n"; - cout << "can_downcast = " << can_downcast::value << "\n"; + cout << "can_downcast = " << can_downcast::value < = " << can_downcast::value < = " << has_RTTI::value << "\n"; - cout << "has_RTTI = " << has_RTTI::value << "\n"; - cout << "has_RTTI = " << has_RTTI::value << "\n"; + cout << "has_RTTI = " << has_RTTI::value < = " << has_RTTI::value < = " << has_RTTI::value < = " << std::is_convertible::value << "\n"; - cout << "is_convertible = " << std::is_convertible::value << "\n"; + cout << "is_convertible = " << std::is_convertible::value < = " << std::is_convertible::value < = " << can_use_dynamic_downcast::value << "\n"; - cout << "can_use_conversion = " << can_use_conversion::value << "\n"; - cout << "can_use_dynamic_downcast = " << can_use_dynamic_downcast::value << "\n"; - cout << "can_use_conversion = " << can_use_conversion::value << "\n"; + cout << "can_use_dynamic_downcast = " << can_use_dynamic_downcast::value < = " << can_use_conversion::value < = " << can_use_dynamic_downcast::value < = " << can_use_conversion::value < = " << can_use_dynamic_downcast::value << "\n"; - cout << "can_use_conversion = " << can_use_conversion::value << "\n"; - cout << "can_use_conversion = " << can_use_conversion::value << "\n"; - cout << "can_use_dynamic_downcast = " << can_use_dynamic_downcast::value << "\n"; + cout << "can_use_dynamic_downcast = " << can_use_dynamic_downcast::value < = " << can_use_conversion::value < = " << can_use_conversion::value < = " << can_use_dynamic_downcast::value <" << AccessCasted::access(d) <" << AccessCasted::access(rD) <" << AccessCasted::access(d) << "\n"; - cout << "Access(D& as D&) --->" << AccessCasted::access(rD) << "\n"; - cout << "Access(D as D) --->" << AccessCasted::access(d) << "\n"; - cout << "Access(D& as D) --->" << AccessCasted::access(rD) << "\n"; + cout << "=== build a value object ==="<" << AccessCasted::access(d) <" << AccessCasted::access(rD) <" << AccessCasted::access(move(dd1)) << "\n"; -// cout << "Access(B& as D&) --->" << AccessCasted::access(rB) << "\n"; -// cout << "Access(D* as D*) --->" << AccessCasted::access(pD) << "\n"; -// cout << "Access(B* as D*) --->" << AccessCasted::access(pB) << "\n"; -// cout << "Access(D*& as D*&) --->" << AccessCasted::access(rpD) << "\n"; -// cout << "Access(B*& as D*&) --->" << AccessCasted::access(rpB) << "\n"; + cout << "Access(D&& as D) --->" << AccessCasted::access(move(dd1)) <" << AccessCasted::access(d) <" << AccessCasted::access(rD) <" << AccessCasted::access(pD) <" << AccessCasted::access(pD) <" << AccessCasted::access(move(pdd1)) <::access(pNull)); + + cout << "=== work cases: actual conversions ==="<" << AccessCasted::access(rB) <" << AccessCasted::access(pD) <" << AccessCasted::access(pB) <" << AccessCasted::access(rpD) <" << AccessCasted::access(rpB) <" << AccessCasted::access(d) << "\n"; -// cout << "Access(D& as B&) --->" << AccessCasted::access(rD) << "\n"; -// cout << "Access(B& as B&) --->" << AccessCasted::access(rB) << "\n"; -// cout << "Access(D* as B*) --->" << AccessCasted::access(pD) << "\n"; -// cout << "Access(B* as B*) --->" << AccessCasted::access(pB) << "\n"; -// cout << "Access(D*& as B*&) --->" << AccessCasted::access(rpD) << "\n"; -// cout << "Access(B*& as B*&) --->" << AccessCasted::access(rpB) << "\n"; +// cout << "Access(D as B&) --->" << AccessCasted::access(d) <" << AccessCasted::access(rD) <" << AccessCasted::access(rB) <" << AccessCasted::access(pD) <" << AccessCasted::access(pB) <" << AccessCasted::access(rpD) <" << AccessCasted::access(rpB) <" << AccessCasted::access(d) << "\n"; -// cout << "Access(E& as F&) --->" << AccessCasted::access(rE) << "\n"; -// cout << "Access(D(E)* as E*) --->" << AccessCasted::access(pDE) << "\n"; -// cout << "Access(D(E)* as F*) --->" << AccessCasted::access(pDE) << "\n"; -// cout << "Access(E* as F*) --->" << AccessCasted::access(pE) << "\n"; +// cout << "Access(D as E&) --->" << AccessCasted::access(d) <" << AccessCasted::access(rE) <" << AccessCasted::access(pDE) <" << AccessCasted::access(pDE) <" << AccessCasted::access(pE) <