Skip to content

Commit 9870f34

Browse files
authored
Merge pull request #55 from 5cript/feat/erase_range
Feat/erase range and MSVC Build Support
2 parents 10c74a5 + 2238185 commit 9870f34

File tree

10 files changed

+291
-82
lines changed

10 files changed

+291
-82
lines changed

.github/workflows/build_and_test.yml

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,40 @@ jobs:
4848
uses: actions/checkout@v2
4949

5050
- name: CMake Configure
51-
run: cmake -B ${{github.workspace}}/build -G"Ninja" -DINT_TREE_BUILD_EXAMPLES=on -DINT_TREE_ENABLE_TESTS=on -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} -DCMAKE_CXX_STANDARD=${{ matrix.cxx_standard }}
51+
run: cmake -B ${{github.workspace}}/build -G"Ninja" -DINT_TREE_USE_OPTIONAL_POLYFILL=on -DINT_TREE_BUILD_EXAMPLES=on -DINT_TREE_ENABLE_TESTS=on -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} -DCMAKE_CXX_STANDARD=${{ matrix.cxx_standard }}
5252

5353
- name: Build
5454
run: cmake --build ${{github.workspace}}/build
5555

5656
- name: Test
5757
working-directory: ${{github.workspace}}/build
58-
run: ./tests/tree-tests
58+
run: ./tests/tree-tests
59+
60+
msvc:
61+
runs-on: windows-latest
62+
steps:
63+
- name: Checkout
64+
uses: actions/checkout@v2
65+
66+
- name: Setup MSVC
67+
uses: microsoft/setup-msbuild@v1.0.2
68+
69+
- name: Install vcpkg and gtest
70+
run: |
71+
git clone https://github.com/microsoft/vcpkg.git
72+
.\vcpkg\bootstrap-vcpkg.bat
73+
.\vcpkg\vcpkg.exe install gtest
74+
shell: pwsh
75+
env:
76+
VCPKG_DEFAULT_TRIPLET: x64-windows
77+
78+
- name: CMake Configure
79+
run: cmake -B ${{github.workspace}}/build -G"Visual Studio 17 2022" -A x64 -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_CXX_STANDARD=20 -DINT_TREE_USE_OPTIONAL_POLYFILL=on -DINT_TREE_BUILD_EXAMPLES=on -DINT_TREE_ENABLE_TESTS=on -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
80+
81+
- name: Build
82+
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
83+
84+
- name: Test
85+
working-directory: ${{github.workspace}}/build
86+
run: .\tests\Release\tree-tests.exe
87+
shell: cmd

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ tests/obj
1717
tests/*.cbp
1818
tests/*.depend
1919
tests/*build_log.html
20-
tests/cairo-wrap
20+
tests/cairo-wrap
21+
22+
CMakeSettings.json

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ endif()
1414

1515
target_include_directories(interval-tree INTERFACE ./include)
1616

17+
if(${MSVC})
18+
target_compile_options(interval-tree INTERFACE /Zc:__cplusplus)
19+
endif()
20+
1721
if(INT_TREE_DRAW_EXAMPLES)
1822
add_subdirectory(cairo-wrap)
1923
add_subdirectory(drawings)

README.md

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ Options are:
182182
- [After deoverlap](#after-deoverlap)
183183
- [interval\_tree deoverlap\_copy()](#interval_tree-deoverlap_copy)
184184
- [interval\_tree punch(interval\_type const\& ival)](#interval_tree-punchinterval_type-const-ival)
185-
- [Before punching (closed\_adjacent intervals)](#before-punching-closed_adjacent-intervals)
185+
- [Before punching (closed intervals)](#before-punching-closed-intervals)
186186
- [After punching (with \[-10, 60\])](#after-punching-with--10-60)
187187
- [interval\_tree punch()](#interval_tree-punch)
188188
- [bool empty() const noexcept](#bool-empty-const-noexcept)
@@ -194,14 +194,16 @@ Options are:
194194
- [reverse\_iterator rend()](#reverse_iterator-rend)
195195
- [reverse\_iterator crbegin()](#reverse_iterator-crbegin)
196196
- [reverse\_iterator crend()](#reverse_iterator-crend)
197+
- [void erase\_range(interval\_type const\& ival)](#void-erase_rangeinterval_type-const-ival)
198+
- [void erase\_range(interval\_type const\& ival, bool retainSlices)](#void-erase_rangeinterval_type-const-ival-bool-retainslices)
197199
- [Members of Interval](#members-of-interval)
198200
- [using value\_type](#using-value_type)
199201
- [using interval\_kind](#using-interval_kind)
200202
- [friend bool operator==(interval const\& lhs, interval const\& other)](#friend-bool-operatorinterval-const-lhs-interval-const-other)
201203
- [friend bool operator!=(interval const\& lhs, interval const\& other)](#friend-bool-operatorinterval-const-lhs-interval-const-other-1)
202204
- [value\_type low() const](#value_type-low-const)
203205
- [value\_type high() const](#value_type-high-const)
204-
- [\[\[deprecated\]\] bool overlaps(value\_type l, value\_type h) const](#deprecated-bool-overlapsvalue_type-l-value_type-h-const)
206+
- [DEPRECATED bool overlaps(value\_type l, value\_type h) const](#deprecated-bool-overlapsvalue_type-l-value_type-h-const)
205207
- [bool overlaps\_exclusive(value\_type l, value\_type h) const](#bool-overlaps_exclusivevalue_type-l-value_type-h-const)
206208
- [bool overlaps(interval const\& other) const](#bool-overlapsinterval-const-other-const)
207209
- [bool overlaps\_exclusive(interval const\& other) const](#bool-overlaps_exclusiveinterval-const-other-const)
@@ -379,10 +381,10 @@ Open intervals with integral numbers will also not produce the gap (5, 6), becau
379381
`ival` can be any subrange of the tree, including encompassing the whole tree.
380382

381383
**Returns**: A new interval_tree containing the gaps.
382-
### Before punching (closed_adjacent intervals)
383-
![BeforePunch](https://private-user-images.githubusercontent.com/6238896/471147224-5c631e00-dea4-4b75-a3bf-6fdd8ec1440b.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTM1NjI1MzQsIm5iZiI6MTc1MzU2MjIzNCwicGF0aCI6Ii82MjM4ODk2LzQ3MTE0NzIyNC01YzYzMWUwMC1kZWE0LTRiNzUtYTNiZi02ZmRkOGVjMTQ0MGIucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDcyNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA3MjZUMjAzNzE0WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ZDQ0NWIwMTcwMjZhNDA1YmUwNGI1YTIzNTBhZTQ5OTNhMWFiOTU5ZmU0N2E3NDI0NTQ0MzYwODA4N2E2MGFiZiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.P5zLeXg0-9bd20Thj6pfq_WxriMn4GC_lDSLzzGKMbw)
384+
### Before punching (closed intervals)
385+
![BeforePunch](https://5cript.github.io/readme-images/interval-tree/punch_source.png)
384386
### After punching (with [-10, 60])
385-
![AfterPunch](https://private-user-images.githubusercontent.com/6238896/471147227-5c226d1d-d544-4a43-89a4-b3545145107d.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTM1NjI1MzQsIm5iZiI6MTc1MzU2MjIzNCwicGF0aCI6Ii82MjM4ODk2LzQ3MTE0NzIyNy01YzIyNmQxZC1kNTQ0LTRhNDMtODlhNC1iMzU0NTE0NTEwN2QucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDcyNiUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA3MjZUMjAzNzE0WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9NmE2ZDUzMjU2ZTNjZWQ0Y2QzYjQ3ZGUyYjgyNWM2NDViYTAxMTdlY2RjYmQyMzg4OWFmZDlhMWU5YjY4NjlmZCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.Infe9i281LDOEC5GeBFuLHVE6Xjqw7KvcUo-gv3hjpk)
387+
![AfterPunch](https://5cript.github.io/readme-images/interval-tree/punch_result.png)
386388

387389
---
388390
### interval_tree punch()
@@ -444,6 +446,12 @@ Returns a past the end const_iterator in reverse.
444446

445447
**Returns**: past the end const_iterator.
446448

449+
### void erase_range(interval_type const& ival)
450+
Removes all intervals overlapping ival from the tree
451+
452+
### void erase_range(interval_type const& ival, bool retainSlices)
453+
Removes all intervals overlapping ival from the tree, but retains the overlap beyond the erase interval.
454+
447455
## Members of Interval
448456
___You can implement your own interval if you provide the same functions, except (slice, operator-, size, operator!=).___
449457

@@ -465,7 +473,7 @@ Which can be picked with the second template parameter of interval:
465473
- [friend bool operator!=(interval const& lhs, interval const& other)](#friend-bool-operatorinterval-const-lhs-interval-const-other-1)
466474
- [value_type low() const](#value_type-low-const)
467475
- [value_type high() const](#value_type-high-const)
468-
- [\[\[deprecated\]\] bool overlaps(value_type l, value_type h) const](#bool-overlapsvalue_type-l-value_type-h-const)
476+
- [DEPRECATED bool overlaps(value_type l, value_type h) const](#bool-overlapsvalue_type-l-value_type-h-const)
469477
- [bool overlaps_exclusive(value_type l, value_type h) const](#bool-overlaps_exclusivevalue_type-l-value_type-h-const)
470478
- [bool overlaps(interval const& other) const](#bool-overlapsinterval-const-other-const)
471479
- [bool overlaps_exclusive(interval const& other) const](#bool-overlaps_exclusiveinterval-const-other-const)
@@ -474,6 +482,7 @@ Which can be picked with the second template parameter of interval:
474482
- [value_type operator-(interval const& other) const](#value_type-operator-interval-const-other-const)
475483
- [value_type size() const](#value_type-size-const)
476484
- [interval join(interval const& other) const](#interval-joininterval-const-other-const)
485+
- [slice\_type slice(interval const\& other) const](#slice_type-sliceinterval-const-other-const)
477486

478487
### using value_type
479488
The underlying interval numerical type
@@ -487,7 +496,7 @@ Comparison operator.
487496
Lower bound.
488497
### value_type high() const
489498
Upper bound.
490-
### \[\[deprecated\]\] bool overlaps(value_type l, value_type h) const
499+
### DEPRECATED bool overlaps(value_type l, value_type h) const
491500
Overlap these bounds with this interval?
492501
Is deprecated because the overlapping does not work with the dynamic interval type.
493502
### bool overlaps_exclusive(value_type l, value_type h) const
@@ -507,12 +516,14 @@ Overlapping intervals have 0 distance.
507516
Returns The amount of elements in the interval when integral, or the distance between the 2 bounds when floating point.
508517
### interval join(interval const& other) const
509518
Joins 2 intervals and whatever is inbetween.
510-
### slice_type<interval> slice(interval const& other) const
519+
### slice_type slice(interval const& other) const
511520
Removes other from this interval returning what is remaining.
512521
The range of other going beyond the range of this is ignored.
513522
Returns a struct with 2 members: left_slice and right_slice.
523+
```
514524
[ this interval ]
515525
[left][other][right]
526+
```
516527

517-
When the intervals are closed, adjacent results are differenty by 1.
528+
When the intervals are closed_adjacent, adjacent results are differenty by 1.
518529
[0, 9].slice([5, 19]) => left: [0, 4], right: nullopt

include/interval-tree/interval_tree.hpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,7 @@ namespace lib_interval_tree
11261126
* inserted with more overlap searches? If the result is a single interval shall it insert_overlap or insert?
11271127
* Be careful to not produce overlapping merge sets when doing recursive insertion, or it will recurse
11281128
* endlessly.
1129+
* @return An iterator to the inserted or merged interval.
11291130
*/
11301131
iterator insert_overlap(interval_type const& ival, bool exclusive = false, bool recursive = true)
11311132
{
@@ -1204,6 +1205,50 @@ namespace lib_interval_tree
12041205
return next;
12051206
}
12061207

