Skip to content

Commit 0b61b9d

Browse files
committed
add version_duplet::operator< and >=
1 parent d5079c3 commit 0b61b9d

4 files changed

Lines changed: 169 additions & 91 deletions

File tree

src/utki/utility.hpp

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -620,66 +620,4 @@ is_cin_terminal()
620620
return is_terminal_cin();
621621
}
622622

623-
/**
624-
* @brief Version duplet.
625-
*/
626-
struct version_duplet {
627-
/**
628-
* @brief Major version.
629-
*/
630-
uint16_t major;
631-
632-
/**
633-
* @brief Minor version.
634-
*/
635-
uint16_t minor;
636-
637-
/**
638-
* @brief Combine major and minor versions into one number.
639-
*/
640-
constexpr uint32_t to_uint32_t() const noexcept
641-
{
642-
return uint32_t(uint32_t(this->major) << sizeof(uint16_t) * utki::byte_bits) | uint32_t(this->minor);
643-
}
644-
645-
friend std::ostream& operator<<(std::ostream& o, const version_duplet& vd)
646-
{
647-
return o << vd.major << '.' << vd.minor;
648-
}
649-
};
650-
651-
/**
652-
* @brief Version triplet.
653-
* Version of the form "MAJOR.MINOR.REVISON".
654-
*/
655-
struct version_triplet {
656-
/**
657-
* @brief Version duplet.
658-
* Major and minor versions.
659-
*/
660-
version_duplet duplet;
661-
662-
/**
663-
* @brief Revision.
664-
*/
665-
uint32_t revision;
666-
667-
/**
668-
* @brief Parse version triplet from string.
669-
* The input string is supposed to contain version triplet at its beginning.
670-
* Parsing will stop on the first character right after the version triplet, or at the end of the string.
671-
* @param str - string to parse.
672-
* @return Parsed version triplet.
673-
* @throw std::invalid_argument in case input string does not represent a version triplet.
674-
*/
675-
version_triplet from(std::string_view str);
676-
// TODO: implement
677-
678-
// TODO: add stream output operator
679-
680-
// TODO: add unit tests
681-
682-
// TODO: move out to version.hpp
683-
};
684-
685623
} // namespace utki

src/utki/version.hpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
The MIT License (MIT)
3+
4+
utki - Utility Kit for C++.
5+
6+
Copyright (c) 2015-2025 Ivan Gagis <igagis@gmail.com>
7+
8+
Permission is hereby granted, free of charge, to any person obtaining a copy
9+
of this software and associated documentation files (the "Software"), to deal
10+
in the Software without restriction, including without limitation the rights
11+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
copies of the Software, and to permit persons to whom the Software is
13+
furnished to do so, subject to the following conditions:
14+
15+
The above copyright notice and this permission notice shall be included in all
16+
copies or substantial portions of the Software.
17+
18+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
SOFTWARE.
25+
*/
26+
27+
/* ================ LICENSE END ================ */
28+
29+
#pragma once
30+
31+
#include <cstdint>
32+
#include <ostream>
33+
34+
#include "type_traits.hpp"
35+
36+
namespace utki {
37+
/**
38+
* @brief Version duplet.
39+
*/
40+
struct version_duplet {
41+
/**
42+
* @brief Major version.
43+
*/
44+
uint16_t major;
45+
46+
/**
47+
* @brief Minor version.
48+
*/
49+
uint16_t minor;
50+
51+
/**
52+
* @brief Combine major and minor versions into one number.
53+
*/
54+
constexpr uint32_t to_uint32_t() const noexcept
55+
{
56+
return uint32_t(uint32_t(this->major) << sizeof(uint16_t) * utki::byte_bits) | uint32_t(this->minor);
57+
}
58+
59+
friend std::ostream& operator<<(std::ostream& o, const version_duplet& vd)
60+
{
61+
return o << vd.major << '.' << vd.minor;
62+
}
63+
64+
friend bool operator>=(const version_duplet& lhs, const version_duplet& rhs) noexcept
65+
{
66+
if (lhs.major > rhs.major) {
67+
return true;
68+
}
69+
if (lhs.major == rhs.major && lhs.minor >= rhs.minor) {
70+
return true;
71+
}
72+
return false;
73+
}
74+
75+
friend bool operator<(const version_duplet& lhs, const version_duplet& rhs) noexcept
76+
{
77+
return !(lhs >= rhs);
78+
}
79+
};
80+
81+
/**
82+
* @brief Version triplet.
83+
* Version of the form "MAJOR.MINOR.REVISON".
84+
*/
85+
struct version_triplet {
86+
/**
87+
* @brief Version duplet.
88+
* Major and minor versions.
89+
*/
90+
version_duplet duplet;
91+
92+
/**
93+
* @brief Revision.
94+
*/
95+
uint32_t revision;
96+
97+
/**
98+
* @brief Parse version triplet from string.
99+
* The input string is supposed to contain version triplet at its beginning.
100+
* Parsing will stop on the first character right after the version triplet, or at the end of the string.
101+
* @param str - string to parse.
102+
* @return Parsed version triplet.
103+
* @throw std::invalid_argument in case input string does not represent a version triplet.
104+
*/
105+
version_triplet from(std::string_view str);
106+
// TODO: implement
107+
108+
// TODO: add stream output operator
109+
110+
// TODO: add unit tests
111+
112+
// TODO: move out to version.hpp
113+
};
114+
115+
} // namespace utki

