libDwm-0.9.45
DwmDiff.hh
Go to the documentation of this file.
1//===========================================================================
2// @(#) $DwmPath: dwm/libDwm/trunk/include/DwmDiff.hh 10303 $
3//===========================================================================
4// Copyright (c) Daniel W. McRobb 2016, 2019, 2020
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions
9// are met:
10//
11// 1. Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// 2. Redistributions in binary form must reproduce the above copyright
14// notice, this list of conditions and the following disclaimer in the
15// documentation and/or other materials provided with the distribution.
16// 3. The names of the authors and copyright holders may not be used to
17// endorse or promote products derived from this software without
18// specific prior written permission.
19//
20// IN NO EVENT SHALL DANIEL W. MCROBB BE LIABLE TO ANY PARTY FOR
21// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
22// INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE,
23// EVEN IF DANIEL W. MCROBB HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
24// DAMAGE.
25//
26// THE SOFTWARE PROVIDED HEREIN IS ON AN "AS IS" BASIS, AND
27// DANIEL W. MCROBB HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
28// UPDATES, ENHANCEMENTS, OR MODIFICATIONS. DANIEL W. MCROBB MAKES NO
29// REPRESENTATIONS AND EXTENDS NO WARRANTIES OF ANY KIND, EITHER
30// IMPLIED OR EXPRESS, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31// WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
32// OR THAT THE USE OF THIS SOFTWARE WILL NOT INFRINGE ANY PATENT,
33// TRADEMARK OR OTHER RIGHTS.
34//===========================================================================
35
36//---------------------------------------------------------------------------
39//---------------------------------------------------------------------------
40
41#ifndef _DWMDIFF_HH_
42#define _DWMDIFF_HH_
43
44#include <algorithm>
45#include <type_traits>
46
47namespace Dwm {
48
49 //--------------------------------------------------------------------------
57 //--------------------------------------------------------------------------
58 template <class InputIt1, class InputIt2, class OutputCont>
59 void Diff(InputIt1 first1, InputIt1 last1,
60 InputIt2 first2, InputIt2 last2,
61 OutputCont & in1not2, OutputCont & in2not1)
62 {
63 using in1ItCat =
64 typename std::iterator_traits<InputIt1>::iterator_category;
65 static_assert(std::is_convertible_v<in1ItCat, std::input_iterator_tag>,
66 "InputIt1 must be an input iterator");
67 using in2ItCat =
68 typename std::iterator_traits<InputIt2>::iterator_category;
69 static_assert(std::is_convertible_v<in2ItCat, std::input_iterator_tag>,
70 "InputIt2 must be an input iterator");
71
72 // xxx: Until C++20 Concepts, we don't have a great way to check
73 // that OutputCont iterators meet the requirements of
74 // LegacyOutputIterator. But since we're going to construct a
75 // std::inserter, we can at least check that it is in output iterator.
76 // This is really a placeholder 'til we have something more sane.
77 using outItCat =
78 typename std::iterator_traits<decltype(std::inserter<OutputCont>(in1not2, in1not2.end()))>::iterator_category;
79 static_assert(std::is_convertible_v<outItCat, std::output_iterator_tag>,
80 "OutputCont::iterator does not meet requirements of"
81 " LegacyOutputIterator");
82
83 // Populate in1not2 with elements from [first1,last1) that are not
84 // found in [first2,last2)
85 set_difference(first1, last1, first2, last2,
86 std::inserter(in1not2, in1not2.end()));
87 // Populate in2not1 with elements from [first2,last2) that are not
88 // found in [first1,last1)
89 set_difference(first2, last2, first1, last1,
90 std::inserter(in2not1, in2not1.end()));
91 return;
92 }
93
94 //--------------------------------------------------------------------------
102 //--------------------------------------------------------------------------
103 template <class InputIt1, class InputIt2, class OutputCont, class Compare>
104 void Diff(InputIt1 first1, InputIt1 last1,
105 InputIt2 first2, InputIt2 last2,
106 OutputCont & in1not2, OutputCont & in2not1, Compare comp)
107 {
108 using in1ItCat =
109 typename std::iterator_traits<InputIt1>::iterator_category;
110 using in2ItCat =
111 typename std::iterator_traits<InputIt2>::iterator_category;
112 static_assert(std::is_convertible_v<in1ItCat, std::input_iterator_tag>,
113 "InputIt1 must be an input iterator");
114 static_assert(std::is_convertible_v<in2ItCat, std::input_iterator_tag>,
115 "InputIt2 must be an input iterator");
116 // xxx: Until C++20 Concepts, we don't have a great way to check
117 // that OutputCont iterators meet the requirements of
118 // LegacyOutputIterator. But since we're going to construct a
119 // std::inserter, we can at least check that it is in output iterator.
120 // This is really a placeholder 'til we have something more sane.
121 using outItCat =
122 typename std::iterator_traits<decltype(std::inserter<OutputCont>(in1not2, in1not2.end()))>::iterator_category;
123 static_assert(std::is_convertible_v<outItCat, std::output_iterator_tag>,
124 "OutputCont::iterator does not meet requirements of"
125 " LegacyOutputIterator");
126
127 // Populate in1not2 with elements from [first1,last1) that are not
128 // found in [first2,last2)
129 set_difference(first1, last1, first2, last2,
130 std::inserter(in1not2, in1not2.end()));
131 // Populate in2not1 with elements from [first2,last2) that are not
132 // found in [first1,last1)
133 set_difference(first2, last2, first1, last1,
134 std::inserter(in2not1, in2not1.end()));
135 return;
136 }
137
138 //--------------------------------------------------------------------------
145 //--------------------------------------------------------------------------
146 template <class InputCont, class OutputCont>
147 void Diff(const InputCont & in1, const InputCont & in2,
148 OutputCont & in1not2, OutputCont & in2not1)
149 {
150 return Diff(in1.begin(), in1.end(), in2.begin(), in2.end(),
151 in1not2, in2not1);
152 }
153
154 //--------------------------------------------------------------------------
162 //--------------------------------------------------------------------------
163 template <class InputCont, class OutputCont, class Compare>
164 void Diff(const InputCont & in1, const InputCont & in2,
165 OutputCont & in1not2, OutputCont & in2not1, Compare comp)
166 {
167 return Diff(in1.begin(), in1.end(), in2.begin(), in2.end(),
168 in1not2, in2not1, comp);
169 }
170
171} // namespace Dwm
172
173#endif // _DWMDIFF_HH_
void Diff(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputCont &in1not2, OutputCont &in2not1)
Copies elements from the sorted range [first1,last1) which are not found in the sorted range [first2,...
Definition DwmDiff.hh:59