diff --git a/include/boost/core/is_same.hpp b/include/boost/core/is_same.hpp new file mode 100644 index 0000000..f373c65 --- /dev/null +++ b/include/boost/core/is_same.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_CORE_IS_SAME_HPP_INCLUDED +#define BOOST_CORE_IS_SAME_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// is_same::value is true when T1 == T2 +// +// Copyright 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include + +namespace boost +{ + +namespace core +{ + +template< class T1, class T2 > struct is_same +{ + BOOST_STATIC_CONSTANT( bool, value = false ); +}; + +template< class T > struct is_same< T, T > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +} // namespace core + +} // namespace boost + +#endif // #ifndef BOOST_CORE_IS_SAME_HPP_INCLUDED diff --git a/include/boost/core/lightweight_test.hpp b/include/boost/core/lightweight_test.hpp index d81c7b8..ec75881 100644 --- a/include/boost/core/lightweight_test.hpp +++ b/include/boost/core/lightweight_test.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include // IDE's like Visual Studio perform better if output goes to std::cout or @@ -38,18 +39,20 @@ namespace detail struct report_errors_reminder { - bool called_report_errors_function; - report_errors_reminder() : called_report_errors_function(false) {} - ~report_errors_reminder() - { - BOOST_ASSERT(called_report_errors_function); // verify report_errors() was called - } + bool called_report_errors_function; + + report_errors_reminder() : called_report_errors_function(false) {} + + ~report_errors_reminder() + { + BOOST_ASSERT(called_report_errors_function); // verify report_errors() was called + } }; inline report_errors_reminder& report_errors_remind() { - static report_errors_reminder r; - return r; + static report_errors_reminder r; + return r; } inline int & test_errors() @@ -115,6 +118,25 @@ template inline void test_ne_impl( char const * expr1, char co } } +template< class T > inline void test_trait_impl( char const * trait, void (*)( T ), + bool expected, char const * file, int line, char const * function ) +{ + if( T::value == expected ) + { + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): predicate '" << trait << "' [" + << BOOST_CORE_TYPEID(T).name() << "]" + << " test failed in function '" << function + << "' (should have been " << ( expected? "true": "false" ) << ")" + << std::endl; + + ++boost::detail::test_errors(); + } +} + } // namespace detail inline int report_errors() @@ -140,9 +162,12 @@ inline int report_errors() } // namespace boost #define BOOST_TEST(expr) ((expr)? (void)0: ::boost::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION)) -#define BOOST_ERROR(msg) ::boost::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) + +#define BOOST_ERROR(msg) ( ::boost::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) ) + #define BOOST_TEST_EQ(expr1,expr2) ( ::boost::detail::test_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) #define BOOST_TEST_NE(expr1,expr2) ( ::boost::detail::test_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) + #ifndef BOOST_NO_EXCEPTIONS #define BOOST_TEST_THROWS( EXPR, EXCEP ) \ try { \ @@ -161,4 +186,7 @@ inline int report_errors() #define BOOST_TEST_THROWS( EXPR, EXCEP ) #endif +#define BOOST_TEST_TRAIT_TRUE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, true, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) ) +#define BOOST_TEST_TRAIT_FALSE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, false, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) ) + #endif // #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP diff --git a/include/boost/core/typeinfo.hpp b/include/boost/core/typeinfo.hpp new file mode 100644 index 0000000..49d7731 --- /dev/null +++ b/include/boost/core/typeinfo.hpp @@ -0,0 +1,140 @@ +#ifndef BOOST_CORE_TYPEINFO_HPP_INCLUDED +#define BOOST_CORE_TYPEINFO_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// core::typeinfo, BOOST_CORE_TYPEID +// +// Copyright 2007, 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if defined( BOOST_NO_TYPEID ) + +#include +#include + +namespace boost +{ + +namespace core +{ + +class typeinfo +{ +private: + + typeinfo( typeinfo const& ); + typeinfo& operator=( typeinfo const& ); + + char const * name_; + +public: + + explicit typeinfo( char const * name ): name_( name ) + { + } + + bool operator==( typeinfo const& rhs ) const + { + return this == &rhs; + } + + bool operator!=( typeinfo const& rhs ) const + { + return this != &rhs; + } + + bool before( typeinfo const& rhs ) const + { + return std::less< typeinfo const* >()( this, &rhs ); + } + + char const* name() const + { + return name_; + } +}; + +} // namespace core + +namespace detail +{ + +template struct core_typeid_ +{ + static boost::core::typeinfo ti_; + + static char const * name() + { + return BOOST_CURRENT_FUNCTION; + } +}; + +#if defined(__SUNPRO_CC) +// see #4199, the Sun Studio compiler gets confused about static initialization +// constructor arguments. But an assignment works just fine. +template boost::core::typeinfo core_typeid_< T >::ti_ = core_typeid_< T >::name(); +#else +template boost::core::typeinfo core_typeid_< T >::ti_(core_typeid_< T >::name()); +#endif + +template struct core_typeid_< T & >: core_typeid_< T > +{ +}; + +template struct core_typeid_< T const >: core_typeid_< T > +{ +}; + +template struct core_typeid_< T volatile >: core_typeid_< T > +{ +}; + +template struct core_typeid_< T const volatile >: core_typeid_< T > +{ +}; + +} // namespace detail + +} // namespace boost + +#define BOOST_CORE_TYPEID(T) (boost::detail::core_typeid_::ti_) + +#else + +#include + +namespace boost +{ + +namespace core +{ + +#if defined( BOOST_NO_STD_TYPEINFO ) + +typedef ::type_info typeinfo; + +#else + +typedef std::type_info typeinfo; + +#endif + +} // namespace core + +} // namespace boost + +#define BOOST_CORE_TYPEID(T) typeid(T) + +#endif + +#endif // #ifndef BOOST_CORE_TYPEINFO_HPP_INCLUDED diff --git a/include/boost/detail/sp_typeinfo.hpp b/include/boost/detail/sp_typeinfo.hpp index 43fae78..4e4de55 100644 --- a/include/boost/detail/sp_typeinfo.hpp +++ b/include/boost/detail/sp_typeinfo.hpp @@ -9,18 +9,15 @@ // detail/sp_typeinfo.hpp // +// Deprecated, please use boost/core/typeinfo.hpp +// // Copyright 2007 Peter Dimov // -// Distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) -#include - -#if defined( BOOST_NO_TYPEID ) - -#include -#include +#include namespace boost { @@ -28,108 +25,12 @@ namespace boost namespace detail { -class sp_typeinfo -{ -private: - - sp_typeinfo( sp_typeinfo const& ); - sp_typeinfo& operator=( sp_typeinfo const& ); - - char const * name_; - -public: - - explicit sp_typeinfo( char const * name ): name_( name ) - { - } - - bool operator==( sp_typeinfo const& rhs ) const - { - return this == &rhs; - } - - bool operator!=( sp_typeinfo const& rhs ) const - { - return this != &rhs; - } - - bool before( sp_typeinfo const& rhs ) const - { - return std::less< sp_typeinfo const* >()( this, &rhs ); - } - - char const* name() const - { - return name_; - } -}; - -template struct sp_typeid_ -{ - static sp_typeinfo ti_; - - static char const * name() - { - return BOOST_CURRENT_FUNCTION; - } -}; - -#if defined(__SUNPRO_CC) -// see #4199, the Sun Studio compiler gets confused about static initialization -// constructor arguments. But an assignment works just fine. -template sp_typeinfo sp_typeid_< T >::ti_ = sp_typeid_< T >::name(); -#else -template sp_typeinfo sp_typeid_< T >::ti_(sp_typeid_< T >::name()); -#endif - -template struct sp_typeid_< T & >: sp_typeid_< T > -{ -}; - -template struct sp_typeid_< T const >: sp_typeid_< T > -{ -}; - -template struct sp_typeid_< T volatile >: sp_typeid_< T > -{ -}; - -template struct sp_typeid_< T const volatile >: sp_typeid_< T > -{ -}; +typedef boost::core::typeinfo sp_typeinfo; } // namespace detail } // namespace boost -#define BOOST_SP_TYPEID(T) (boost::detail::sp_typeid_::ti_) - -#else - -#include - -namespace boost -{ - -namespace detail -{ - -#if defined( BOOST_NO_STD_TYPEINFO ) - -typedef ::type_info sp_typeinfo; - -#else - -typedef std::type_info sp_typeinfo; - -#endif - -} // namespace detail - -} // namespace boost - -#define BOOST_SP_TYPEID(T) typeid(T) - -#endif +#define BOOST_SP_TYPEID(T) BOOST_CORE_TYPEID(T) #endif // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index eb6be32..8e72070 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -56,3 +56,12 @@ run-fail lightweight_test_fail3.cpp ; run-fail lightweight_test_fail4.cpp ; run-fail lightweight_test_fail5.cpp ; run-fail lightweight_test_fail6.cpp ; +run-fail lightweight_test_fail7.cpp ; +run-fail lightweight_test_fail8.cpp ; + +run is_same_test.cpp ; + +run typeinfo_test.cpp ; +run typeinfo_test.cpp : : : off : typeinfo_test_no_rtti ; + +run iterator_test.cpp ; diff --git a/test/is_same_test.cpp b/test/is_same_test.cpp new file mode 100644 index 0000000..08756e5 --- /dev/null +++ b/test/is_same_test.cpp @@ -0,0 +1,39 @@ +// +// Test for core::is_same +// +// Copyright 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include +#include +#include + +struct X +{ +}; + +struct Y +{ +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same )); + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same )); + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same )); + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same )); + BOOST_TEST_TRAIT_TRUE(( boost::core::is_same )); + + BOOST_TEST_TRAIT_FALSE(( boost::core::is_same )); + BOOST_TEST_TRAIT_FALSE(( boost::core::is_same )); + BOOST_TEST_TRAIT_FALSE(( boost::core::is_same )); + BOOST_TEST_TRAIT_FALSE(( boost::core::is_same )); + BOOST_TEST_TRAIT_FALSE(( boost::core::is_same )); + BOOST_TEST_TRAIT_FALSE(( boost::core::is_same )); + + return boost::report_errors(); +} diff --git a/test/iterator_test.cpp b/test/iterator_test.cpp new file mode 100644 index 0000000..d0ca885 --- /dev/null +++ b/test/iterator_test.cpp @@ -0,0 +1,69 @@ +// +// Test for boost/iterator.hpp +// +// Copyright 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include +#include +#include + +/* + +template< class Category, class T, + class Distance = ptrdiff_t, + class Pointer = T*, + class Reference = T&> +struct iterator +{ + typedef T value_type; + typedef Distance difference_type; + typedef Pointer pointer; + typedef Reference reference; + typedef Category iterator_category; +}; + +*/ + +struct C +{ +}; + +struct T +{ +}; + +struct D +{ +}; + +struct P +{ +}; + +struct R +{ +}; + +int main() +{ + using boost::core::is_same; + + BOOST_TEST_TRAIT_TRUE((is_same::iterator_category,C>)); + BOOST_TEST_TRAIT_TRUE((is_same::value_type,T>)); + BOOST_TEST_TRAIT_TRUE((is_same::difference_type,D>)); + BOOST_TEST_TRAIT_TRUE((is_same::pointer,P>)); + BOOST_TEST_TRAIT_TRUE((is_same::reference,R>)); + + BOOST_TEST_TRAIT_TRUE((is_same::iterator_category,C>)); + BOOST_TEST_TRAIT_TRUE((is_same::value_type,T>)); + BOOST_TEST_TRAIT_TRUE((is_same::difference_type,std::ptrdiff_t>)); + BOOST_TEST_TRAIT_TRUE((is_same::pointer,T*>)); + BOOST_TEST_TRAIT_TRUE((is_same::reference,T&>)); + + return boost::report_errors(); +} diff --git a/test/lightweight_test_fail7.cpp b/test/lightweight_test_fail7.cpp new file mode 100644 index 0000000..85ce8e9 --- /dev/null +++ b/test/lightweight_test_fail7.cpp @@ -0,0 +1,38 @@ +// +// Negative test for BOOST_TEST_TRAIT_TRUE +// +// Copyright (c) 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +template struct Y1 +{ + enum { value = 1 }; +}; + +template struct Y2 +{ + enum { value = 0 }; +}; + +struct X1 +{ + typedef int type; +}; + +struct X2 +{ + typedef int type; +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE(( Y2 )); + + return boost::report_errors(); +} diff --git a/test/lightweight_test_fail8.cpp b/test/lightweight_test_fail8.cpp new file mode 100644 index 0000000..f2311b0 --- /dev/null +++ b/test/lightweight_test_fail8.cpp @@ -0,0 +1,38 @@ +// +// Negative test for BOOST_TEST_TRAIT_FALSE +// +// Copyright (c) 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +template struct Y1 +{ + enum { value = 1 }; +}; + +template struct Y2 +{ + enum { value = 0 }; +}; + +struct X1 +{ + typedef int type; +}; + +struct X2 +{ + typedef int type; +}; + +int main() +{ + BOOST_TEST_TRAIT_FALSE(( Y1 )); + + return boost::report_errors(); +} diff --git a/test/lightweight_test_test.cpp b/test/lightweight_test_test.cpp index 7847ad1..8fae051 100644 --- a/test/lightweight_test_test.cpp +++ b/test/lightweight_test_test.cpp @@ -32,6 +32,26 @@ void f( bool x ) } } +template struct Y1 +{ + enum { value = 1 }; +}; + +template struct Y2 +{ + enum { value = 0 }; +}; + +struct X1 +{ + typedef int type; +}; + +struct X2 +{ + typedef int type; +}; + int main() { int x = 0; @@ -68,7 +88,13 @@ int main() BOOST_TEST_THROWS( f(true), X ); BOOST_TEST_THROWS( f(false), int ); - // + // BOOST_TEST_TRAIT_TRUE + + BOOST_TEST_TRAIT_TRUE(( Y1 )); + + // BOOST_TEST_TRAIT_FALSE + + BOOST_TEST_TRAIT_FALSE(( Y2 )); return boost::report_errors(); } diff --git a/test/typeinfo_test.cpp b/test/typeinfo_test.cpp new file mode 100644 index 0000000..3e122bb --- /dev/null +++ b/test/typeinfo_test.cpp @@ -0,0 +1,51 @@ +// +// typeinfo_test.cpp +// +// Copyright (c) 2009 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include +#include +#include + +int main() +{ + BOOST_TEST( BOOST_CORE_TYPEID( int ) == BOOST_CORE_TYPEID( int ) ); + BOOST_TEST( BOOST_CORE_TYPEID( int ) != BOOST_CORE_TYPEID( long ) ); + BOOST_TEST( BOOST_CORE_TYPEID( int ) != BOOST_CORE_TYPEID( void ) ); + + boost::core::typeinfo const & ti = BOOST_CORE_TYPEID( int ); + + boost::core::typeinfo const * pti = &BOOST_CORE_TYPEID( int ); + BOOST_TEST( *pti == ti ); + + BOOST_TEST( ti == ti ); + BOOST_TEST( !( ti != ti ) ); + BOOST_TEST( !ti.before( ti ) ); + + char const * nti = ti.name(); + std::cout << nti << std::endl; + + boost::core::typeinfo const & tv = BOOST_CORE_TYPEID( void ); + + boost::core::typeinfo const * ptv = &BOOST_CORE_TYPEID( void ); + BOOST_TEST( *ptv == tv ); + + BOOST_TEST( tv == tv ); + BOOST_TEST( !( tv != tv ) ); + BOOST_TEST( !tv.before( tv ) ); + + char const * ntv = tv.name(); + std::cout << ntv << std::endl; + + BOOST_TEST( ti != tv ); + BOOST_TEST( !( ti == tv ) ); + + BOOST_TEST( ti.before( tv ) != tv.before( ti ) ); + + return boost::report_errors(); +}