Sharg 1.1.2-rc.1
The argument parser for bio-c++ tools.
Loading...
Searching...
No Matches
id_pair.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2006-2024, Knut Reinert & Freie Universität Berlin
2// SPDX-FileCopyrightText: 2016-2024, Knut Reinert & MPI für molekulare Genetik
3// SPDX-License-Identifier: BSD-3-Clause
4
10#pragma once
11
12#include <algorithm>
13#include <string>
14#include <unordered_set>
15
16#include <sharg/platform.hpp>
17
18namespace sharg::detail
19{
20
24struct id_pair
25{
26 char short_id{};
27 std::string long_id{};
28
29 id_pair() = default;
30 id_pair(id_pair const &) = default;
31 id_pair & operator=(id_pair const &) = default;
32 id_pair(id_pair &&) = default;
33 id_pair & operator=(id_pair &&) = default;
34 ~id_pair() = default;
35
37 id_pair(char const short_id) : short_id{short_id}
38 {}
39
41 id_pair(std::string long_id) : long_id{std::move(long_id)}
42 {}
43
45 id_pair(char const short_id, std::string long_id) : short_id{short_id}, long_id{std::move(long_id)}
46 {}
47
51 friend bool operator==(id_pair const & lhs, id_pair const & rhs)
52 {
53 return (!lhs.empty_short_id() && lhs.short_id == rhs.short_id)
54 || (!lhs.empty_long_id() && lhs.long_id == rhs.long_id);
55 }
56
60 friend bool operator==(id_pair const & lhs, char const & rhs)
61 {
62 return !lhs.empty_short_id() && lhs.short_id == rhs;
63 }
64
68 friend bool operator==(id_pair const & lhs, std::string const & rhs)
69 {
70 return !lhs.empty_long_id() && lhs.long_id == rhs;
71 }
72
74 bool empty_short_id() const noexcept
75 {
76 return empty(short_id);
77 }
78
80 bool empty_long_id() const noexcept
81 {
82 return empty(long_id);
83 }
84
86 bool empty() const noexcept
87 {
88 return empty_short_id() && empty_long_id();
89 }
90
92 template <typename id_type>
93 static bool empty(id_type const & id) noexcept;
94
95 // Note: The following two functions are declared, but not defined.
96 // We first need to specialise std::hash<id_pair> in the std namespace.
97 // After that, we can define the functions.
98 // Defining them here would generate std::hash<id_pair> before the specialisation.
99 // 1.) Now there are two specialisations for std::hash<id_pair> (error)
100 // 2.) The default-generated std::hash<id_pair> does actually not work
101
103 template <typename id_type>
104 static auto find(std::unordered_set<id_pair> const & used_ids, id_type const & id);
105
107 template <typename id_type>
108 static bool contains(std::unordered_set<id_pair> const & used_ids, id_type const & id);
109};
110
111} // namespace sharg::detail
112
113namespace std
114{
115
119template <>
120struct hash<sharg::detail::id_pair>
121{
123 size_t operator()(sharg::detail::id_pair const & value) const noexcept
124 {
125 size_t const h1 = std::hash<char>{}(value.short_id);
126 size_t const h2 = std::hash<std::string>{}(value.long_id);
127 return h1 ^ (h2 << 1);
128 }
129};
130
131} // namespace std
132
133namespace sharg::detail
134{
135
136template <typename id_type>
137inline bool id_pair::empty(id_type const & id) noexcept
138{
139 if constexpr (std::same_as<id_type, id_pair>)
140 return id.empty();
141 else if constexpr (std::same_as<id_type, char>)
142 return id == '\0';
143 else
144 return id.empty();
145}
146
147template <typename id_type>
148inline auto id_pair::find(std::unordered_set<id_pair> const & used_ids, id_type const & id)
149{
150 if (empty(id))
151 return used_ids.end();
152
153 return std::ranges::find_if(used_ids,
154 [&id](id_pair const & pair)
155 {
156 return pair == id;
157 });
158}
159
160template <typename id_type>
161inline bool id_pair::contains(std::unordered_set<id_pair> const & used_ids, id_type const & id)
162{
163 return find(used_ids, id) != used_ids.end();
164}
165
166} // namespace sharg::detail
T empty(T... args)
T end(T... args)
T find(T... args)
T is_same_v
T move(T... args)
T operator()(T... args)
Provides platform and dependency checks.
Hide me