00001
00002 #ifndef _INSTIGATE_STL_INTERNAL_HEADER_IN_ALGORITHM
00003 #error This is an internal header file used to implement Instigate STL.\
00004 It should never be included directly by a program.
00005 #endif
00006
00007 #ifndef INSTIGATE_STL_SET_SYMMETRIC_DIFFERENCE_HPP
00008 #define INSTIGATE_STL_SET_SYMMETRIC_DIFFERENCE_HPP
00009
00059
00060 #include "concept.hpp"
00061 #include "_copy.hpp"
00062
00063
00064 #include <generic/base.hpp>
00065
00066
00067
00068
00069 namespace instigate {
00070 namespace stl {
00071 template <typename I, typename I1, typename O>
00072 O set_symmetric_difference(I b, I e, I1 f, I1 l, O r);
00073 template <typename I, typename I1, typename O, typename BP>
00074 O set_symmetric_difference(I b, I e, I1 f, I1 l, O r, BP p);
00075 }
00076 }
00077
00143 template <typename I, typename I1, typename O>
00144 O instigate::stl::set_symmetric_difference(I b, I e, I1 f, I1 l, O r)
00145 {
00146 namespace SP = instigate::stl::single_pass_iterator;
00147 namespace RI = instigate::stl::readable_iterator;
00148 namespace EQ = instigate::generic::equality_comparable;
00149 namespace LT = instigate::generic::less_than_comparable;
00150 namespace INC = instigate::stl::incrementable_iterator;
00151 namespace WR = instigate::stl::writable_iterator;
00152 CHECK(SP::requirements<I>);
00153 CHECK(RI::requirements<I>);
00154 CHECK(SP::requirements<I1>);
00155 CHECK(RI::requirements<I1>);
00156 CHECK(INC::requirements<O>);
00157 CHECK(WR::requirements<O>);
00158 typedef typename RI::interface<I>::value_type value_type1;
00159 typedef typename RI::interface<I1>::value_type value_type2;
00160 CHECK_SAME_TYPE(value_type1, value_type2);
00161 CHECK_CONVERTIBILITY(value_type1, value_type2);
00162 CHECK(LT::requirements<value_type1>);
00163 while (!equal(b, e) && !equal(f, l)) {
00164 if (less_than(const_dereference(b), const_dereference(f))) {
00165 dereference_assign(r, const_dereference(b));
00166 increment(b);
00167 increment(r);
00168 }
00169 else if (less_than(const_dereference(f),const_dereference(b)))
00170 {
00171 dereference_assign(r, const_dereference(f));
00172 increment(f);
00173 increment(r);
00174 } else {
00175 increment(b);
00176 increment(f);
00177 }
00178 }
00179 return instigate::stl::copy(f, l, instigate::stl::copy(b, e, r));
00180 }
00181
00236 template <typename I, typename I1, typename O, typename BP>
00237 O instigate::stl::set_symmetric_difference(I b, I e, I1 f, I1 l, O r, BP p)
00238 {
00239 namespace SP = instigate::stl::single_pass_iterator;
00240 namespace RI = instigate::stl::readable_iterator;
00241 namespace EQ = instigate::generic::equality_comparable;
00242 namespace LT = instigate::generic::less_than_comparable;
00243 namespace INC = instigate::stl::incrementable_iterator;
00244 namespace WR = instigate::stl::writable_iterator;
00245 namespace BPI = instigate::stl::binary_predicate;
00246 CHECK(SP::requirements<I>);
00247 CHECK(RI::requirements<I>);
00248 CHECK(SP::requirements<I1>);
00249 CHECK(RI::requirements<I1>);
00250 CHECK(INC::requirements<O>);
00251 CHECK(WR::requirements<O>);
00252 CHECK(BPI::requirements<BP>);
00253 typedef typename RI::interface<I>::value_type value_type1;
00254 typedef typename RI::interface<I1>::value_type value_type2;
00255 typedef typename WR::interface<O>::value_type value_type3;
00256 typedef typename BPI::interface<BP>::first_argument_type
00257 first_argument_type;
00258 typedef typename BPI::interface<BP>::second_argument_type
00259 second_argument_type;
00260 CHECK_SAME_TYPE(value_type1, value_type2);
00261 CHECK_CONVERTIBILITY(value_type1, value_type3);
00262 CHECK_CONVERTIBILITY(value_type2, value_type3);
00263 CHECK_CONVERTIBILITY(value_type1, first_argument_type);
00264 CHECK_CONVERTIBILITY(value_type2, second_argument_type);
00265 while (!equal(b, e) && !equal(f, l)) {
00266 if (invoke_predicate(p, const_dereference(b),
00267 const_dereference(f)))
00268 {
00269 dereference_assign(r, const_dereference(b));
00270 increment(b);
00271 increment(r);
00272 }
00273 else if (invoke_predicate(p, const_dereference(f),
00274 const_dereference(b)))
00275 {
00276 dereference_assign(r, const_dereference(f));
00277 increment(f);
00278 increment(r);
00279 } else {
00280 increment(b);
00281 increment(f);
00282 }
00283 }
00284 return instigate::stl::copy(f, l, instigate::stl::copy(b, e, r));
00285 }
00286
00287
00288
00289 #endif // INSTIGATE_STL_SET_SYMMETRIC_DIFFERENCE_HPP