Loading...
Searching...
No Matches
SceneGlob.hpp
1#pragma once
2#include <cstddef>
3#include <string_view>
4
5namespace Threedim
6{
7
8// Path glob of the scene nodes (Scene Graph Filter, Scene Selector,
9// Configure Primitive): `*` matches anything except `/`, `**` matches across
10// slashes, `?` matches a single non-slash character, everything else is
11// literal.
12inline bool scene_glob_match(std::string_view pattern, std::string_view text) noexcept
13{
14 constexpr auto npos = std::string_view::npos;
15 std::size_t pi = 0, ti = 0;
16 // Where to resume after a mismatch: the last `*`, which cannot eat a slash,
17 // and the last `**`, which a `*` stopped by a slash falls back to.
18 std::size_t star_pi = npos, star_ti = 0;
19 std::size_t dstar_pi = npos, dstar_ti = 0;
20
21 while(ti < text.size())
22 {
23 if(pi < pattern.size())
24 {
25 const char pc = pattern[pi];
26 if(pc == '*')
27 {
28 if(pi + 1 < pattern.size() && pattern[pi + 1] == '*')
29 {
30 pi += 2;
31 dstar_pi = pi;
32 dstar_ti = ti;
33 star_pi = npos;
34 }
35 else
36 {
37 pi += 1;
38 star_pi = pi;
39 star_ti = ti;
40 }
41 continue;
42 }
43 if(pc == '?' ? text[ti] != '/' : pc == text[ti])
44 {
45 ++pi;
46 ++ti;
47 continue;
48 }
49 }
50 if(star_pi != npos && text[star_ti] != '/')
51 {
52 pi = star_pi;
53 ti = ++star_ti;
54 continue;
55 }
56 if(dstar_pi != npos)
57 {
58 star_pi = npos;
59 pi = dstar_pi;
60 ti = ++dstar_ti;
61 continue;
62 }
63 return false;
64 }
65 while(pi < pattern.size() && pattern[pi] == '*')
66 ++pi;
67 return pi == pattern.size();
68}
69
70}