Skip to content

Commit 11106f5

Browse files
committed
add c++20 std::format and operator <=>; include test cases
1 parent 1133a96 commit 11106f5

File tree

6 files changed

+95
-14
lines changed

6 files changed

+95
-14
lines changed

CMakeLists.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.14)
2-
project(semver LANGUAGES CXX VERSION 0.3.1)
2+
project(semver LANGUAGES CXX VERSION 0.3.3)
33

44
set(CMAKE_CXX_STANDARD 17)
55

@@ -16,13 +16,13 @@ include(GNUInstallDirs)
1616
## --------------------------------------------------------------------
1717
## Build
1818
## --------------------------------------------------------------------
19-
message(PROJECT_NAME: ${PROJECT_NAME})
20-
message(CMAKE_HOST_SYSTEM: ${CMAKE_HOST_SYSTEM})
21-
message(CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE})
22-
message(CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER})
23-
message(CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID})
24-
message(CMAKE_CXX_COMPILER_VERSION: ${CMAKE_CXX_COMPILER_VERSION})
25-
message(CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS})
19+
message(STATUS "PROJECT_NAME: ${PROJECT_NAME}")
20+
message(VERBOSE " CMAKE_HOST_SYSTEM: ${CMAKE_HOST_SYSTEM}")
21+
message(VERBOSE " CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
22+
message(VERBOSE " CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")
23+
message(VERBOSE " CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}")
24+
message(VERBOSE " CMAKE_CXX_COMPILER_VERSION: ${CMAKE_CXX_COMPILER_VERSION}")
25+
message(VERBOSE " CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
2626

2727
add_library(${PROJECT_NAME} INTERFACE)
2828
add_library (${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ provides the ability to **parse**, **compare**, and **increment** semantic versi
2929
FetchContent_Declare(
3030
cpp-semver
3131
GIT_REPOSITORY https://github.com/z4kn4fein/cpp-semver.git
32-
GIT_TAG v0.3.2)
32+
GIT_TAG v0.3.3)
3333
FetchContent_MakeAvailable(cpp-semver)
3434
```
3535

include/semver/semver.hpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,20 @@ SOFTWARE.
2525
#ifndef Z4KN4FEIN_SEMVER_H
2626
#define Z4KN4FEIN_SEMVER_H
2727

28+
#include <ostream>
2829
#include <string>
2930
#include <regex>
3031
#include <utility>
3132
#include <vector>
3233

34+
// conditionally include <format> and its dependency <string_view> for C++20
35+
#ifdef __cpp_lib_format
36+
#if __cpp_lib_format >= 201907L
37+
#include <format>
38+
#include <string_view>
39+
#endif
40+
#endif
41+
3342
namespace semver
3443
{
3544
const std::string default_prerelease_part = "0";
@@ -313,6 +322,17 @@ namespace semver
313322
return compare(other) != 0;
314323
}
315324

325+
// conditionally provide three-way operator for C++20
326+
#ifdef __cpp_impl_three_way_comparison
327+
#if __cpp_impl_three_way_comparison >= 201907L
328+
329+
auto operator<=>(const version& other) const {
330+
return compare(other);
331+
}
332+
333+
#endif
334+
#endif
335+
316336
static version parse(const std::string& version_str, bool strict = true) {
317337
std::regex regex(strict ? version_pattern : loose_version_pattern);
318338
std::cmatch match;
@@ -372,4 +392,19 @@ namespace semver
372392
}
373393
}
374394

395+
// conditionally provide formatter for C++20
396+
#ifdef __cpp_lib_format
397+
#if __cpp_lib_format >= 201907L
398+
399+
template <>
400+
struct std::formatter<semver::version> : std::formatter<std::string_view> {
401+
template <typename FormatContext>
402+
auto format(const semver::version& version, FormatContext& ctx) const {
403+
return std::formatter<std::string_view>::format(version.str(), ctx);
404+
}
405+
};
406+
407+
#endif
408+
#endif
409+
375410
#endif // Z4KN4FEIN_SEMVER_H

test/CMakeLists.txt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,17 @@ FetchContent_MakeAvailable(Catch2)
1212
list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras)
1313

1414
file(GLOB test-sources CONFIGURE_DEPENDS *.cpp)
15-
add_executable(${PROJECT_NAME}-tests "${test-sources}")
16-
17-
target_link_libraries(${PROJECT_NAME}-tests PRIVATE Catch2::Catch2WithMain ${PROJECT_NAME})
1815

1916
include(Catch)
20-
catch_discover_tests(${PROJECT_NAME}-tests)
17+
18+
# add c++17 tests
19+
add_executable(${PROJECT_NAME}-tests-17 "${test-sources}")
20+
set_target_properties(${PROJECT_NAME}-tests-17 PROPERTIES CXX_STANDARD 17)
21+
target_link_libraries(${PROJECT_NAME}-tests-17 PRIVATE Catch2::Catch2WithMain ${PROJECT_NAME})
22+
catch_discover_tests(${PROJECT_NAME}-tests-17)
23+
24+
# add c++17 tests
25+
add_executable(${PROJECT_NAME}-tests-20 "${test-sources}")
26+
set_target_properties(${PROJECT_NAME}-tests-20 PROPERTIES CXX_STANDARD 20)
27+
target_link_libraries(${PROJECT_NAME}-tests-20 PRIVATE Catch2::Catch2WithMain ${PROJECT_NAME})
28+
catch_discover_tests(${PROJECT_NAME}-tests-20)

test/compare.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ TEST_CASE("Test version compare, greater than, by prerelease", "[version][compar
5252
semver::version v = semver::version::parse("5.2.3-alpha.2");
5353
REQUIRE(v > semver::version::parse("5.2.3-alpha")); // by pre-release part count
5454
REQUIRE(v > semver::version::parse("5.2.3-alpha.1")); // by pre-release number comparison
55+
REQUIRE(v < semver::version::parse("5.2.3-alpha.11")); // by pre-release number comparison
5556
REQUIRE(v > semver::version::parse("5.2.3-a")); // by pre-release alphabetical comparison
5657
REQUIRE(v >= semver::version::parse("5.2.3-alpha.2"));
5758
}
@@ -64,4 +65,17 @@ TEST_CASE("Test version equality", "[version][compare]") {
6465
REQUIRE(semver::version::parse("0.0.0") == semver::version::parse("0.0.0"));
6566
REQUIRE(semver::version::parse("5.2.3-alpha.2+build.34") == semver::version::parse("5.2.3-alpha.2"));
6667
REQUIRE(semver::version::parse("5.2.3-alpha.2+build.34") == semver::version::parse("5.2.3-alpha.2+build.35"));
67-
}
68+
}
69+
70+
#ifdef __cpp_impl_three_way_comparison
71+
#if __cpp_impl_three_way_comparison >= 201907L
72+
73+
TEST_CASE("Test version 3-way compare", "[version][compare]") {
74+
semver::version v = semver::version::parse("5.2.3");
75+
REQUIRE((v <=> semver::version::parse("6.0.0")) < 0);
76+
REQUIRE((v <=> semver::version::parse("4.0.0")) > 0);
77+
REQUIRE((v <=> semver::version::parse("5.2.3")) == 0);
78+
}
79+
80+
#endif
81+
#endif

test/serialization.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <catch2/catch_all.hpp>
2+
#include <semver/semver.hpp>
3+
#include <sstream>
4+
5+
TEST_CASE("Test version std::ostream <<", "[version]") {
6+
semver::version v = semver::version::parse("5.2.3");
7+
std::stringstream ss;
8+
ss << v;
9+
REQUIRE(ss.str() == "5.2.3");
10+
}
11+
12+
#ifdef __cpp_lib_format
13+
#if __cpp_lib_format >= 201907L
14+
15+
TEST_CASE("Test version std::format formatter", "[version]") {
16+
REQUIRE(std::format("{}", semver::version::parse("5.2.3")) == "5.2.3");
17+
REQUIRE(std::format("{}", semver::version::parse("5.2.3-alpha")) == "5.2.3-alpha");
18+
REQUIRE(std::format("{}", semver::version::parse("5.2.3-1.2.3")) == "5.2.3-1.2.3");
19+
REQUIRE(std::format("{}", semver::version::parse("5.2.3-alpha+build34")) == "5.2.3-alpha+build34");
20+
REQUIRE(std::format("{}", semver::version::parse("5.2.3-1.2.3+build34")) == "5.2.3-1.2.3+build34");
21+
}
22+
23+
#endif
24+
#endif

0 commit comments

Comments
 (0)