1208+
/**
1209+
* @brief Erases all elements that overlap with ival, if retainSlices is true, the left and right overhanging
1210+
* parts are reinserted.
1211+
*
1212+
* ( i1 )
1213+
* ( i2 )
1214+
* ( erase )
1215+
* yields for retainSlices = true:
1216+
* (i1rest) (i2rest)
1217+
*
1218+
* Edge behavior depends on the interval type, or rather the slice implementation.
1219+
*
1220+
* @param ival The interval to erase.
1221+
* @param retainSlice If true, retains the non-overlapping parts of the intervals.
1222+
*/
1223+
template <typename interval_t = interval_type>
1224+
#ifdef LIB_INTERVAL_TREE_CONCEPTS
1225+
requires detail::has_slice<interval_t>
1226+
void
1227+
#else
1228+
typename std::enable_if<detail::has_slice<interval_t>, void>::type
1229+
#endif
1230+
erase_range(interval_t const& ival, bool retainSlices)
1231+
{
1232+
const auto iter = insert_overlap(ival, false, true);
1233+
if (!retainSlices)
1234+
{
1235+
erase(iter);
1236+
return;
1237+
}
1238+
1239+
const auto slices = iter->slice(ival);
1240+
erase(iter);
1241+
if (slices.left_slice)
1242+
insert(slices.left_slice.value());
1243+
if (slices.right_slice)
1244+
insert(slices.right_slice.value());
1245+
}
1246+
1247+
void erase_range(interval_type const& ival)
1248+
{
1249+
erase(insert_overlap(ival, false, true));
1250+
}
1251+
12071252
/**
12081253
* Returns the size of the object.
12091254
*/

