Ticket #5475: foreach_cxx0x_v2.patch
File foreach_cxx0x_v2.patch, 12.8 KB (added by , 12 years ago) |
---|
-
Boosty/boost-trunk/boost/foreach.hpp
30 30 #include <boost/config.hpp> 31 31 #include <boost/detail/workaround.hpp> 32 32 33 // Some compilers support rvalue references and auto type deduction. 34 // With these C++0x features, temporary collections can be bound to 35 // rvalue references and their lifetime is extended. No copy/move is needed. 36 #if !defined(BOOST_NO_DECLTYPE) && !defined(BOOST_NO_RVALUE_REFERENCES) 37 # define BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING 33 38 // Some compilers let us detect even const-qualified rvalues at compile-time 34 # if !defined(BOOST_NO_RVALUE_REFERENCES)\39 #elif !defined(BOOST_NO_RVALUE_REFERENCES) \ 35 40 || BOOST_WORKAROUND(BOOST_MSVC, >= 1310) && !defined(_PREFAST_) \ 36 41 || (BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ <= 5) && !defined(BOOST_INTEL) && \ 37 42 !defined(BOOST_CLANG)) \ … … 88 93 #include <boost/utility/addressof.hpp> 89 94 #include <boost/foreach_fwd.hpp> 90 95 96 #ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING 97 # include <boost/type_traits/decay.hpp> 98 # include <boost/type_traits/remove_const.hpp> 99 # include <boost/type_traits/remove_cv.hpp> 100 #endif 101 91 102 #ifdef BOOST_FOREACH_RUN_TIME_CONST_RVALUE_DETECTION 92 103 # include <new> 93 104 # include <boost/aligned_storage.hpp> 94 105 # include <boost/utility/enable_if.hpp> 95 # include <boost/type_traits/remove_const.hpp>96 106 #endif 97 107 98 108 namespace boost … … 689 699 } 690 700 #endif 691 701 702 #ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING 703 template<typename T> 704 inline typename foreach_iterator<typename remove_const<T>::type, is_const<T> >::type 705 begin(T &col) 706 { 707 return boost::begin(col); 708 } 709 710 template<typename T> 711 inline T * 712 begin(T *&col) 713 { 714 return col; 715 } 716 717 template<typename T> 718 inline T * 719 begin(T * const &col) 720 { 721 return col; 722 } 723 #endif 724 692 725 /////////////////////////////////////////////////////////////////////////////// 693 726 // end 694 727 // … … 729 762 } 730 763 #endif 731 764 765 #ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING 766 template<typename T> 767 inline typename foreach_iterator<typename remove_const<T>::type, is_const<T> >::type 768 end(T &col) 769 { 770 return boost::end(col); 771 } 772 773 struct cstr_end_iterator 774 { 775 }; 776 777 template<typename T> 778 inline cstr_end_iterator 779 end(T *&col) 780 { 781 return cstr_end_iterator(); 782 } 783 784 template<typename T> 785 inline cstr_end_iterator 786 end(T * const &col) 787 { 788 return cstr_end_iterator(); 789 } 790 #endif 791 732 792 /////////////////////////////////////////////////////////////////////////////// 733 793 // done 734 794 // … … 747 807 } 748 808 #endif 749 809 810 #ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING 811 template<typename Iterator> 812 inline bool operator !=(Iterator cur, cstr_end_iterator) 813 { 814 return *cur != 0; 815 } 816 #endif 817 818 750 819 /////////////////////////////////////////////////////////////////////////////// 751 820 // next 752 821 // … … 811 880 } 812 881 #endif 813 882 883 #ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING 884 template<typename T> 885 inline typename foreach_reverse_iterator<typename remove_const<T>::type, is_const<T> >::type 886 rbegin(T &col) 887 { 888 return boost::rbegin(col); 889 } 890 891 template<typename T> 892 inline reverse_iterator<T *> 893 rbegin(T *&col) 894 { 895 T *p = col; 896 while(0 != *p) 897 ++p; 898 return reverse_iterator<T *>(p); 899 } 900 901 template<typename T> 902 inline reverse_iterator<T *> 903 rbegin(T * const &col) 904 { 905 T *p = col; 906 while(0 != *p) 907 ++p; 908 return reverse_iterator<T *>(p); 909 } 910 #endif 911 814 912 /////////////////////////////////////////////////////////////////////////////// 815 913 // rend 816 914 // … … 852 950 } 853 951 #endif 854 952 953 #ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING 954 template<typename T> 955 inline typename foreach_reverse_iterator<typename remove_const<T>::type, is_const<T> >::type 956 rend(T &col) 957 { 958 return boost::rend(col); 959 } 960 961 template<typename T> 962 inline reverse_iterator<T *> 963 rend(T *&col) 964 { 965 return reverse_iterator<T *>(col); 966 } 967 968 template<typename T> 969 inline reverse_iterator<T *> 970 rend(T * const &col) 971 { 972 return reverse_iterator<T *>(col); 973 } 974 #endif 975 855 976 /////////////////////////////////////////////////////////////////////////////// 856 977 // rdone 857 978 // … … 922 1043 boost::foreach_detail_::to_ptr(COL) \ 923 1044 , boost_foreach_argument_dependent_lookup_hack_value)) 924 1045 925 #if defined(BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION)926 1046 /////////////////////////////////////////////////////////////////////////////// 1047 // R-values and const R-values are bound to rvalue references 1048 /////////////////////////////////////////////////////////////////////////////// 1049 #if defined(BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING) 1050 # define BOOST_FOREACH_PREAMBLE() \ 1051 BOOST_FOREACH_SUPPRESS_WARNINGS() 1052 1053 namespace boost { namespace foreach_detail_ 1054 { 1055 template<typename T> 1056 typename remove_cv<typename decay<T>::type>::type decay_copy(T &&); 1057 1058 template<typename T> 1059 T const add_const_if_rvalue(T &&); 1060 }} 1061 # define BOOST_FOREACH_AUTO_OBJECT(NAME, EXPR) \ 1062 if (bool BOOST_PP_CAT(NAME, _defined) = false) {} else \ 1063 for (decltype(boost::foreach_detail_::decay_copy(EXPR)) NAME = (EXPR); \ 1064 !BOOST_PP_CAT(NAME, _defined); BOOST_PP_CAT(NAME, _defined) = true) 1065 1066 // If EXPR is an rvalue, bind it to a const rvalue reference. 1067 # define BOOST_FOREACH_AUTO_REF_REF(NAME, EXPR) \ 1068 if (bool BOOST_PP_CAT(NAME, _defined) = false) {} else \ 1069 for (decltype(boost::foreach_detail_::add_const_if_rvalue(EXPR)) &&NAME = (EXPR); \ 1070 !BOOST_PP_CAT(NAME, _defined); BOOST_PP_CAT(NAME, _defined) = true) 1071 1072 #elif defined(BOOST_FOREACH_COMPILE_TIME_CONST_RVALUE_DETECTION) 1073 /////////////////////////////////////////////////////////////////////////////// 927 1074 // R-values and const R-values supported here with zero runtime overhead 928 1075 /////////////////////////////////////////////////////////////////////////////// 1076 # define BOOST_FOREACH_PREAMBLE() \ 1077 BOOST_FOREACH_SUPPRESS_WARNINGS() 929 1078 1079 1080 930 1081 // No variable is needed to track the rvalue-ness of the collection expression 931 1082 # define BOOST_FOREACH_PREAMBLE() \ 932 1083 BOOST_FOREACH_SUPPRESS_WARNINGS() … … 1092 1243 // BOOST_FOREACH(i, int_list) 1093 1244 // { ... } 1094 1245 // 1095 #define BOOST_FOREACH(VAR, COL) \ 1246 #ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING 1247 # define BOOST_FOREACH(VAR, COL) \ 1248 BOOST_FOREACH_PREAMBLE() \ 1249 BOOST_FOREACH_AUTO_REF_REF( \ 1250 BOOST_FOREACH_ID(_foreach_col) \ 1251 , COL) \ 1252 BOOST_FOREACH_AUTO_OBJECT( \ 1253 BOOST_FOREACH_ID(_foreach_cur) \ 1254 , boost::foreach_detail_::begin(BOOST_FOREACH_ID(_foreach_col))) \ 1255 BOOST_FOREACH_AUTO_OBJECT( \ 1256 BOOST_FOREACH_ID(_foreach_end) \ 1257 , boost::foreach_detail_::end(BOOST_FOREACH_ID(_foreach_col))) \ 1258 for (bool BOOST_FOREACH_ID(_foreach_continue) = true; \ 1259 BOOST_FOREACH_ID(_foreach_continue) \ 1260 && BOOST_FOREACH_ID(_foreach_cur) != BOOST_FOREACH_ID(_foreach_end); \ 1261 BOOST_FOREACH_ID(_foreach_continue) \ 1262 ? (void)++BOOST_FOREACH_ID(_foreach_cur) : (void)0) \ 1263 if ( (BOOST_FOREACH_ID(_foreach_continue) = false) ) {} else \ 1264 for (VAR = *BOOST_FOREACH_ID(_foreach_cur); \ 1265 !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true) 1266 #else 1267 # define BOOST_FOREACH(VAR, COL) \ 1096 1268 BOOST_FOREACH_PREAMBLE() \ 1097 1269 if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \ 1098 1270 if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_BEGIN(COL)) {} else \ … … 1102 1274 BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_NEXT(COL) : (void)0) \ 1103 1275 if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \ 1104 1276 for (VAR = BOOST_FOREACH_DEREF(COL); !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true) 1277 #endif 1105 1278 1106 1279 /////////////////////////////////////////////////////////////////////////////// 1107 1280 // BOOST_REVERSE_FOREACH … … 1110 1283 // all other respects, BOOST_REVERSE_FOREACH is like 1111 1284 // BOOST_FOREACH. 1112 1285 // 1113 #define BOOST_REVERSE_FOREACH(VAR, COL) \ 1286 #ifdef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING 1287 # define BOOST_REVERSE_FOREACH(VAR, COL) \ 1288 BOOST_FOREACH_PREAMBLE() \ 1289 BOOST_FOREACH_AUTO_REF_REF( \ 1290 BOOST_FOREACH_ID(_foreach_col) \ 1291 , COL) \ 1292 BOOST_FOREACH_AUTO_OBJECT( \ 1293 BOOST_FOREACH_ID(_foreach_cur) \ 1294 , boost::foreach_detail_::rbegin(BOOST_FOREACH_ID(_foreach_col))) \ 1295 BOOST_FOREACH_AUTO_OBJECT( \ 1296 BOOST_FOREACH_ID(_foreach_end) \ 1297 , boost::foreach_detail_::rend(BOOST_FOREACH_ID(_foreach_col))) \ 1298 for (bool BOOST_FOREACH_ID(_foreach_continue) = true; \ 1299 BOOST_FOREACH_ID(_foreach_continue) \ 1300 && BOOST_FOREACH_ID(_foreach_cur) != BOOST_FOREACH_ID(_foreach_end); \ 1301 BOOST_FOREACH_ID(_foreach_continue) \ 1302 ? (void)++BOOST_FOREACH_ID(_foreach_cur) : (void)0) \ 1303 if ( (BOOST_FOREACH_ID(_foreach_continue) = false) ) {} else \ 1304 for (VAR = *BOOST_FOREACH_ID(_foreach_cur); \ 1305 !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true) 1306 #else 1307 # define BOOST_REVERSE_FOREACH(VAR, COL) \ 1114 1308 BOOST_FOREACH_PREAMBLE() \ 1115 1309 if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL)) {} else \ 1116 1310 if (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_cur) = BOOST_FOREACH_RBEGIN(COL)) {} else \ … … 1120 1314 BOOST_FOREACH_ID(_foreach_continue) ? BOOST_FOREACH_RNEXT(COL) : (void)0) \ 1121 1315 if (boost::foreach_detail_::set_false(BOOST_FOREACH_ID(_foreach_continue))) {} else \ 1122 1316 for (VAR = BOOST_FOREACH_RDEREF(COL); !BOOST_FOREACH_ID(_foreach_continue); BOOST_FOREACH_ID(_foreach_continue) = true) 1317 #endif 1123 1318 1124 1319 #endif