File indexing completed on 2024-12-29 04:50:10

0001 /*
0002     SPDX-FileCopyrightText: 2018 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include <cmath>
0010 #include <cstdint>
0011 
0012 namespace KItinerary {
0013 
0014 /** Lookup functions, utilities and data types for the static knowledge database.
0015  *  The content accessible by this functions is extracted from Wikidata and compiled
0016  *  into this library.
0017  *  @note The types in this namespace match the binary storage structure and thus
0018  *  are not intended for use in binary compatible APIs.
0019  */
0020 namespace KnowledgeDb
0021 {
0022 
0023 /** Geographical coordinate.
0024  *  This matches the binary data layout on disk, it's not intended
0025  *  for use in API.
0026  */
0027 struct Coordinate {
0028     inline constexpr Coordinate()
0029         : longitude(NAN)
0030         , latitude(NAN)
0031     {
0032     }
0033 
0034     inline explicit constexpr Coordinate(float lng, float lat)
0035         : longitude(lng)
0036         , latitude(lat)
0037     {
0038     }
0039 
0040     inline bool isValid() const
0041     {
0042         return !std::isnan(latitude) && !std::isnan(longitude);
0043     }
0044 
0045     inline constexpr bool operator==(Coordinate other) const
0046     {
0047         return latitude == other.latitude && longitude == other.longitude;
0048     }
0049 
0050     float longitude;
0051     float latitude;
0052 };
0053 
0054 /** Unalinged storage of a numerical value.
0055  *  This is optimized for a compact memory layout, at the expense of slightly more
0056  *  expensive comparison operations.
0057  *  @tparam N the size in byte, at this point limited to at most 4
0058  */
0059 template <int N> class UnalignedNumber : private UnalignedNumber<N-1> {
0060 public:
0061     inline constexpr UnalignedNumber() = default;
0062     inline explicit constexpr UnalignedNumber(uint32_t num)
0063         : UnalignedNumber<N-1>(num)
0064         , m_value((num & (0xFF << (N-1)*8)) >> (N-1)*8)
0065     {}
0066 
0067     inline constexpr bool operator==(UnalignedNumber<N> other) const
0068     {
0069         if (m_value == other.m_value) {
0070             return UnalignedNumber<N-1>::operator==(other);
0071         }
0072         return false;
0073     }
0074     inline constexpr bool operator!=(UnalignedNumber<N> other) const
0075     {
0076         if (m_value == other.m_value) {
0077             return UnalignedNumber<N-1>::operator!=(other);
0078         }
0079         return true;
0080     }
0081     inline constexpr bool operator<(UnalignedNumber<N> other) const
0082     {
0083         if (m_value == other.m_value) {
0084             return UnalignedNumber<N-1>::operator<(other);
0085         }
0086         return m_value < other.m_value;
0087     }
0088 
0089     inline constexpr UnalignedNumber<N>& operator=(uint32_t num)
0090     {
0091         setValue(num);
0092         return *this;
0093     }
0094     inline constexpr UnalignedNumber<N>& operator|=(uint32_t num)
0095     {
0096         setValue(value() | num);
0097         return *this;
0098     }
0099 
0100     inline constexpr operator uint32_t() const
0101     {
0102         return value();
0103     }
0104 
0105     inline constexpr uint32_t value() const
0106     {
0107         return UnalignedNumber<N-1>::value() | (m_value << (N-1)*8);
0108     }
0109 
0110 protected:
0111     inline constexpr void setValue(uint32_t num)
0112     {
0113         m_value = (num & (0xFF << (N-1)*8)) >> (N-1)*8;
0114         UnalignedNumber<N-1>::setValue(num);
0115     }
0116 
0117 private:
0118     uint8_t m_value = 0;
0119 };
0120 
0121 template <> class UnalignedNumber<1> {
0122 public:
0123     inline constexpr UnalignedNumber() = default;
0124     inline explicit constexpr UnalignedNumber(uint32_t num)
0125         : m_value(num & 0xFF)
0126     {}
0127 
0128     inline constexpr bool operator==(UnalignedNumber<1> other) const
0129     {
0130         return m_value == other.m_value;
0131     }
0132     inline constexpr bool operator!=(UnalignedNumber<1> other) const
0133     {
0134         return m_value != other.m_value;
0135     }
0136     inline constexpr bool operator<(UnalignedNumber<1> other) const
0137     {
0138         return m_value < other.m_value;
0139     }
0140 
0141     inline constexpr uint32_t value() const
0142     {
0143         return m_value;
0144     }
0145 
0146 protected:
0147     inline constexpr void setValue(uint32_t num)
0148     {
0149         m_value = num & 0xFF;
0150     }
0151 
0152 private:
0153     uint8_t m_value = 0;
0154 };
0155 
0156 }
0157 
0158 }
0159