include/interval-tree/optional.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ namespace lib_interval_tree
8787
template < \
8888
typename U, \
8989
typename... Args, \
90-
std::enable_if_t<std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value, int>...> \
90+
std::enable_if_t<std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value, int> = 0> \
9191
constexpr explicit optional_base(in_place_t, std::initializer_list<U> il, Args&&... args) \
9292
: value_(il, std::forward<Args>(args)...) \
9393
, engaged_{true} \

tests/CMakeLists.txt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,25 @@ file(GLOB sources "*.cpp")
1919
# Add Executable
2020
add_executable(tree-tests ${sources})
2121

22-
target_link_libraries(tree-tests PRIVATE gtest gmock interval-tree)
22+
find_package(GTest REQUIRED)
23+
24+
target_link_libraries(tree-tests PRIVATE interval-tree GTest::gtest GTest::gmock GTest::gmock_main)
2325

2426
# Compiler Options
2527
set(DEBUG_OPTIONS -fexceptions -g -Wall -pedantic-errors -pedantic)
2628
target_compile_options(tree-tests PUBLIC "$<$<CONFIG:DEBUG>:${DEBUG_OPTIONS}>")
2729

28-
set(RELEASE_OPTIONS -fexceptions -O3 -Wall -pedantic)
30+
if (${MSVC})
31+
set(WARNING_FLAGS -W4)
32+
else()
33+
set(WARNING_FLAGS -Wall)
34+
list(APPEND WARNING_FLAGS -Wextra)
35+
endif()
36+
set(RELEASE_OPTIONS -fexceptions -O3 ${WARNING_FLAGS} -pedantic)
2937
target_compile_options(tree-tests PUBLIC "$<$<CONFIG:RELEASE>:${RELEASE_OPTIONS}>")
3038

3139
if (INT_TREE_DRAW_EXAMPLES)
32-
target_link_libraries(tree-tests PRIVATE cairo cairo-wrap)
40+
target_link_libraries(tree-tests PRIVATE cairo-wrap cairo)
3341
endif()
3442

3543
# If msys2, copy dynamic libraries to executable directory, visual studio does this automatically.

0 commit comments

Comments
 (0)