Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:35:26

0001 #ifndef BOOST_DESCRIBE_OPERATORS_HPP_INCLUDED
0002 #define BOOST_DESCRIBE_OPERATORS_HPP_INCLUDED
0003 
0004 // Copyright 2020, 2021 Peter Dimov
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // https://www.boost.org/LICENSE_1_0.txt
0007 
0008 #include <boost/describe/detail/config.hpp>
0009 
0010 #if defined(BOOST_DESCRIBE_CXX14)
0011 
0012 #include <boost/describe/bases.hpp>
0013 #include <boost/describe/members.hpp>
0014 #include <boost/describe/modifiers.hpp>
0015 #include <boost/mp11/algorithm.hpp>
0016 #include <type_traits>
0017 #include <iosfwd>
0018 
0019 #if defined(_MSC_VER) && _MSC_VER == 1900
0020 # pragma warning(push)
0021 # pragma warning(disable: 4100) // unreferenced formal parameter
0022 #endif
0023 
0024 namespace boost
0025 {
0026 namespace describe
0027 {
0028 
0029 namespace detail
0030 {
0031 
0032 template<class T,
0033     class Bd = describe::describe_bases<T, mod_any_access>,
0034     class Md = describe::describe_members<T, mod_any_access>>
0035 bool eq( T const& t1, T const& t2 )
0036 {
0037     bool r = true;
0038 
0039     mp11::mp_for_each<Bd>([&](auto D){
0040 
0041         using B = typename decltype(D)::type;
0042         r = r && (B const&)t1 == (B const&)t2;
0043 
0044     });
0045 
0046     mp11::mp_for_each<Md>([&](auto D){
0047 
0048         r = r && t1.*D.pointer == t2.*D.pointer;
0049 
0050     });
0051 
0052     return r;
0053 }
0054 
0055 template<class T,
0056     class Bd = describe::describe_bases<T, mod_any_access>,
0057     class Md = describe::describe_members<T, mod_any_access>>
0058 bool lt( T const& t1, T const& t2 )
0059 {
0060     int r = 0;
0061 
0062     mp11::mp_for_each<Bd>([&](auto D){
0063 
0064         using B = typename decltype(D)::type;
0065         if( r == 0 && (B const&)t1 < (B const&)t2 ) r = -1;
0066         if( r == 0 && (B const&)t2 < (B const&)t1 ) r = +1;
0067 
0068     });
0069 
0070     mp11::mp_for_each<Md>([&](auto D){
0071 
0072         if( r == 0 && t1.*D.pointer < t2.*D.pointer ) r = -1;
0073         if( r == 0 && t2.*D.pointer < t1.*D.pointer ) r = +1;
0074 
0075     });
0076 
0077     return r < 0;
0078 }
0079 
0080 template<class Os, class T,
0081     class Bd = describe::describe_bases<T, mod_any_access>,
0082     class Md = describe::describe_members<T, mod_any_access>>
0083 void print( Os& os, T const& t )
0084 {
0085     os << "{";
0086 
0087     bool first = true;
0088 
0089     mp11::mp_for_each<Bd>([&](auto D){
0090 
0091         if( !first ) { os << ", "; }
0092         first = false;
0093 
0094         using B = typename decltype(D)::type;
0095         os << (B const&)t;
0096 
0097     });
0098 
0099     mp11::mp_for_each<Md>([&](auto D){
0100 
0101         if( !first ) { os << ", "; }
0102         first = false;
0103 
0104         os << "." << D.name << " = " << t.*D.pointer;
0105 
0106     });
0107 
0108     os << "}";
0109 }
0110 
0111 } // namespace detail
0112 
0113 namespace operators
0114 {
0115 
0116 template<class T> std::enable_if_t<
0117     has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
0118     operator==( T const& t1, T const& t2 )
0119 {
0120     return detail::eq( t1, t2 );
0121 }
0122 
0123 template<class T> std::enable_if_t<
0124     has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
0125     operator!=( T const& t1, T const& t2 )
0126 {
0127     return !detail::eq( t1, t2 );
0128 }
0129 
0130 template<class T> std::enable_if_t<
0131     has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
0132     operator<( T const& t1, T const& t2 )
0133 {
0134     return detail::lt( t1, t2 );
0135 }
0136 
0137 template<class T> std::enable_if_t<
0138     has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
0139     operator>=( T const& t1, T const& t2 )
0140 {
0141     return !detail::lt( t1, t2 );
0142 }
0143 
0144 template<class T> std::enable_if_t<
0145     has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
0146     operator>( T const& t1, T const& t2 )
0147 {
0148     return detail::lt( t2, t1 );
0149 }
0150 
0151 template<class T> std::enable_if_t<
0152     has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value, bool>
0153     operator<=( T const& t1, T const& t2 )
0154 {
0155     return !detail::lt( t2, t1 );
0156 }
0157 
0158 template<class T, class Ch, class Tr> std::enable_if_t<
0159     has_describe_bases<T>::value && has_describe_members<T>::value && !std::is_union<T>::value,
0160     std::basic_ostream<Ch, Tr>&>
0161     operator<<( std::basic_ostream<Ch, Tr>& os, T const& t )
0162 {
0163     os.width( 0 );
0164     detail::print( os, t );
0165     return os;
0166 }
0167 
0168 } // namespace operators
0169 
0170 } // namespace describe
0171 } // namespace boost
0172 
0173 #if defined(_MSC_VER) && _MSC_VER == 1900
0174 # pragma warning(pop)
0175 #endif
0176 
0177 #endif // defined(BOOST_DESCRIBE_CXX14)
0178 
0179 #endif // #ifndef BOOST_DESCRIBE_OPERATORS_HPP_INCLUDED