cppbind: Refactor to use C++11+ type_traits
This commit is contained in:
parent
9078a085c3
commit
af5833cbc5
@ -492,13 +492,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS_C} ${MSVC_FLAGS}")
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
|
||||||
|
|
||||||
check_cxx_source_compiles("
|
include(CheckCXXFeatures)
|
||||||
#include <utility>
|
|
||||||
#include <type_traits>
|
|
||||||
std::make_index_sequence<0> t;
|
|
||||||
int main() { return 0; }"
|
|
||||||
HAVE_STD_INDEX_SEQUENCE
|
|
||||||
)
|
|
||||||
|
|
||||||
# use BEFORE to ensure local directories are used first,
|
# use BEFORE to ensure local directories are used first,
|
||||||
# ahead of system-installed libs
|
# ahead of system-installed libs
|
||||||
|
30
CMakeModules/CheckCXXFeatures.cmake
Normal file
30
CMakeModules/CheckCXXFeatures.cmake
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <utility>
|
||||||
|
#include <type_traits>
|
||||||
|
std::make_index_sequence<0> t;
|
||||||
|
int main() {}" HAVE_STD_INDEX_SEQUENCE
|
||||||
|
)
|
||||||
|
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <type_traits>
|
||||||
|
std::remove_cv_t<const int> t;
|
||||||
|
int main() {}" HAVE_STD_REMOVE_CV_T
|
||||||
|
)
|
||||||
|
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <type_traits>
|
||||||
|
std::remove_cvref_t<const int&> t;
|
||||||
|
int main() {}" HAVE_STD_REMOVE_CVREF_T
|
||||||
|
)
|
||||||
|
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <type_traits>
|
||||||
|
std::enable_if_t<true, int> t;
|
||||||
|
int main() {}" HAVE_STD_ENABLE_IF_T
|
||||||
|
)
|
||||||
|
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <type_traits>
|
||||||
|
std::bool_constant<true> t;
|
||||||
|
int main() {}" HAVE_STD_BOOL_CONSTANT
|
||||||
|
)
|
@ -15,6 +15,7 @@ foreach( mylibfolder
|
|||||||
nasal/cppbind
|
nasal/cppbind
|
||||||
props
|
props
|
||||||
serial
|
serial
|
||||||
|
std
|
||||||
structure
|
structure
|
||||||
threads
|
threads
|
||||||
timing
|
timing
|
||||||
|
@ -9,7 +9,6 @@ set(HEADERS
|
|||||||
SVGpreserveAspectRatio.hxx
|
SVGpreserveAspectRatio.hxx
|
||||||
argparse.hxx
|
argparse.hxx
|
||||||
interpolator.hxx
|
interpolator.hxx
|
||||||
integer_sequence.hxx
|
|
||||||
make_new.hxx
|
make_new.hxx
|
||||||
sg_dir.hxx
|
sg_dir.hxx
|
||||||
sg_hash.hxx
|
sg_hash.hxx
|
||||||
@ -57,10 +56,6 @@ add_executable(test_CSSBorder CSSBorder_test.cxx)
|
|||||||
add_test(CSSBorder ${EXECUTABLE_OUTPUT_PATH}/test_CSSBorder)
|
add_test(CSSBorder ${EXECUTABLE_OUTPUT_PATH}/test_CSSBorder)
|
||||||
target_link_libraries(test_CSSBorder ${TEST_LIBS})
|
target_link_libraries(test_CSSBorder ${TEST_LIBS})
|
||||||
|
|
||||||
add_executable(test_integer_sequence integer_sequence_test.cxx)
|
|
||||||
add_test(integer_sequence ${EXECUTABLE_OUTPUT_PATH}/test_integer_sequence)
|
|
||||||
target_link_libraries(test_integer_sequence ${TEST_LIBS})
|
|
||||||
|
|
||||||
add_executable(test_tabbed_values tabbed_values_test.cxx)
|
add_executable(test_tabbed_values tabbed_values_test.cxx)
|
||||||
add_test(tabbed_values ${EXECUTABLE_OUTPUT_PATH}/test_tabbed_values)
|
add_test(tabbed_values ${EXECUTABLE_OUTPUT_PATH}/test_tabbed_values)
|
||||||
target_link_libraries(test_tabbed_values ${TEST_LIBS})
|
target_link_libraries(test_tabbed_values ${TEST_LIBS})
|
||||||
|
@ -24,17 +24,16 @@
|
|||||||
#include "NasalObjectHolder.hxx"
|
#include "NasalObjectHolder.hxx"
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/misc/integer_sequence.hxx>
|
#include <simgear/std/integer_sequence.hxx>
|
||||||
|
#include <simgear/std/type_traits.hxx>
|
||||||
#include <simgear/structure/SGWeakReferenced.hxx>
|
#include <simgear/structure/SGWeakReferenced.hxx>
|
||||||
#include <simgear/structure/SGWeakPtr.hxx>
|
#include <simgear/structure/SGWeakPtr.hxx>
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/call_traits.hpp>
|
#include <boost/call_traits.hpp>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/lambda/lambda.hpp>
|
|
||||||
#include <boost/mpl/has_xxx.hpp>
|
#include <boost/mpl/has_xxx.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/utility/enable_if.hpp>
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@ -62,10 +61,7 @@ namespace osg
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline typename boost::enable_if<
|
inline std::enable_if_t<std::is_pointer<T>::value, T>
|
||||||
boost::is_pointer<T>,
|
|
||||||
T
|
|
||||||
>::type
|
|
||||||
get_pointer(T ptr)
|
get_pointer(T ptr)
|
||||||
{
|
{
|
||||||
return ptr;
|
return ptr;
|
||||||
@ -101,8 +97,8 @@ namespace nasal
|
|||||||
class GhostMetadata
|
class GhostMetadata
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef void(*Deleter)(void*);
|
using Deleter = void(*)(void*);
|
||||||
typedef std::vector<std::pair<Deleter, void*> > DestroyList;
|
using DestroyList = std::vector<std::pair<Deleter, void*>>;
|
||||||
|
|
||||||
static DestroyList _destroy_list;
|
static DestroyList _destroy_list;
|
||||||
|
|
||||||
@ -154,19 +150,6 @@ namespace nasal
|
|||||||
};
|
};
|
||||||
|
|
||||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type)
|
BOOST_MPL_HAS_XXX_TRAIT_DEF(element_type)
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct reduced_type
|
|
||||||
{
|
|
||||||
typedef typename boost::remove_cv<
|
|
||||||
typename boost::remove_reference<T>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T1, class T2>
|
|
||||||
struct reduced_is_same:
|
|
||||||
public boost::is_same<typename reduced_type<T1>::type, T2>
|
|
||||||
{};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Destroy all ghost queued for deletion.
|
/** @brief Destroy all ghost queued for deletion.
|
||||||
@ -178,8 +161,8 @@ namespace nasal
|
|||||||
*/
|
*/
|
||||||
void ghostProcessDestroyList();
|
void ghostProcessDestroyList();
|
||||||
|
|
||||||
typedef SGSharedPtr<internal::MethodHolder> MethodHolderPtr;
|
using MethodHolderPtr = SGSharedPtr<internal::MethodHolder>;
|
||||||
typedef SGWeakPtr<internal::MethodHolder> MethodHolderWeakPtr;
|
using MethodHolderWeakPtr = SGWeakPtr<internal::MethodHolder>;
|
||||||
|
|
||||||
// Dummy template to create shorter and easy to understand compile errors if
|
// Dummy template to create shorter and easy to understand compile errors if
|
||||||
// trying to wrap the wrong type as a Ghost.
|
// trying to wrap the wrong type as a Ghost.
|
||||||
@ -187,9 +170,10 @@ namespace nasal
|
|||||||
class Ghost
|
class Ghost
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BOOST_STATIC_ASSERT(("Ghost can only wrap shared pointer!"
|
static_assert(
|
||||||
&& is_strong_ref<T>::value
|
is_strong_ref<T>::value,
|
||||||
));
|
"Ghost can only wrap shared pointer!"
|
||||||
|
);
|
||||||
|
|
||||||
static Ghost& init(const std::string& name);
|
static Ghost& init(const std::string& name);
|
||||||
static bool isInit();
|
static bool isInit();
|
||||||
@ -209,7 +193,7 @@ namespace nasal
|
|||||||
* int myMember();
|
* int myMember();
|
||||||
* void doSomethingElse(const nasal::CallContext& ctx);
|
* void doSomethingElse(const nasal::CallContext& ctx);
|
||||||
* }
|
* }
|
||||||
* typedef boost::shared_ptr<MyClass> MyClassPtr;
|
* using MyClassPtr = boost::shared_ptr<MyClass>;
|
||||||
*
|
*
|
||||||
* std::string myOtherFreeMember(int num);
|
* std::string myOtherFreeMember(int num);
|
||||||
*
|
*
|
||||||
@ -235,29 +219,22 @@ namespace nasal
|
|||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
class Ghost<T, typename boost::enable_if<is_strong_ref<T> >::type>:
|
class Ghost<T, std::enable_if_t<is_strong_ref<T>::value>>:
|
||||||
public internal::GhostMetadata
|
public internal::GhostMetadata
|
||||||
{
|
{
|
||||||
// Shared pointer required for Ghost (no weak pointer!)
|
|
||||||
BOOST_STATIC_ASSERT((is_strong_ref<T>::value));
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename T::element_type raw_type;
|
using raw_type = typename T::element_type;
|
||||||
typedef typename shared_ptr_traits<T>::strong_ref strong_ref;
|
using strong_ref = typename shared_ptr_traits<T>::strong_ref;
|
||||||
typedef typename shared_ptr_traits<T>::weak_ref weak_ref;
|
using weak_ref = typename shared_ptr_traits<T>::weak_ref;
|
||||||
typedef naRef (raw_type::*member_func_t)(const CallContext&);
|
using member_func_t = naRef (raw_type::*)(const CallContext&);
|
||||||
typedef naRef (*free_func_t)(raw_type&, const CallContext&);
|
using free_func_t = naRef (*)(raw_type&, const CallContext&);
|
||||||
typedef boost::function<naRef(raw_type&, naContext)> getter_t;
|
using getter_t = boost::function<naRef(raw_type&, naContext)>;
|
||||||
typedef boost::function<void( raw_type&, naContext, naRef)> setter_t;
|
using setter_t = boost::function<void( raw_type&, naContext, naRef)>;
|
||||||
typedef boost::function<naRef(raw_type&, const CallContext&)> method_t;
|
using method_t = boost::function<naRef(raw_type&, const CallContext&)>;
|
||||||
typedef boost::function<bool( raw_type&,
|
using fallback_getter_t =
|
||||||
naContext,
|
boost::function<bool(raw_type&, naContext, const std::string&, naRef&)>;
|
||||||
const std::string&,
|
using fallback_setter_t =
|
||||||
naRef& )> fallback_getter_t;
|
boost::function<bool(raw_type&, naContext, const std::string&, naRef)>;
|
||||||
typedef boost::function<bool( raw_type&,
|
|
||||||
naContext,
|
|
||||||
const std::string&,
|
|
||||||
naRef )> fallback_setter_t;
|
|
||||||
|
|
||||||
template<class Ret, class... Args>
|
template<class Ret, class... Args>
|
||||||
using method_variadic_t = boost::function<Ret (raw_type&, Args...)>;
|
using method_variadic_t = boost::function<Ret (raw_type&, Args...)>;
|
||||||
@ -272,8 +249,8 @@ namespace nasal
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
typedef SGSharedPtr<MethodHolder> SharedPtr;
|
using SharedPtr = SGSharedPtr<MethodHolder>;
|
||||||
typedef SGWeakPtr<MethodHolder> WeakPtr;
|
using WeakPtr = SGWeakPtr<MethodHolder>;
|
||||||
|
|
||||||
method_t _method;
|
method_t _method;
|
||||||
|
|
||||||
@ -372,7 +349,7 @@ namespace nasal
|
|||||||
MethodHolderPtr func;
|
MethodHolderPtr func;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::string, member_t> MemberMap;
|
using MemberMap = std::map<std::string, member_t>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a new ghost type.
|
* Register a new ghost type.
|
||||||
@ -409,19 +386,18 @@ namespace nasal
|
|||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template<class BaseGhost>
|
template<class BaseGhost>
|
||||||
typename boost::enable_if
|
std::enable_if_t<
|
||||||
<
|
std::is_base_of<GhostMetadata, BaseGhost>::value,
|
||||||
boost::is_base_of<GhostMetadata, BaseGhost>,
|
Ghost&
|
||||||
Ghost
|
>
|
||||||
>::type&
|
|
||||||
bases()
|
bases()
|
||||||
{
|
{
|
||||||
BOOST_STATIC_ASSERT
|
static_assert(
|
||||||
((
|
std::is_base_of<typename BaseGhost::raw_type, raw_type>::value,
|
||||||
boost::is_base_of<typename BaseGhost::raw_type, raw_type>::value
|
"Not a base class!"
|
||||||
));
|
);
|
||||||
|
|
||||||
typedef typename BaseGhost::strong_ref base_ref;
|
using base_ref = typename BaseGhost::strong_ref;
|
||||||
|
|
||||||
BaseGhost* base = BaseGhost::getSingletonPtr();
|
BaseGhost* base = BaseGhost::getSingletonPtr();
|
||||||
base->addDerived(
|
base->addDerived(
|
||||||
@ -467,17 +443,16 @@ namespace nasal
|
|||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
template<class Base>
|
template<class Base>
|
||||||
typename boost::disable_if
|
std::enable_if_t<
|
||||||
<
|
!std::is_base_of<GhostMetadata, Base>::value,
|
||||||
boost::is_base_of<GhostMetadata, Base>,
|
Ghost&
|
||||||
Ghost
|
>
|
||||||
>::type&
|
|
||||||
bases()
|
bases()
|
||||||
{
|
{
|
||||||
BOOST_STATIC_ASSERT
|
static_assert(
|
||||||
((
|
std::is_base_of<typename Ghost<Base>::raw_type, raw_type>::value,
|
||||||
boost::is_base_of<typename Ghost<Base>::raw_type, raw_type>::value
|
"Not a base class!"
|
||||||
));
|
);
|
||||||
|
|
||||||
return bases< Ghost<Base> >();
|
return bases< Ghost<Base> >();
|
||||||
}
|
}
|
||||||
@ -853,10 +828,10 @@ namespace nasal
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
static_assert(
|
static_assert(
|
||||||
boost::is_convertible<raw_type&, Type>::value,
|
std::is_convertible<raw_type&, Type>::value,
|
||||||
//|| boost::is_convertible<raw_type*, Type>::value
|
//|| std::is_convertible<raw_type*, Type>::value
|
||||||
// TODO check how to do it with pointer...
|
// TODO check how to do it with pointer...
|
||||||
"First parameter can not be converted from the Ghost raw_type"
|
"First parameter can not be converted from the Ghost raw_type!"
|
||||||
);
|
);
|
||||||
|
|
||||||
return method(name, method_variadic_t<Ret, Args...>(fn));
|
return method(name, method_variadic_t<Ret, Args...>(fn));
|
||||||
@ -868,11 +843,11 @@ namespace nasal
|
|||||||
*/
|
*/
|
||||||
template<class RefType>
|
template<class RefType>
|
||||||
static
|
static
|
||||||
typename boost::enable_if_c<
|
std::enable_if_t<
|
||||||
boost::is_same<RefType, strong_ref>::value
|
std::is_same<RefType, strong_ref>::value
|
||||||
|| boost::is_same<RefType, weak_ref>::value,
|
|| std::is_same<RefType, weak_ref>::value,
|
||||||
naRef
|
naRef
|
||||||
>::type
|
>
|
||||||
makeGhost(naContext c, RefType const& ref_ptr)
|
makeGhost(naContext c, RefType const& ref_ptr)
|
||||||
{
|
{
|
||||||
strong_ref ref(ref_ptr);
|
strong_ref ref(ref_ptr);
|
||||||
@ -927,13 +902,10 @@ namespace nasal
|
|||||||
if( !naIsVector(na_parents) )
|
if( !naIsVector(na_parents) )
|
||||||
return strong_ref();
|
return strong_ref();
|
||||||
|
|
||||||
typedef std::vector<naRef> naRefs;
|
auto parents = from_nasal<std::vector<naRef>>(c, na_parents);
|
||||||
naRefs parents = from_nasal<naRefs>(c, na_parents);
|
for(auto parent: parents)
|
||||||
for( naRefs::const_iterator parent = parents.begin();
|
|
||||||
parent != parents.end();
|
|
||||||
++parent )
|
|
||||||
{
|
{
|
||||||
strong_ref ref = fromNasal(c, *parent);
|
strong_ref ref = fromNasal(c, parent);
|
||||||
if( get_pointer(ref) )
|
if( get_pointer(ref) )
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
@ -985,8 +957,9 @@ namespace nasal
|
|||||||
static naGhostType _ghost_type_strong, //!< Stored as shared pointer
|
static naGhostType _ghost_type_strong, //!< Stored as shared pointer
|
||||||
_ghost_type_weak; //!< Stored as weak shared pointer
|
_ghost_type_weak; //!< Stored as weak shared pointer
|
||||||
|
|
||||||
typedef naRef (*to_nasal_t)(naContext, const strong_ref&, bool);
|
using to_nasal_t = naRef (*)(naContext, const strong_ref&, bool);
|
||||||
typedef strong_ref (*from_nasal_t)(naContext, naRef);
|
using from_nasal_t = strong_ref (*)(naContext, naRef);
|
||||||
|
|
||||||
struct DerivedInfo
|
struct DerivedInfo
|
||||||
{
|
{
|
||||||
to_nasal_t to_nasal;
|
to_nasal_t to_nasal;
|
||||||
@ -999,7 +972,7 @@ namespace nasal
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<DerivedInfo> DerivedList;
|
using DerivedList = std::vector<DerivedInfo>;
|
||||||
DerivedList _derived_types;
|
DerivedList _derived_types;
|
||||||
|
|
||||||
static bool isInstance(naGhostType* ghost_type, bool& is_weak)
|
static bool isInstance(naGhostType* ghost_type, bool& is_weak)
|
||||||
@ -1013,13 +986,10 @@ namespace nasal
|
|||||||
|
|
||||||
template<class RefPtr, bool is_weak>
|
template<class RefPtr, bool is_weak>
|
||||||
static
|
static
|
||||||
typename boost::enable_if_c<
|
std::enable_if_t<!is_weak, RefPtr>
|
||||||
!is_weak,
|
|
||||||
RefPtr
|
|
||||||
>::type
|
|
||||||
getPtr(void* ptr)
|
getPtr(void* ptr)
|
||||||
{
|
{
|
||||||
typedef shared_ptr_storage<strong_ref> storage_type;
|
using storage_type = shared_ptr_storage<strong_ref>;
|
||||||
if( ptr )
|
if( ptr )
|
||||||
return storage_type::template get<RefPtr>(
|
return storage_type::template get<RefPtr>(
|
||||||
static_cast<typename storage_type::storage_type*>(ptr)
|
static_cast<typename storage_type::storage_type*>(ptr)
|
||||||
@ -1030,13 +1000,13 @@ namespace nasal
|
|||||||
|
|
||||||
template<class RefPtr, bool is_weak>
|
template<class RefPtr, bool is_weak>
|
||||||
static
|
static
|
||||||
typename boost::enable_if_c<
|
std::enable_if_t<
|
||||||
is_weak && supports_weak_ref<T>::value,
|
is_weak && supports_weak_ref<T>::value,
|
||||||
RefPtr
|
RefPtr
|
||||||
>::type
|
>
|
||||||
getPtr(void* ptr)
|
getPtr(void* ptr)
|
||||||
{
|
{
|
||||||
typedef shared_ptr_storage<weak_ref> storage_type;
|
using storage_type = shared_ptr_storage<weak_ref>;
|
||||||
if( ptr )
|
if( ptr )
|
||||||
return storage_type::template get<RefPtr>(
|
return storage_type::template get<RefPtr>(
|
||||||
static_cast<typename storage_type::storage_type*>(ptr)
|
static_cast<typename storage_type::storage_type*>(ptr)
|
||||||
@ -1047,10 +1017,10 @@ namespace nasal
|
|||||||
|
|
||||||
template<class RefPtr, bool is_weak>
|
template<class RefPtr, bool is_weak>
|
||||||
static
|
static
|
||||||
typename boost::enable_if_c<
|
std::enable_if_t<
|
||||||
is_weak && !supports_weak_ref<T>::value,
|
is_weak && !supports_weak_ref<T>::value,
|
||||||
RefPtr
|
RefPtr
|
||||||
>::type
|
>
|
||||||
getPtr(void* ptr)
|
getPtr(void* ptr)
|
||||||
{
|
{
|
||||||
return RefPtr();
|
return RefPtr();
|
||||||
@ -1066,10 +1036,10 @@ namespace nasal
|
|||||||
|
|
||||||
template<class BaseGhost>
|
template<class BaseGhost>
|
||||||
static
|
static
|
||||||
typename boost::enable_if
|
std::enable_if_t<
|
||||||
< boost::is_polymorphic<typename BaseGhost::raw_type>,
|
std::is_polymorphic<typename BaseGhost::raw_type>::value,
|
||||||
naRef
|
naRef
|
||||||
>::type
|
>
|
||||||
toNasal( naContext c,
|
toNasal( naContext c,
|
||||||
const typename BaseGhost::strong_ref& base_ref,
|
const typename BaseGhost::strong_ref& base_ref,
|
||||||
bool strong )
|
bool strong )
|
||||||
@ -1078,10 +1048,10 @@ namespace nasal
|
|||||||
|
|
||||||
// Check first if passed pointer can by converted to instance of class
|
// Check first if passed pointer can by converted to instance of class
|
||||||
// this ghost wraps.
|
// this ghost wraps.
|
||||||
if( !boost::is_same
|
if( !std::is_same<
|
||||||
< typename BaseGhost::raw_type,
|
typename BaseGhost::raw_type,
|
||||||
typename Ghost::raw_type
|
typename Ghost::raw_type
|
||||||
>::value
|
>::value
|
||||||
&& dynamic_cast<const typename Ghost::raw_type*>(ptr) != ptr )
|
&& dynamic_cast<const typename Ghost::raw_type*>(ptr) != ptr )
|
||||||
return naNil();
|
return naNil();
|
||||||
|
|
||||||
@ -1120,13 +1090,13 @@ namespace nasal
|
|||||||
|
|
||||||
template<class BaseGhost>
|
template<class BaseGhost>
|
||||||
static
|
static
|
||||||
typename boost::disable_if
|
std::enable_if_t<
|
||||||
< boost::is_polymorphic<typename BaseGhost::raw_type>,
|
!std::is_polymorphic<typename BaseGhost::raw_type>::value,
|
||||||
naRef
|
naRef
|
||||||
>::type
|
>
|
||||||
toNasal( naContext c,
|
toNasal( naContext c,
|
||||||
const typename BaseGhost::strong_ref& ref,
|
const typename BaseGhost::strong_ref& ref,
|
||||||
bool strong )
|
bool strong )
|
||||||
{
|
{
|
||||||
// For non polymorphic classes there is no possibility to get the actual
|
// For non polymorphic classes there is no possibility to get the actual
|
||||||
// dynamic type, therefore we can only use its static type.
|
// dynamic type, therefore we can only use its static type.
|
||||||
@ -1149,7 +1119,7 @@ namespace nasal
|
|||||||
template<class Ret>
|
template<class Ret>
|
||||||
getter_t to_getter(Ret (raw_type::*getter)() const)
|
getter_t to_getter(Ret (raw_type::*getter)() const)
|
||||||
{
|
{
|
||||||
typedef typename boost::call_traits<Ret>::param_type param_type;
|
using param_type = typename boost::call_traits<Ret>::param_type;
|
||||||
naRef(*to_nasal_)(naContext, param_type) = &to_nasal;
|
naRef(*to_nasal_)(naContext, param_type) = &to_nasal;
|
||||||
|
|
||||||
// Getter signature: naRef(raw_type&, naContext)
|
// Getter signature: naRef(raw_type&, naContext)
|
||||||
@ -1202,7 +1172,7 @@ namespace nasal
|
|||||||
*/
|
*/
|
||||||
template<class Ret>
|
template<class Ret>
|
||||||
static
|
static
|
||||||
typename boost::disable_if<boost::is_void<Ret>, naRef>::type
|
std::enable_if_t<!std::is_void<Ret>::value, naRef>
|
||||||
method_invoker
|
method_invoker
|
||||||
(
|
(
|
||||||
const boost::function<Ret (raw_type&, const CallContext&)>& func,
|
const boost::function<Ret (raw_type&, const CallContext&)>& func,
|
||||||
@ -1218,7 +1188,7 @@ namespace nasal
|
|||||||
*/
|
*/
|
||||||
template<class Ret>
|
template<class Ret>
|
||||||
static
|
static
|
||||||
typename boost::enable_if<boost::is_void<Ret>, naRef>::type
|
std::enable_if_t<std::is_void<Ret>::value, naRef>
|
||||||
method_invoker
|
method_invoker
|
||||||
(
|
(
|
||||||
const boost::function<Ret (raw_type&, const CallContext&)>& func,
|
const boost::function<Ret (raw_type&, const CallContext&)>& func,
|
||||||
@ -1236,10 +1206,10 @@ namespace nasal
|
|||||||
*/
|
*/
|
||||||
template<class Arg>
|
template<class Arg>
|
||||||
static
|
static
|
||||||
typename boost::disable_if<
|
std::enable_if_t<
|
||||||
internal::reduced_is_same<Arg, CallContext>,
|
!std::is_same<std::remove_cvref_t<Arg>, CallContext>::value,
|
||||||
typename from_nasal_ptr<Arg>::return_type
|
typename from_nasal_ptr<Arg>::return_type
|
||||||
>::type
|
>
|
||||||
arg_from_nasal(const CallContext& ctx, size_t index)
|
arg_from_nasal(const CallContext& ctx, size_t index)
|
||||||
{
|
{
|
||||||
return ctx.requireArg<Arg>(index);
|
return ctx.requireArg<Arg>(index);
|
||||||
@ -1250,19 +1220,21 @@ namespace nasal
|
|||||||
*/
|
*/
|
||||||
template<class Arg>
|
template<class Arg>
|
||||||
static
|
static
|
||||||
typename boost::enable_if<
|
std::enable_if_t<
|
||||||
internal::reduced_is_same<Arg, CallContext>,
|
std::is_same<std::remove_cvref_t<Arg>, CallContext>::value,
|
||||||
typename from_nasal_ptr<Arg>::return_type
|
typename from_nasal_ptr<Arg>::return_type
|
||||||
>::type
|
>
|
||||||
arg_from_nasal(const CallContext& ctx, size_t)
|
arg_from_nasal(const CallContext& ctx, size_t)
|
||||||
{
|
{
|
||||||
// Either const CallContext& or CallContext, non-const reference
|
// Either const CallContext& or CallContext, non-const reference
|
||||||
// does not make sense.
|
// does not make sense.
|
||||||
BOOST_STATIC_ASSERT( (!boost::is_same<Arg, CallContext&>::value) );
|
static_assert(
|
||||||
|
!boost::is_same<Arg, CallContext&>::value,
|
||||||
|
"Only const reference and value make sense!");
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::unique_ptr<Ghost> GhostPtr;
|
using GhostPtr = std::unique_ptr<Ghost>;
|
||||||
MemberMap _members;
|
MemberMap _members;
|
||||||
fallback_getter_t _fallback_getter;
|
fallback_getter_t _fallback_getter;
|
||||||
fallback_setter_t _fallback_setter;
|
fallback_setter_t _fallback_setter;
|
||||||
@ -1302,13 +1274,10 @@ namespace nasal
|
|||||||
|
|
||||||
template<bool is_weak>
|
template<bool is_weak>
|
||||||
static
|
static
|
||||||
typename boost::enable_if_c<
|
std::enable_if_t<!is_weak, naRef>
|
||||||
!is_weak,
|
|
||||||
naRef
|
|
||||||
>::type
|
|
||||||
create(naContext c, const strong_ref& ref_ptr)
|
create(naContext c, const strong_ref& ref_ptr)
|
||||||
{
|
{
|
||||||
typedef shared_ptr_storage<strong_ref> storage_type;
|
using storage_type = shared_ptr_storage<strong_ref>;
|
||||||
return naNewGhost2( c,
|
return naNewGhost2( c,
|
||||||
&Ghost::_ghost_type_strong,
|
&Ghost::_ghost_type_strong,
|
||||||
storage_type::ref(ref_ptr) );
|
storage_type::ref(ref_ptr) );
|
||||||
@ -1316,13 +1285,13 @@ namespace nasal
|
|||||||
|
|
||||||
template<bool is_weak>
|
template<bool is_weak>
|
||||||
static
|
static
|
||||||
typename boost::enable_if_c<
|
std::enable_if_t<
|
||||||
is_weak && supports_weak_ref<T>::value,
|
is_weak && supports_weak_ref<T>::value,
|
||||||
naRef
|
naRef
|
||||||
>::type
|
>
|
||||||
create(naContext c, const strong_ref& ref_ptr)
|
create(naContext c, const strong_ref& ref_ptr)
|
||||||
{
|
{
|
||||||
typedef shared_ptr_storage<weak_ref> storage_type;
|
using storage_type = shared_ptr_storage<weak_ref>;
|
||||||
return naNewGhost2( c,
|
return naNewGhost2( c,
|
||||||
&Ghost::_ghost_type_weak,
|
&Ghost::_ghost_type_weak,
|
||||||
storage_type::ref(ref_ptr) );
|
storage_type::ref(ref_ptr) );
|
||||||
@ -1330,10 +1299,10 @@ namespace nasal
|
|||||||
|
|
||||||
template<bool is_weak>
|
template<bool is_weak>
|
||||||
static
|
static
|
||||||
typename boost::enable_if_c<
|
std::enable_if_t<
|
||||||
is_weak && !supports_weak_ref<T>::value,
|
is_weak && !supports_weak_ref<T>::value,
|
||||||
naRef
|
naRef
|
||||||
>::type
|
>
|
||||||
create(naContext, const strong_ref&)
|
create(naContext, const strong_ref&)
|
||||||
{
|
{
|
||||||
return naNil();
|
return naNil();
|
||||||
@ -1342,7 +1311,7 @@ namespace nasal
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
static void destroy(void *ptr)
|
static void destroy(void *ptr)
|
||||||
{
|
{
|
||||||
typedef shared_ptr_storage<Type> storage_type;
|
using storage_type = shared_ptr_storage<Type>;
|
||||||
storage_type::unref(
|
storage_type::unref(
|
||||||
static_cast<typename storage_type::storage_type*>(ptr)
|
static_cast<typename storage_type::storage_type*>(ptr)
|
||||||
);
|
);
|
||||||
@ -1477,13 +1446,11 @@ namespace nasal
|
|||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
naGhostType
|
naGhostType
|
||||||
Ghost<T, typename boost::enable_if<is_strong_ref<T> >::type>
|
Ghost<T, std::enable_if_t<is_strong_ref<T>::value>>::_ghost_type_strong;
|
||||||
::_ghost_type_strong;
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
naGhostType
|
naGhostType
|
||||||
Ghost<T, typename boost::enable_if<is_strong_ref<T> >::type>
|
Ghost<T, std::enable_if_t<is_strong_ref<T>::value>>::_ghost_type_weak;
|
||||||
::_ghost_type_weak;
|
|
||||||
|
|
||||||
} // namespace nasal
|
} // namespace nasal
|
||||||
|
|
||||||
@ -1492,15 +1459,13 @@ namespace nasal
|
|||||||
* Convert every shared pointer to a ghost.
|
* Convert every shared pointer to a ghost.
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
typename boost::enable_if<
|
std::enable_if_t<
|
||||||
nasal::internal::has_element_type<
|
nasal::internal::has_element_type<std::remove_cvref_t<T>>::value,
|
||||||
typename nasal::internal::reduced_type<T>::type
|
|
||||||
>,
|
|
||||||
naRef
|
naRef
|
||||||
>::type
|
>
|
||||||
to_nasal_helper(naContext c, T ptr)
|
to_nasal_helper(naContext c, T ptr)
|
||||||
{
|
{
|
||||||
typedef typename nasal::shared_ptr_traits<T>::strong_ref strong_ref;
|
using strong_ref = typename nasal::shared_ptr_traits<T>::strong_ref;
|
||||||
return nasal::Ghost<strong_ref>::makeGhost(c, ptr);
|
return nasal::Ghost<strong_ref>::makeGhost(c, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1508,15 +1473,13 @@ to_nasal_helper(naContext c, T ptr)
|
|||||||
* Convert nasal ghosts/hashes to shared pointer (of a ghost).
|
* Convert nasal ghosts/hashes to shared pointer (of a ghost).
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
typename boost::enable_if<
|
std::enable_if_t<
|
||||||
nasal::internal::has_element_type<
|
nasal::internal::has_element_type<std::remove_cvref_t<T>>::value,
|
||||||
typename nasal::internal::reduced_type<T>::type
|
|
||||||
>,
|
|
||||||
T
|
T
|
||||||
>::type
|
>
|
||||||
from_nasal_helper(naContext c, naRef ref, const T*)
|
from_nasal_helper(naContext c, naRef ref, const T*)
|
||||||
{
|
{
|
||||||
typedef typename nasal::shared_ptr_traits<T>::strong_ref strong_ref;
|
using strong_ref = typename nasal::shared_ptr_traits<T>::strong_ref;
|
||||||
return T(nasal::Ghost<strong_ref>::fromNasalChecked(c, ref));
|
return T(nasal::Ghost<strong_ref>::fromNasalChecked(c, ref));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1524,11 +1487,11 @@ from_nasal_helper(naContext c, naRef ref, const T*)
|
|||||||
* Convert any pointer to a SGReferenced based object to a ghost.
|
* Convert any pointer to a SGReferenced based object to a ghost.
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
typename boost::enable_if_c<
|
std::enable_if_t<
|
||||||
boost::is_base_of<SGReferenced, T>::value
|
std::is_base_of<SGReferenced, T>::value
|
||||||
|| boost::is_base_of<SGWeakReferenced, T>::value,
|
|| std::is_base_of<SGWeakReferenced, T>::value,
|
||||||
naRef
|
naRef
|
||||||
>::type
|
>
|
||||||
to_nasal_helper(naContext c, T* ptr)
|
to_nasal_helper(naContext c, T* ptr)
|
||||||
{
|
{
|
||||||
return nasal::Ghost<SGSharedPtr<T> >::makeGhost(c, SGSharedPtr<T>(ptr));
|
return nasal::Ghost<SGSharedPtr<T> >::makeGhost(c, SGSharedPtr<T>(ptr));
|
||||||
@ -1538,20 +1501,14 @@ to_nasal_helper(naContext c, T* ptr)
|
|||||||
* Convert nasal ghosts/hashes to pointer (of a SGReferenced based ghost).
|
* Convert nasal ghosts/hashes to pointer (of a SGReferenced based ghost).
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
typename boost::enable_if_c<
|
std::enable_if_t<
|
||||||
boost::is_base_of<
|
std::is_base_of<SGReferenced, std::remove_pointer_t<T>>::value
|
||||||
SGReferenced,
|
|| std::is_base_of<SGWeakReferenced, std::remove_pointer_t<T>>::value,
|
||||||
typename boost::remove_pointer<T>::type
|
|
||||||
>::value
|
|
||||||
|| boost::is_base_of<
|
|
||||||
SGWeakReferenced,
|
|
||||||
typename boost::remove_pointer<T>::type
|
|
||||||
>::value,
|
|
||||||
T
|
T
|
||||||
>::type
|
>
|
||||||
from_nasal_helper(naContext c, naRef ref, const T*)
|
from_nasal_helper(naContext c, naRef ref, const T*)
|
||||||
{
|
{
|
||||||
typedef SGSharedPtr<typename boost::remove_pointer<T>::type> TypeRef;
|
using TypeRef = SGSharedPtr<std::remove_pointer_t<T>>;
|
||||||
return T(nasal::Ghost<TypeRef>::fromNasalChecked(c, ref));
|
return T(nasal::Ghost<TypeRef>::fromNasalChecked(c, ref));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1559,10 +1516,10 @@ from_nasal_helper(naContext c, naRef ref, const T*)
|
|||||||
* Convert any pointer to a osg::Referenced based object to a ghost.
|
* Convert any pointer to a osg::Referenced based object to a ghost.
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
typename boost::enable_if<
|
std::enable_if_t<
|
||||||
boost::is_base_of<osg::Referenced, T>,
|
std::is_base_of<osg::Referenced, T>::value,
|
||||||
naRef
|
naRef
|
||||||
>::type
|
>
|
||||||
to_nasal_helper(naContext c, T* ptr)
|
to_nasal_helper(naContext c, T* ptr)
|
||||||
{
|
{
|
||||||
return nasal::Ghost<osg::ref_ptr<T> >::makeGhost(c, osg::ref_ptr<T>(ptr));
|
return nasal::Ghost<osg::ref_ptr<T> >::makeGhost(c, osg::ref_ptr<T>(ptr));
|
||||||
@ -1572,13 +1529,13 @@ to_nasal_helper(naContext c, T* ptr)
|
|||||||
* Convert nasal ghosts/hashes to pointer (of a osg::Referenced based ghost).
|
* Convert nasal ghosts/hashes to pointer (of a osg::Referenced based ghost).
|
||||||
*/
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
typename boost::enable_if<
|
std::enable_if_t<
|
||||||
boost::is_base_of<osg::Referenced, typename boost::remove_pointer<T>::type>,
|
std::is_base_of<osg::Referenced, std::remove_pointer_t<T>>::value,
|
||||||
T
|
T
|
||||||
>::type
|
>
|
||||||
from_nasal_helper(naContext c, naRef ref, const T*)
|
from_nasal_helper(naContext c, naRef ref, const T*)
|
||||||
{
|
{
|
||||||
typedef osg::ref_ptr<typename boost::remove_pointer<T>::type> TypeRef;
|
using TypeRef = osg::ref_ptr<std::remove_pointer_t<T>>;
|
||||||
return T(nasal::Ghost<TypeRef>::fromNasalChecked(c, ref));
|
return T(nasal::Ghost<TypeRef>::fromNasalChecked(c, ref));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,10 +20,7 @@
|
|||||||
#ifndef SG_NASAL_TRAITS_HXX_
|
#ifndef SG_NASAL_TRAITS_HXX_
|
||||||
#define SG_NASAL_TRAITS_HXX_
|
#define SG_NASAL_TRAITS_HXX_
|
||||||
|
|
||||||
#include <boost/mpl/logical.hpp>
|
#include <simgear/std/type_traits.hxx>
|
||||||
#include <boost/type_traits/integral_constant.hpp>
|
|
||||||
#include <boost/type_traits/is_base_of.hpp>
|
|
||||||
#include <boost/utility/enable_if.hpp>
|
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class SGReferenced;
|
class SGReferenced;
|
||||||
@ -56,12 +53,11 @@ namespace osg
|
|||||||
namespace nasal
|
namespace nasal
|
||||||
{
|
{
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_vec2: public boost::integral_constant<bool, false> {};
|
struct is_vec2: public std::false_type {};
|
||||||
|
|
||||||
#define SG_MAKE_TRAIT(templ,type,attr)\
|
#define SG_MAKE_TRAIT(templ,type,attr)\
|
||||||
template templ\
|
template templ\
|
||||||
struct attr< type >:\
|
struct attr< type >: public std::true_type {};
|
||||||
public boost::integral_constant<bool, true> {};
|
|
||||||
|
|
||||||
SG_MAKE_TRAIT(<class T>, SGVec2<T>, is_vec2)
|
SG_MAKE_TRAIT(<class T>, SGVec2<T>, is_vec2)
|
||||||
SG_MAKE_TRAIT(<>, osg::Vec2b, is_vec2)
|
SG_MAKE_TRAIT(<>, osg::Vec2b, is_vec2)
|
||||||
@ -75,42 +71,34 @@ SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2)
|
|||||||
struct shared_ptr_traits;
|
struct shared_ptr_traits;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_strong_ref:
|
struct is_strong_ref: public std::false_type {};
|
||||||
public boost::integral_constant<bool, false>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct is_weak_ref:
|
struct is_weak_ref: public std::false_type {};
|
||||||
public boost::integral_constant<bool, false>
|
|
||||||
{};
|
|
||||||
|
|
||||||
#define SG_MAKE_SHARED_PTR_TRAIT(strong, weak, intrusive)\
|
#define SG_MAKE_SHARED_PTR_TRAIT(strong, weak, intrusive)\
|
||||||
template<class T>\
|
template<class T>\
|
||||||
struct shared_ptr_traits<strong<T> >\
|
struct shared_ptr_traits<strong<T> >\
|
||||||
{\
|
{\
|
||||||
typedef strong<T> strong_ref;\
|
using strong_ref = strong<T>;\
|
||||||
typedef weak<T> weak_ref;\
|
using weak_ref = weak<T>;\
|
||||||
typedef T element_type;\
|
using element_type = T;\
|
||||||
typedef boost::integral_constant<bool, true> is_strong;\
|
using is_strong = std::true_type;\
|
||||||
typedef boost::integral_constant<bool, intrusive> is_intrusive;\
|
using is_intrusive = std::bool_constant<intrusive>;\
|
||||||
};\
|
};\
|
||||||
template<class T>\
|
template<class T>\
|
||||||
struct shared_ptr_traits<weak<T> >\
|
struct shared_ptr_traits<weak<T> >\
|
||||||
{\
|
{\
|
||||||
typedef strong<T> strong_ref;\
|
using strong_ref = strong<T>;\
|
||||||
typedef weak<T> weak_ref;\
|
using weak_ref = weak<T>;\
|
||||||
typedef T element_type;\
|
using element_type = T;\
|
||||||
typedef boost::integral_constant<bool, false> is_strong;\
|
using is_strong = std::false_type;\
|
||||||
typedef boost::integral_constant<bool, intrusive> is_intrusive;\
|
using is_intrusive = std::bool_constant<intrusive>;\
|
||||||
};\
|
};\
|
||||||
template<class T>\
|
template<class T>\
|
||||||
struct is_strong_ref<strong<T> >:\
|
struct is_strong_ref<strong<T> >: public std::true_type {};\
|
||||||
public boost::integral_constant<bool, true>\
|
|
||||||
{};\
|
|
||||||
template<class T>\
|
template<class T>\
|
||||||
struct is_weak_ref<weak<T> >:\
|
struct is_weak_ref<weak<T> >: public std::true_type {};
|
||||||
public boost::integral_constant<bool, true>\
|
|
||||||
{};
|
|
||||||
|
|
||||||
SG_MAKE_SHARED_PTR_TRAIT(SGSharedPtr, SGWeakPtr, true)
|
SG_MAKE_SHARED_PTR_TRAIT(SGSharedPtr, SGWeakPtr, true)
|
||||||
SG_MAKE_SHARED_PTR_TRAIT(osg::ref_ptr, osg::observer_ptr, true)
|
SG_MAKE_SHARED_PTR_TRAIT(osg::ref_ptr, osg::observer_ptr, true)
|
||||||
@ -119,25 +107,20 @@ SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2)
|
|||||||
#undef SG_MAKE_SHARED_PTR_TRAIT
|
#undef SG_MAKE_SHARED_PTR_TRAIT
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct supports_weak_ref:
|
struct supports_weak_ref: public std::true_type {};
|
||||||
public boost::integral_constant<bool, true>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct supports_weak_ref<SGSharedPtr<T> >:
|
struct supports_weak_ref<SGSharedPtr<T> >:
|
||||||
public boost::integral_constant<
|
public std::bool_constant<std::is_base_of<SGWeakReferenced, T>::value>
|
||||||
bool,
|
|
||||||
boost::is_base_of<SGWeakReferenced, T>::value
|
|
||||||
>
|
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct shared_ptr_storage
|
struct shared_ptr_storage
|
||||||
{
|
{
|
||||||
typedef T storage_type;
|
using storage_type = T;
|
||||||
typedef typename T::element_type element_type;
|
using element_type = typename T::element_type;
|
||||||
typedef typename shared_ptr_traits<T>::strong_ref strong_ref;
|
using strong_ref = typename shared_ptr_traits<T>::strong_ref;
|
||||||
typedef typename shared_ptr_traits<T>::weak_ref weak_ref;
|
using weak_ref = typename shared_ptr_traits<T>::weak_ref;
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
static storage_type* ref(U ptr)
|
static storage_type* ref(U ptr)
|
||||||
@ -151,39 +134,30 @@ SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2)
|
|||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
static
|
static
|
||||||
typename boost::enable_if<
|
std::enable_if_t<std::is_same<U, element_type*>::value, element_type*>
|
||||||
boost::is_same<U, element_type*>,
|
|
||||||
element_type*
|
|
||||||
>::type
|
|
||||||
get(storage_type* ptr)
|
get(storage_type* ptr)
|
||||||
{
|
{
|
||||||
return get_pointer(*ptr);
|
return get_pointer(*ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
static
|
static
|
||||||
typename boost::enable_if<
|
std::enable_if_t<
|
||||||
boost::mpl::or_<
|
std::is_same<U, strong_ref>::value
|
||||||
boost::is_same<U, strong_ref>,
|
|| (std::is_same<U, weak_ref>::value && supports_weak_ref<U>::value),
|
||||||
boost::mpl::and_<
|
|
||||||
boost::is_same<U, weak_ref>,
|
|
||||||
supports_weak_ref<U>
|
|
||||||
>
|
|
||||||
>,
|
|
||||||
U
|
U
|
||||||
>::type
|
>
|
||||||
get(storage_type* ptr)
|
get(storage_type* ptr)
|
||||||
{
|
{
|
||||||
return U(*ptr);
|
return U(*ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
static
|
static
|
||||||
typename boost::enable_if<
|
std::enable_if_t<
|
||||||
boost::mpl::and_<
|
std::is_same<U, weak_ref>::value && !supports_weak_ref<U>::value,
|
||||||
boost::is_same<U, weak_ref>,
|
|
||||||
boost::mpl::not_<supports_weak_ref<U> >
|
|
||||||
>,
|
|
||||||
U
|
U
|
||||||
>::type
|
>
|
||||||
get(storage_type* ptr)
|
get(storage_type* ptr)
|
||||||
{
|
{
|
||||||
return U();
|
return U();
|
||||||
@ -195,46 +169,37 @@ SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2)
|
|||||||
template<class T>
|
template<class T>
|
||||||
struct intrusive_ptr_storage
|
struct intrusive_ptr_storage
|
||||||
{
|
{
|
||||||
typedef typename T::element_type storage_type;
|
using storage_type = typename T::element_type;
|
||||||
typedef typename T::element_type element_type;
|
using element_type = typename T::element_type;
|
||||||
typedef typename shared_ptr_traits<T>::strong_ref strong_ref;
|
using strong_ref = typename shared_ptr_traits<T>::strong_ref;
|
||||||
typedef typename shared_ptr_traits<T>::weak_ref weak_ref;
|
using weak_ref = typename shared_ptr_traits<T>::weak_ref;
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
static
|
static
|
||||||
typename boost::enable_if<
|
std::enable_if_t<std::is_same<U, element_type*>::value, element_type*>
|
||||||
boost::is_same<U, element_type*>,
|
|
||||||
element_type*
|
|
||||||
>::type
|
|
||||||
get(storage_type* ptr)
|
get(storage_type* ptr)
|
||||||
{
|
{
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
static
|
static
|
||||||
typename boost::enable_if<
|
std::enable_if_t<
|
||||||
boost::mpl::or_<
|
std::is_same<U, strong_ref>::value
|
||||||
boost::is_same<U, strong_ref>,
|
|| (std::is_same<U, weak_ref>::value && supports_weak_ref<U>::value),
|
||||||
boost::mpl::and_<
|
|
||||||
boost::is_same<U, weak_ref>,
|
|
||||||
supports_weak_ref<U>
|
|
||||||
>
|
|
||||||
>,
|
|
||||||
U
|
U
|
||||||
>::type
|
>
|
||||||
get(storage_type* ptr)
|
get(storage_type* ptr)
|
||||||
{
|
{
|
||||||
return U(ptr);
|
return U(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U>
|
template<class U>
|
||||||
static
|
static
|
||||||
typename boost::enable_if<
|
std::enable_if_t<
|
||||||
boost::mpl::and_<
|
std::is_same<U, weak_ref>::value && !supports_weak_ref<U>::value,
|
||||||
boost::is_same<U, weak_ref>,
|
|
||||||
boost::mpl::not_<supports_weak_ref<U> >
|
|
||||||
>,
|
|
||||||
U
|
U
|
||||||
>::type
|
>
|
||||||
get(storage_type* ptr)
|
get(storage_type* ptr)
|
||||||
{
|
{
|
||||||
return U();
|
return U();
|
||||||
@ -246,8 +211,8 @@ SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2)
|
|||||||
struct shared_ptr_storage<SGSharedPtr<T> >:
|
struct shared_ptr_storage<SGSharedPtr<T> >:
|
||||||
public internal::intrusive_ptr_storage<SGSharedPtr<T> >
|
public internal::intrusive_ptr_storage<SGSharedPtr<T> >
|
||||||
{
|
{
|
||||||
typedef T storage_type;
|
using storage_type = T;
|
||||||
typedef T element_type;
|
using element_type = T;
|
||||||
|
|
||||||
static storage_type* ref(element_type* ptr)
|
static storage_type* ref(element_type* ptr)
|
||||||
{
|
{
|
||||||
@ -265,8 +230,8 @@ SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2)
|
|||||||
struct shared_ptr_storage<osg::ref_ptr<T> >:
|
struct shared_ptr_storage<osg::ref_ptr<T> >:
|
||||||
public internal::intrusive_ptr_storage<osg::ref_ptr<T> >
|
public internal::intrusive_ptr_storage<osg::ref_ptr<T> >
|
||||||
{
|
{
|
||||||
typedef T storage_type;
|
using storage_type = T;
|
||||||
typedef T element_type;
|
using element_type = T;
|
||||||
|
|
||||||
|
|
||||||
static storage_type* ref(element_type* ptr)
|
static storage_type* ref(element_type* ptr)
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
#cmakedefine HAVE_MKDTEMP
|
#cmakedefine HAVE_MKDTEMP
|
||||||
#cmakedefine HAVE_AL_EXT_H
|
#cmakedefine HAVE_AL_EXT_H
|
||||||
#cmakedefine HAVE_STD_INDEX_SEQUENCE
|
#cmakedefine HAVE_STD_INDEX_SEQUENCE
|
||||||
|
#cmakedefine HAVE_STD_REMOVE_CV_T
|
||||||
|
#cmakedefine HAVE_STD_REMOVE_CVREF_T
|
||||||
|
#cmakedefine HAVE_STD_ENABLE_IF_T
|
||||||
|
#cmakedefine HAVE_STD_BOOL_CONSTANT
|
||||||
|
|
||||||
#cmakedefine GCC_ATOMIC_BUILTINS_FOUND
|
#cmakedefine GCC_ATOMIC_BUILTINS_FOUND
|
||||||
|
|
||||||
|
21
simgear/std/CMakeLists.txt
Normal file
21
simgear/std/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
include (SimGearComponent)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
integer_sequence.hxx
|
||||||
|
type_traits.hxx
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
)
|
||||||
|
|
||||||
|
simgear_component(std std "${SOURCES}" "${HEADERS}")
|
||||||
|
|
||||||
|
if(ENABLE_TESTS)
|
||||||
|
add_executable(test_integer_sequence integer_sequence_test.cxx)
|
||||||
|
add_test(integer_sequence ${EXECUTABLE_OUTPUT_PATH}/test_integer_sequence)
|
||||||
|
target_link_libraries(test_integer_sequence ${TEST_LIBS})
|
||||||
|
|
||||||
|
add_executable(test_type_traits type_traits_test.cxx)
|
||||||
|
add_test(type_traits ${EXECUTABLE_OUTPUT_PATH}/test_type_traits)
|
||||||
|
target_link_libraries(test_type_traits ${TEST_LIBS})
|
||||||
|
endif()
|
@ -17,13 +17,13 @@
|
|||||||
// License along with this library; if not, write to the Free Software
|
// License along with this library; if not, write to the Free Software
|
||||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
#ifndef SIMGEAR_MISC_INTEGER_SEQUENCE_HXX_
|
#ifndef SIMGEAR_STD_INTEGER_SEQUENCE_HXX_
|
||||||
#define SIMGEAR_MISC_INTEGER_SEQUENCE_HXX_
|
#define SIMGEAR_STD_INTEGER_SEQUENCE_HXX_
|
||||||
|
|
||||||
#include <simgear/simgear_config.h>
|
#include <simgear/simgear_config.h>
|
||||||
|
#include "type_traits.hxx"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#ifndef HAVE_STD_INDEX_SEQUENCE
|
#ifndef HAVE_STD_INDEX_SEQUENCE
|
||||||
# include <cstddef>
|
# include <cstddef>
|
||||||
@ -85,4 +85,4 @@ namespace std
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* SIMGEAR_MISC_INTEGER_SEQUENCE_HXX_ */
|
#endif /* SIMGEAR_STD_INTEGER_SEQUENCE_HXX_ */
|
@ -1,5 +1,4 @@
|
|||||||
#include "integer_sequence.hxx"
|
#include <simgear/std/integer_sequence.hxx>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
67
simgear/std/type_traits.hxx
Normal file
67
simgear/std/type_traits.hxx
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
///@file
|
||||||
|
/// Type Traits (Provide features of later C++ standards)
|
||||||
|
//
|
||||||
|
// Copyright (C) 2017 Thomas Geymayer <tomgey@gmail.com>
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Library General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Library General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Library General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
|
#ifndef SIMGEAR_STD_TYPE_TRAITS_HXX_
|
||||||
|
#define SIMGEAR_STD_TYPE_TRAITS_HXX_
|
||||||
|
|
||||||
|
#include <simgear/simgear_config.h>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
#ifndef HAVE_STD_REMOVE_CV_T
|
||||||
|
template<class T>
|
||||||
|
using remove_cv_t = typename remove_cv<T>::type;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using remove_const_t = typename remove_const<T>::type;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using remove_volatile_t = typename remove_volatile<T>::type;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using remove_reference_t = typename remove_reference<T>::type;
|
||||||
|
|
||||||
|
template< class T >
|
||||||
|
using remove_pointer_t = typename remove_pointer<T>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STD_REMOVE_CVREF_T
|
||||||
|
template<class T>
|
||||||
|
struct remove_cvref
|
||||||
|
{
|
||||||
|
using type = remove_cv_t<remove_reference_t<T>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using remove_cvref_t = typename remove_cvref<T>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STD_ENABLE_IF_T
|
||||||
|
template<bool B, class T = void>
|
||||||
|
using enable_if_t = typename enable_if<B, T>::type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STD_BOOL_CONSTANT
|
||||||
|
template <bool B>
|
||||||
|
using bool_constant = integral_constant<bool, B>;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SIMGEAR_STD_TYPE_TRAITS_HXX_ */
|
24
simgear/std/type_traits_test.cxx
Normal file
24
simgear/std/type_traits_test.cxx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include <simgear/std/type_traits.hxx>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
void assert_same()
|
||||||
|
{
|
||||||
|
static_assert(is_same<T, U>::value, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
assert_same<remove_cv_t<int const volatile>, int>();
|
||||||
|
assert_same<remove_const_t<int const volatile>, int volatile>();
|
||||||
|
assert_same<remove_volatile_t<int const volatile>, int const>();
|
||||||
|
assert_same<remove_reference_t<int const volatile&>, int const volatile>();
|
||||||
|
assert_same<remove_pointer_t<int const volatile*>, int const volatile>();
|
||||||
|
assert_same<remove_cvref_t<int const volatile&>, int>();
|
||||||
|
|
||||||
|
assert_same<enable_if_t<true, double>, double>();
|
||||||
|
assert_same<bool_constant<true>, integral_constant<bool, true>>();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user