Update comments
This commit is contained in:
parent
2997a8f0c7
commit
43394f86ca
20
src/mask.h
20
src/mask.h
|
@ -1,14 +1,20 @@
|
||||||
#include <algorithm>
|
#include <cstddef>
|
||||||
|
|
||||||
template<typename T> constexpr T mask(size_t bits, size_t offset = 0) {
|
// Returns an instance of T with the given number of bits set to 1, starting at the given offset
|
||||||
return (((T)1 << bits) - 1) << offset;
|
template<typename T> constexpr T mask(size_t num_bits, size_t offset = 0) {
|
||||||
|
return (((T)1 << num_bits) - 1) << offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> constexpr T get_masked(T data, size_t bits, size_t offset) {
|
// Returns the given number of bits from the data parameter, starting at the given offset
|
||||||
return (data >> offset) & mask<T>(bits);
|
template<typename T> constexpr T get_masked(T data, size_t num_bits, size_t offset) {
|
||||||
|
return (data >> offset) & mask<T>(num_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a copy of the given data with the given number of bits (starting at the given offset)
|
||||||
|
* set to match the given binary value
|
||||||
|
*/
|
||||||
//TODO: support typeof(data) != typeof(value)?
|
//TODO: support typeof(data) != typeof(value)?
|
||||||
template<typename T> constexpr T set_masked(T data, T value, size_t bits, size_t offset) {
|
template<typename T> constexpr T set_masked(T data, T value, size_t num_bits, size_t offset) {
|
||||||
return (data & ~mask<T>(bits, offset)) | ((value & mask<T>(bits)) << offset);
|
return (data & ~mask<T>(num_bits, offset)) | ((value & mask<T>(num_bits)) << offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,16 @@
|
||||||
|
|
||||||
#include "mask.h"
|
#include "mask.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raised when a phone number is too long to fit in a ShortPhoneNumber
|
||||||
|
*
|
||||||
|
* This shouldn't happen for any valid phone numbers.
|
||||||
|
*/
|
||||||
class PhoneNumberTooLongException : public std::runtime_error {
|
class PhoneNumberTooLongException : public std::runtime_error {
|
||||||
public:
|
public:
|
||||||
PhoneNumberTooLongException(const i18n::phonenumbers::PhoneNumber& number, const char* msg);
|
PhoneNumberTooLongException(const i18n::phonenumbers::PhoneNumber& number, const char* msg);
|
||||||
|
|
||||||
|
/// Returns the original phone number object
|
||||||
i18n::phonenumbers::PhoneNumber number() const {
|
i18n::phonenumbers::PhoneNumber number() const {
|
||||||
return _number;
|
return _number;
|
||||||
}
|
}
|
||||||
|
@ -27,18 +33,24 @@ class PhoneNumberTooLongException : public std::runtime_error {
|
||||||
class ShortPhoneNumber {
|
class ShortPhoneNumber {
|
||||||
public:
|
public:
|
||||||
enum : size_t {
|
enum : size_t {
|
||||||
|
/// The largest possible country code
|
||||||
MAX_COUNTRY_CODE = 999,
|
MAX_COUNTRY_CODE = 999,
|
||||||
|
/// The maximum number of leading zeroes in a national phone number
|
||||||
MAX_LEADING_ZEROS = 15,
|
MAX_LEADING_ZEROS = 15,
|
||||||
//15 digits
|
/// The largest possible national number
|
||||||
MAX_NATIONAL_NUMBER = 999999999999999,
|
MAX_NATIONAL_NUMBER = 999999999999999,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum : size_t {
|
enum : size_t {
|
||||||
|
/// The number of bits reserved for a country code
|
||||||
COUNTRY_CODE_BITS = 10,
|
COUNTRY_CODE_BITS = 10,
|
||||||
|
/// The number of bits reserved for the leading zero count
|
||||||
LEADING_ZEROS_BITS = 4,
|
LEADING_ZEROS_BITS = 4,
|
||||||
|
/// The number of bits reserved for the national number
|
||||||
NATIONAL_NUMBER_BITS = 50,
|
NATIONAL_NUMBER_BITS = 50,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Bit offsets of the number components
|
||||||
enum : size_t {
|
enum : size_t {
|
||||||
COUNTRY_CODE_OFFSET = 0,
|
COUNTRY_CODE_OFFSET = 0,
|
||||||
LEADING_ZEROS_OFFSET = COUNTRY_CODE_OFFSET + COUNTRY_CODE_BITS,
|
LEADING_ZEROS_OFFSET = COUNTRY_CODE_OFFSET + COUNTRY_CODE_BITS,
|
||||||
|
@ -55,10 +67,11 @@ class ShortPhoneNumber {
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Casts this object to a libphonenumber PhoneNumber object
|
||||||
operator i18n::phonenumbers::PhoneNumber() const;
|
operator i18n::phonenumbers::PhoneNumber() const;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compares to another PhoneNumber using a fast collation heuristic
|
* Compares to another ShortPhoneNumber using a fast collation heuristic
|
||||||
*
|
*
|
||||||
* May not produce intuitive results for numbers with the same
|
* May not produce intuitive results for numbers with the same
|
||||||
* country code but different lengths
|
* country code but different lengths
|
||||||
|
@ -72,26 +85,32 @@ class ShortPhoneNumber {
|
||||||
return other._data - this->_data;
|
return other._data - this->_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the number's country code
|
||||||
google::protobuf::uint32 country_code() const {
|
google::protobuf::uint32 country_code() const {
|
||||||
return get_masked(_data, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
return get_masked(_data, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the number's country code
|
||||||
void country_code(google::protobuf::uint32 value) {
|
void country_code(google::protobuf::uint32 value) {
|
||||||
_data = set_masked(_data, (google::protobuf::uint64)value, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
_data = set_masked(_data, (google::protobuf::uint64)value, COUNTRY_CODE_BITS, COUNTRY_CODE_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the national number
|
||||||
google::protobuf::uint64 national_number() const {
|
google::protobuf::uint64 national_number() const {
|
||||||
return get_masked(_data, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
return get_masked(_data, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the national number
|
||||||
void national_number(google::protobuf::uint64 value) {
|
void national_number(google::protobuf::uint64 value) {
|
||||||
_data = set_masked(_data, value, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
_data = set_masked(_data, value, NATIONAL_NUMBER_BITS, NATIONAL_NUMBER_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the number of leading zeros
|
||||||
google::protobuf::uint64 leading_zeros() const {
|
google::protobuf::uint64 leading_zeros() const {
|
||||||
return get_masked(_data, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
return get_masked(_data, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the number of leading zeros
|
||||||
void leading_zeros(google::protobuf::uint64 value) {
|
void leading_zeros(google::protobuf::uint64 value) {
|
||||||
_data = set_masked(_data, value, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
_data = set_masked(_data, value, LEADING_ZEROS_BITS, LEADING_ZEROS_OFFSET);
|
||||||
}
|
}
|
||||||
|
@ -100,5 +119,8 @@ class ShortPhoneNumber {
|
||||||
google::protobuf::uint64 _data;
|
google::protobuf::uint64 _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the size changes, we'll need to update the extension script too.
|
/*
|
||||||
|
* If the size of the ShortPhoneNumber class changes for any reason, it will trip this assertion and remind us to
|
||||||
|
* update the SQL definition of the short_phone_number type.
|
||||||
|
*/
|
||||||
static_assert(sizeof(ShortPhoneNumber) == 8);
|
static_assert(sizeof(ShortPhoneNumber) == 8);
|
||||||
|
|
Loading…
Reference in New Issue