tests/unit/src/utility.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -265,35 +265,6 @@ const tst::set set("util", [](tst::suite& suite) {
265265
tst::check(result == expected, SL);
266266
});
267267

268-
suite.add("version_duplet__to_uint32_t", []() {
269-
utki::version_duplet dp = {10, 20};
270-
271-
tst::check_eq(dp.to_uint32_t(), utki::version_duplet{10, 20}.to_uint32_t(), SL);
272-
273-
tst::check_ne(dp.to_uint32_t(), utki::version_duplet{11, 20}.to_uint32_t(), SL);
274-
tst::check_ne(dp.to_uint32_t(), utki::version_duplet{10, 21}.to_uint32_t(), SL);
275-
tst::check_ne(dp.to_uint32_t(), utki::version_duplet{11, 21}.to_uint32_t(), SL);
276-
277-
tst::check_lt(dp.to_uint32_t(), utki::version_duplet{11, 20}.to_uint32_t(), SL);
278-
tst::check_lt(dp.to_uint32_t(), utki::version_duplet{10, 21}.to_uint32_t(), SL);
279-
tst::check_lt(dp.to_uint32_t(), utki::version_duplet{11, 21}.to_uint32_t(), SL);
280-
281-
tst::check_le(dp.to_uint32_t(), utki::version_duplet{11, 20}.to_uint32_t(), SL);
282-
tst::check_le(dp.to_uint32_t(), utki::version_duplet{10, 21}.to_uint32_t(), SL);
283-
tst::check_le(dp.to_uint32_t(), utki::version_duplet{11, 21}.to_uint32_t(), SL);
284-
tst::check_le(dp.to_uint32_t(), utki::version_duplet{10, 20}.to_uint32_t(), SL);
285-
});
286-
287-
suite.add("version_duplet__operator_stream_output", []() {
288-
utki::version_duplet dp = {10, 20};
289-
290-
std::stringstream ss;
291-
292-
ss << dp;
293-
294-
tst::check_eq(ss.str(), "10.20"s, SL);
295-
});
296-
297268
suite.add("contains__vector", []() {
298269
std::vector<std::string> v = {"aaa", "bbb", "ccc"};
299270

tests/unit/src/version.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include <tst/check.hpp>
2+
#include <tst/set.hpp>
3+
#include <utki/version.hpp>
4+
5+
using namespace std::string_literals;
6+
7+
namespace {
8+
const tst::set set("version", [](tst::suite& suite) {
9+
suite.add("version_duplet__to_uint32_t", []() {
10+
utki::version_duplet dp = {10, 20};
11+
12+
tst::check_eq(dp.to_uint32_t(), utki::version_duplet{10, 20}.to_uint32_t(), SL);
13+
14+
tst::check_ne(dp.to_uint32_t(), utki::version_duplet{11, 20}.to_uint32_t(), SL);
15+
tst::check_ne(dp.to_uint32_t(), utki::version_duplet{10, 21}.to_uint32_t(), SL);
16+
tst::check_ne(dp.to_uint32_t(), utki::version_duplet{11, 21}.to_uint32_t(), SL);
17+
18+
tst::check_lt(dp.to_uint32_t(), utki::version_duplet{11, 20}.to_uint32_t(), SL);
19+
tst::check_lt(dp.to_uint32_t(), utki::version_duplet{10, 21}.to_uint32_t(), SL);
20+
tst::check_lt(dp.to_uint32_t(), utki::version_duplet{11, 21}.to_uint32_t(), SL);
21+
22+
tst::check_le(dp.to_uint32_t(), utki::version_duplet{11, 20}.to_uint32_t(), SL);
23+
tst::check_le(dp.to_uint32_t(), utki::version_duplet{10, 21}.to_uint32_t(), SL);
24+
tst::check_le(dp.to_uint32_t(), utki::version_duplet{11, 21}.to_uint32_t(), SL);
25+
tst::check_le(dp.to_uint32_t(), utki::version_duplet{10, 20}.to_uint32_t(), SL);
26+
});
27+
28+
suite.add("version_duplet__operator_stream_output", []() {
29+
utki::version_duplet dp = {10, 20};
30+
31+
std::stringstream ss;
32+
33+
ss << dp;
34+
35+
tst::check_eq(ss.str(), "10.20"s, SL);
36+
});
37+
38+
suite.add("operator_greater_or_equal", []() {
39+
tst::check(utki::version_duplet{1, 2} >= utki::version_duplet{1, 1}, SL);
40+
tst::check(utki::version_duplet{1, 2} >= utki::version_duplet{1, 2}, SL);
41+
tst::check(!(utki::version_duplet{1, 2} >= utki::version_duplet{1, 3}), SL);
42+
tst::check(utki::version_duplet{2, 0} >= utki::version_duplet{1, 9}, SL);
43+
tst::check(utki::version_duplet{2, 0} >= utki::version_duplet{0, 9}, SL);
44+
});
45+
46+
suite.add("operator_less", []() {
47+
tst::check(!(utki::version_duplet{1, 2} < utki::version_duplet{1, 1}), SL);
48+
tst::check(!(utki::version_duplet{1, 2} < utki::version_duplet{1, 2}), SL);
49+
tst::check(utki::version_duplet{1, 2} < utki::version_duplet{1, 3}, SL);
50+
tst::check(!(utki::version_duplet{2, 0} < utki::version_duplet{1, 9}), SL);
51+
tst::check(!(utki::version_duplet{2, 0} < utki::version_duplet{0, 9}), SL);
52+
});
53+
});
54+
} // namespace

0 commit comments

Comments
 (0)