ifm3d
semver.h
1 // -*- c++ -*-
2 /*
3  * Copyright 2022 ifm electronic, gmbh
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef IFM3D_DEVICE_SEMVER_H
8 #define IFM3D_DEVICE_SEMVER_H
9 
10 #include <fmt/format.h>
11 #include <ifm3d/device/module_device.h>
12 #include <iostream>
13 #include <optional>
14 #include <string>
15 
16 namespace ifm3d
17 {
19  struct IFM3D_EXPORT SemVer
20  {
21  SemVer(size_t major,
22  size_t minor,
23  size_t patch,
24  const std::optional<std::string>& prerelease = std::nullopt,
25  const std::optional<std::string>& build_meta = std::nullopt)
26  : major_num(major),
27  minor_num(minor),
28  patch_num(patch),
29  prerelease(prerelease),
30  build_meta(build_meta)
31 
32  {}
33 
34  size_t major_num;
35  size_t minor_num;
36  size_t patch_num;
37  std::optional<std::string> prerelease;
38  std::optional<std::string> build_meta;
39 
40  constexpr bool
41  operator<(const SemVer& rhs) const
42  {
43  // Note: sorting by prerelease is not implemented as it's not needed for
44  // our usecase
45  return major_num < rhs.major_num ||
46  (major_num == rhs.major_num &&
47  (minor_num < rhs.minor_num ||
48  (minor_num == rhs.minor_num && (patch_num < rhs.patch_num))));
49  }
50 
51  constexpr bool
52  operator==(const SemVer& rhs) const
53  {
54  return ((major_num == rhs.major_num) && (minor_num == rhs.minor_num) &&
55  (patch_num == rhs.patch_num) && (prerelease == rhs.prerelease) &&
56  (build_meta == rhs.build_meta));
57  }
58 
59  constexpr bool
60  operator!=(const SemVer& rhs) const
61  {
62  return !(*this == rhs);
63  }
64 
65  constexpr bool
66  operator>=(const SemVer& rhs) const
67  {
68  return !(*this < rhs);
69  }
70 
71  constexpr bool
72  operator>(const SemVer& rhs) const
73  {
74  return rhs < *this;
75  }
76 
77  constexpr bool
78  operator<=(const SemVer& rhs) const
79  {
80  return !(rhs < *this);
81  }
82 
83  [[nodiscard]] std::string
84  ToString() const
85  {
86  std::string version = std::to_string(major_num) + "." +
87  std::to_string(minor_num) + "." +
88  std::to_string(patch_num);
89 
90  if (prerelease.has_value())
91  {
92  version += "-" + prerelease.value();
93  }
94 
95  if (build_meta.has_value())
96  {
97  version += "+" + build_meta.value();
98  }
99 
100  return version;
101  }
102 
103  /* To support fmt ostream */
104  friend std::ostream&
105  operator<<(std::ostream& os, const SemVer& version)
106  {
107  return os << version.ToString();
108  }
109 
110  static std::optional<SemVer> Parse(const std::string& version_string);
111  };
112 } // end: namespace ifm3d
113 
114 template <>
115 struct fmt::formatter<ifm3d::SemVer> : fmt::formatter<std::string_view>
116 {
117  auto
118  format(const ifm3d::SemVer& version, format_context& ctx) const
119  {
120  const auto value = version.ToString();
121  return fmt::formatter<std::string_view>::format(value, ctx);
122  }
123 };
124 
125 #endif // IFM3D_DEVICE_SEMVER_H
Definition: semver.h:20