Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:51

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2017-2017.
0004 // Distributed under the Boost Software License, Version 1.0.
0005 // (See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // See http://www.boost.org/libs/move for documentation.
0009 //
0010 //////////////////////////////////////////////////////////////////////////////
0011 #ifndef BOOST_MOVE_SET_DIFFERENCE_HPP
0012 #define BOOST_MOVE_SET_DIFFERENCE_HPP
0013 
0014 #include <boost/move/algo/move.hpp>
0015 #include <boost/move/iterator.hpp>
0016 #include <boost/move/utility_core.hpp>
0017 
0018 #if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600))
0019 #pragma GCC diagnostic push
0020 #pragma GCC diagnostic ignored "-Wsign-conversion"
0021 #endif
0022 
0023 namespace boost {
0024 namespace move_detail{
0025 
0026 template<class InputIt, class OutputIt>
0027 OutputIt copy(InputIt first, InputIt last, OutputIt result)
0028 {
0029    while (first != last) {
0030       *result++ = *first;
0031       ++result;
0032       ++first;
0033    }
0034    return result;
0035 }
0036 
0037 }  //namespace move_detail{
0038 
0039 namespace movelib {
0040 
0041 //Moves the elements from the sorted range [first1, last1) which are not found in the sorted
0042 //range [first2, last2) to the range beginning at result.
0043 //The resulting range is also sorted. Equivalent elements are treated individually,
0044 //that is, if some element is found m times in [first1, last1) and n times in [first2, last2),
0045 //it will be moved to result exactly max(m-n, 0) times.
0046 //The resulting range cannot overlap with either of the input ranges.
0047 template<class InputIt1, class InputIt2,
0048          class OutputIt, class Compare>
0049 OutputIt set_difference
0050    (InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt result, Compare comp)
0051 {
0052    while (first1 != last1) {
0053       if (first2 == last2)
0054          return boost::move_detail::copy(first1, last1, result);
0055 
0056       if (comp(*first1, *first2)) {
0057          *result = *first1;
0058          ++result;
0059          ++first1;
0060       }
0061       else {
0062          if (!comp(*first2, *first1)) {
0063             ++first1;
0064          }
0065          ++first2;
0066       }
0067    }
0068    return result;
0069 }
0070 
0071 //Moves the elements from the sorted range [first1, last1) which are not found in the sorted
0072 //range [first2, last2) to the range beginning at first1 (in place operation in range1).
0073 //The resulting range is also sorted. Equivalent elements are treated individually,
0074 //that is, if some element is found m times in [first1, last1) and n times in [first2, last2),
0075 //it will be moved to result exactly max(m-n, 0) times.
0076 template<class InputOutputIt1, class InputIt2, class Compare>
0077 InputOutputIt1 inplace_set_difference
0078    (InputOutputIt1 first1, InputOutputIt1 last1, InputIt2 first2, InputIt2 last2, Compare comp )
0079 {
0080    while (first1 != last1) {
0081       //Skip copying from range 1 if no element has to be skipped
0082       if (first2 == last2){
0083          return last1;
0084       }
0085       else if (comp(*first1, *first2)){
0086          ++first1;
0087       }
0088       else{
0089          if (!comp(*first2, *first1)) {
0090             InputOutputIt1 result = first1;
0091             //An element from range 1 must be skipped, no longer an inplace operation
0092             return boost::movelib::set_difference
0093                ( boost::make_move_iterator(++first1)
0094                , boost::make_move_iterator(last1)
0095                , ++first2, last2, result, comp);
0096          }
0097          ++first2;
0098       }
0099    }
0100    return first1;
0101 }
0102 
0103 //Moves the elements from the sorted range [first1, last1) which are not found in the sorted
0104 //range [first2, last2) to the range beginning at first1.
0105 //The resulting range is also sorted. Equivalent elements from range 1 are moved past to end
0106 //of the result,
0107 //that is, if some element is found m times in [first1, last1) and n times in [first2, last2),
0108 //it will be moved to result exactly max(m-n, 0) times.
0109 //The resulting range cannot overlap with either of the input ranges.
0110 template<class ForwardIt1, class InputIt2,
0111          class OutputIt, class Compare>
0112 OutputIt set_unique_difference
0113    (ForwardIt1 first1, ForwardIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt result, Compare comp)
0114 {
0115    while (first1 != last1) {
0116       if (first2 == last2){
0117          //unique_copy-like sequence with forward iterators but don't write i
0118          //to result before comparing as moving *i could alter the value in i.
0119          ForwardIt1 i = first1;
0120          while (++first1 != last1) {
0121             if (comp(*i, *first1)) {
0122                *result = *i;
0123                ++result;
0124                i = first1;
0125             }
0126          }
0127          *result = *i;
0128          ++result;
0129          break;
0130       }
0131 
0132       if (comp(*first1, *first2)) {
0133          //Skip equivalent elements in range1 but don't write i
0134          //to result before comparing as moving *i could alter the value in i.
0135          ForwardIt1 i = first1;
0136          while (++first1 != last1) {
0137             if (comp(*i, *first1)) {
0138                break;
0139             }
0140          }
0141          *result = *i;
0142          ++result;
0143       }
0144       else {
0145          if (comp(*first2, *first1)) {
0146             ++first2;
0147          }
0148          else{
0149             ++first1;
0150          }
0151       }
0152    }
0153    return result;
0154 }
0155 
0156 //Moves the elements from the sorted range [first1, last1) which are not found in the sorted
0157 //range [first2, last2) to the range beginning at first1 (in place operation in range1).
0158 //The resulting range is also sorted. Equivalent elements are treated individually,
0159 //that is, if some element is found m times in [first1, last1) and n times in [first2, last2),
0160 //it will be moved to result exactly max(m-n, 0) times.
0161 template<class ForwardOutputIt1, class ForwardIt2, class Compare>
0162 ForwardOutputIt1 inplace_set_unique_difference
0163    (ForwardOutputIt1 first1, ForwardOutputIt1 last1, ForwardIt2 first2, ForwardIt2 last2, Compare comp )
0164 {
0165    while (first1 != last1) {
0166       //Skip copying from range 1 if no element has to be skipped
0167       if (first2 == last2){
0168          //unique-like algorithm for the remaining range 1
0169          ForwardOutputIt1 result = first1;
0170          while (++first1 != last1) {
0171             if (comp(*result, *first1) && ++result != first1) {
0172                *result = boost::move(*first1);
0173             }
0174          }
0175          return ++result;
0176       }
0177       else if (comp(*first2, *first1)) {
0178          ++first2;
0179       }
0180       else if (comp(*first1, *first2)){
0181          //skip any adjacent equivalent element in range 1
0182          ForwardOutputIt1 result = first1;
0183          if (++first1 != last1 && !comp(*result, *first1)) {
0184             //Some elements from range 1 must be skipped, no longer an inplace operation
0185             while (++first1 != last1 && !comp(*result, *first1)){}
0186             return boost::movelib::set_unique_difference
0187                ( boost::make_move_iterator(first1)
0188                , boost::make_move_iterator(last1)
0189                , first2, last2, ++result, comp);
0190          }
0191       }
0192       else{
0193          ForwardOutputIt1 result = first1;
0194          //Some elements from range 1 must be skipped, no longer an inplace operation
0195          while (++first1 != last1 && !comp(*result, *first1)){}
0196          //An element from range 1 must be skipped, no longer an inplace operation
0197          return boost::movelib::set_unique_difference
0198             ( boost::make_move_iterator(first1)
0199             , boost::make_move_iterator(last1)
0200             , first2, last2, result, comp);
0201       }
0202    }
0203    return first1;
0204 }
0205 
0206 #if defined(BOOST_CLANG) || (defined(BOOST_GCC) && (BOOST_GCC >= 40600))
0207 #pragma GCC diagnostic pop
0208 #endif
0209 
0210 }  //namespace movelib {
0211 }  //namespace boost {
0212 
0213 #endif   //#define BOOST_MOVE_SET_DIFFERENCE_HPP