22
33namespace REL
44{
5- class Version
5+ template <typename T>
6+ class VersionBase
67 {
78 public:
89 using value_type = std::uint16_t ;
910 using reference = value_type&;
1011 using const_reference = const value_type&;
1112
12- constexpr Version () noexcept = default;
13+ constexpr VersionBase () noexcept = default;
1314
14- explicit constexpr Version (std::array<value_type, 4 > a_version) noexcept :
15+ explicit constexpr VersionBase (std::array<value_type, 4 > a_version) noexcept :
1516 _impl(a_version)
1617 {}
1718
18- constexpr Version (value_type a_v1, value_type a_v2 = 0 , value_type a_v3 = 0 , value_type a_v4 = 0 ) noexcept :
19+ constexpr VersionBase (value_type a_v1, value_type a_v2 = 0 , value_type a_v3 = 0 , value_type a_v4 = 0 ) noexcept :
1920 _impl{ a_v1, a_v2, a_v3, a_v4 }
2021 {}
2122
@@ -27,7 +28,7 @@ namespace REL
2728 [[nodiscard]] constexpr decltype (auto ) end() const noexcept { return _impl.end (); }
2829 [[nodiscard]] constexpr decltype (auto ) cend() const noexcept { return _impl.cend (); }
2930
30- [[nodiscard]] std::strong_ordering constexpr compare (const Version & a_rhs) const noexcept
31+ [[nodiscard]] std::strong_ordering constexpr compare (const VersionBase & a_rhs) const noexcept
3132 {
3233 for (std::size_t i = 0 ; i < _impl.size (); ++i) {
3334 if ((*this )[i] != a_rhs[i]) {
@@ -40,10 +41,10 @@ namespace REL
4041 [[nodiscard]] constexpr std::uint32_t pack () const noexcept
4142 {
4243 return static_cast <std::uint32_t >(
43- (_impl[0 ] & 0x00F ) << 28u |
44- (_impl[1 ] & 0xFFF ) << 16u |
45- (_impl[2 ] & 0xFFF ) << 4u |
46- (_impl[3 ] & 0x00F ) << 0u );
44+ (_impl[0 ] & T::AND_MAJOR ) << T::SHL_MAJOR |
45+ (_impl[1 ] & T::AND_MINOR ) << T::SHL_MINOR |
46+ (_impl[2 ] & T::AND_PATCH ) << T::SHL_PATCH |
47+ (_impl[3 ] & T::AND_BUILD ) << T::SHL_BUILD );
4748 }
4849
4950 [[nodiscard]] constexpr value_type major () const noexcept { return _impl[0 ]; }
@@ -73,22 +74,22 @@ namespace REL
7374 return result;
7475 }
7576
76- [[nodiscard]] static constexpr Version unpack (const std::uint32_t a_packedVersion) noexcept
77+ [[nodiscard]] static constexpr VersionBase unpack (const std::uint32_t a_packedVersion) noexcept
7778 {
78- return Version {
79- static_cast <value_type>((a_packedVersion >> 28 ) & 0x00F ),
80- static_cast <value_type>((a_packedVersion >> 16 ) & 0xFFF ),
81- static_cast <value_type>((a_packedVersion >> 4 ) & 0xFFF ),
82- static_cast <value_type>(a_packedVersion & 0x0F )
79+ return VersionBase {
80+ static_cast <value_type>((a_packedVersion >> T::SHL_MAJOR ) & T::AND_MAJOR ),
81+ static_cast <value_type>((a_packedVersion >> T::SHL_MINOR ) & T::AND_MINOR ),
82+ static_cast <value_type>((a_packedVersion >> T::SHL_PATCH ) & T::AND_PATCH ),
83+ static_cast <value_type>(( a_packedVersion >> T::SHL_BUILD) & T::AND_BUILD )
8384 };
8485 }
8586
86- [[nodiscard]] friend constexpr bool operator ==(const Version & a_lhs, const Version & a_rhs) noexcept
87+ [[nodiscard]] friend constexpr bool operator ==(const VersionBase & a_lhs, const VersionBase & a_rhs) noexcept
8788 {
8889 return a_lhs.compare (a_rhs) == 0 ;
8990 }
9091
91- [[nodiscard]] friend constexpr std::strong_ordering operator <=>(const Version & a_lhs, const Version & a_rhs) noexcept
92+ [[nodiscard]] friend constexpr std::strong_ordering operator <=>(const VersionBase & a_lhs, const VersionBase & a_rhs) noexcept
9293 {
9394 return a_lhs.compare (a_rhs);
9495 }
@@ -97,26 +98,40 @@ namespace REL
9798 std::array<value_type, 4 > _impl{ 0 , 0 , 0 , 0 };
9899 };
99100
101+ struct VersionPackInfo
102+ {
103+ static constexpr auto AND_MAJOR{ 0x0FF };
104+ static constexpr auto AND_MINOR{ 0x0FF };
105+ static constexpr auto AND_PATCH{ 0xFFF };
106+ static constexpr auto AND_BUILD{ 0x00F };
107+ static constexpr auto SHL_MAJOR{ 8 * 3 };
108+ static constexpr auto SHL_MINOR{ 8 * 2 };
109+ static constexpr auto SHL_PATCH{ 8 / 2 };
110+ static constexpr auto SHL_BUILD{ 8 * 0 };
111+ };
112+
113+ using Version = VersionBase<VersionPackInfo>;
114+
100115 [[nodiscard]] std::optional<Version> GetFileVersion (std::string_view a_filename);
101116 [[nodiscard]] std::optional<Version> GetFileVersion (std::wstring_view a_filename);
102117}
103118
104- template <class CharT >
105- struct std ::formatter<REL::Version , CharT> : formatter<std::string, CharT>
119+ template <typename T, class CharT >
120+ struct std ::formatter<REL::VersionBase<T> , CharT> : formatter<std::string, CharT>
106121{
107122 template <class FormatContext >
108- constexpr auto format (const REL::Version & a_version, FormatContext& a_ctx) const
123+ constexpr auto format (const REL::VersionBase<T> & a_version, FormatContext& a_ctx) const
109124 {
110125 return formatter<std::string, CharT>::format (a_version.string (), a_ctx);
111126 }
112127};
113128
114129#ifdef FMT_VERSION
115- template <class CharT >
116- struct fmt ::formatter<REL::Version , CharT> : formatter<std::string, CharT>
130+ template <typename T, class CharT >
131+ struct fmt ::formatter<REL::VersionBase<T> , CharT> : formatter<std::string, CharT>
117132{
118133 template <class FormatContext >
119- auto format (const REL::Version & a_version, FormatContext& a_ctx) const
134+ auto format (const REL::VersionBase<T> & a_version, FormatContext& a_ctx) const
120135 {
121136 return formatter<std::string, CharT>::format (a_version.string (), a_ctx);
122137 }
0 commit comments