test.cpp
// find csv files in current directory
std::vector<fs::path> files_vector = get_files_in_directory(L"./", L".csv"); if (files_vector.empty())
{
std::wcout << "CSV files not found." << std::endl; return 3;
}
try
{
// start testing
MobileNumbersData mobile_numbers_data; double s = 0, start, finish;
for (const auto &file : files_vector)
{
std::wifstream wstream(file); if (!wstream.is_open())
{
std::wcout << "File \"" << file.wstring() << "\" skipped (open error)." << std::endl; continue;
}
start = get_proc_time(); mobile_numbers_data.add_data(wstream); finish = get_proc_time();
s += finish - start;
}
std::wcout << "-- Adding data from files: " << s << " seconds" << std::endl; s = 0;
for (int i = 0; i < n_tests; ++i)
{
auto mobile_number = mobile_numbers_data.generate(); start = get_proc_time();
auto range = mobile_numbers_data.find_without_check(mobile_number); finish = get_proc_time();
s += finish - start;
}
std::wcout << "== Without check results" << std::endl;
std::wcout << "-- Testing time: " << s << " seconds" << std::endl; s = 0;
for (int i = 0; i < n_tests; ++i)
{
auto mobile_number = mobile_numbers_data.generate(); start = get_proc_time();
auto range = mobile_numbers_data.find_with_check(mobile_number); finish = get_proc_time();
s += finish - start;
}
std::wcout << "== With check results" << std::endl;
std::wcout << "-- Testing time: " << s << " seconds" << std::endl;
}
catch (const std::exception &e)
{
std::wcout << e.what() << std::endl; return 4;
}
return 0;
}
Таблица 13. Файл lib/mobile_number_defines.h lib/mobile_number_defines.h
#ifndef MOBILE_NUMBER_DEFINES_H #define MOBILE_NUMBER_DEFINES_H
#include <cmath> #include <string> #include <regex> #include <random> #include <functional>
namespace MobileNumberDefines
{
constexpr size_t COUNTRY_CODE_DIGITS = 1;
16
lib/mobile_number_defines.h
constexpr size_t OPERATOR_CODE_DIGITS = 3; constexpr size_t CALLER_CODE_DIGITS = 7;
constexpr int MAX_COUNTRY_CODE = std::pow(10, COUNTRY_CODE_DIGITS) - 1; constexpr int MAX_OPERATOR_CODE = std::pow(10, OPERATOR_CODE_DIGITS) - 1; constexpr int MAX_CALLER_CODE = std::pow(10, CALLER_CODE_DIGITS) - 1;
const std::regex mobile_number_regex("^(?:(\\+?\\d)[\\- ]?)?(?:\\(?(\\d{3})\\)?[\\- ]?)(\\d{3})[\\- ]?(\\d{2})[\\- ]?(\\d{2})$");
/* Can work with next mobile numbers +79811742698 +7(981)1742698 +7-(981)-174-26-98 89811742698 9811742698 (981) 174 2698 (981)-174-2698 981-174-2698 981 174 2698 9811742698
...
country_code -- group #1 operator_code -- group #2 caller_code -- groups #3, #4 and #5
*/
const std::basic_regex<wchar_t> mobile_numbers_range_regex(L"^(\\d{3});(\\d{7});(\\d{7});[^;]*?;([^;]*);(.*)$");
/* Can work with next mobile numbers range
АВС/ DEF;От;До;Емкость;Оператор;Регион
301;2110000;2129999;20000;ПАО "Ростелеком";г. Улан-Удэ|Республика Бурятия 301;2150000;2169999;20000;ПАО "Ростелеком";г. Улан-Удэ|Республика Бурятия 301;2180000;2189999;10000;ПАО "Ростелеком";г. Улан-Удэ|Республика Бурятия
...
operator_code -- group #1 caller_code_from -- group #2 caller_code_to -- group #3 mobile_operator -- group #4 region -- group #5
*/
}
namespace RandomGen
{
extern std::random_device random_device_mn; extern std::mt19937 mt;
extern std::uniform_int_distribution<size_t> size_t_distribution; extern std::uniform_int_distribution<int> int_distribution; extern size_t get_random_size_t_number(size_t, size_t);
extern int get_random_int_number(int, int);
}
#endif // MOBILE_NUMBER_DEFINES_H
Таблица 14. Файл lib/mobile_number_defines.cpp lib/mobile_number_defines.cpp
#include "mobile_number_defines.h"
std::random_device RandomGen::random_device_mn;
std::mt19937 RandomGen::mt = std::mt19937(RandomGen::random_device_mn());
std::uniform_int_distribution<size_t> RandomGen::size_t_distribution(0, std::numeric_limits<size_t>::max());
std::uniform_int_distribution<int> RandomGen::int_distribution(0, std::numeric_limits<int>::max());
size_t RandomGen::get_random_size_t_number(size_t from, size_t to)
{
return from + RandomGen::size_t_distribution(RandomGen::mt) % (to - from + 1);
}
17
lib/mobile_number_defines.cpp
int RandomGen::get_random_int_number(int from, int to)
{
return from + RandomGen::int_distribution(RandomGen::mt) % (to - from + 1);
}
Таблица 15. Файл lib/mobile_numbers_range.h lib/mobile_numbers_range.h
#ifndef MOBILE_NUMBERS_RANGE_H #define MOBILE_NUMBERS_RANGE_H
#include <list> #include <cmath> #include <string> #include <algorithm> #include <stdexcept>
#include "mobile_number_defines.h"
class MobileNumbersRange
{
public:
MobileNumbersRange();
MobileNumbersRange(std::string, std::string, std::string, std::wstring, std::wstring); MobileNumbersRange(int, int, int, std::wstring, std::wstring);
// getters
int operator_code_i() const; int caller_code_from_i() const; int caller_code_to_i() const;
std::string operator_code() const; std::string caller_code_from() const; std::string caller_code_to() const; std::wstring operator_name() const; std::wstring region() const;
// setters
void set_operator_code_i(int); void set_caller_code_i(int, int);
void set_operator_code(const std::string &); void set_operator_code(const std::wstring &);
void set_caller_code(const std::string &, const std::string &); void set_caller_code(const std::wstring &, const std::wstring &); void set_operator_name(const std::wstring &);
void set_region(const std::wstring &); // check
int cmp_in_range(long) const;
friend bool operator<(const MobileNumbersRange &, const MobileNumbersRange &);
private:
int m_operator_code, m_caller_code_from, m_caller_code_to; std::wstring m_operator_name, m_region;
};
#endif // MOBILE_NUMBERS_RANGE_H
Таблица 16. Файл lib/mobile_numbers_range.cpp lib/mobile_numbers_range.cpp
#include "mobile_numbers_range.h"
MobileNumbersRange::MobileNumbersRange() {}
MobileNumbersRange::MobileNumbersRange(std::string operator_code, std::string caller_code_from, std::string caller_code_to, std::wstring mobile_operator, std::wstring region)
{
set_operator_code(operator_code);
18
lib/mobile_numbers_range.cpp
set_caller_code(caller_code_from, caller_code_to); set_operator_name(mobile_operator); set_region(region);
}
MobileNumbersRange::MobileNumbersRange(int operator_code, int caller_code_from, int caller_code_to,
std::wstring mobile_operator, std::wstring region)
{
set_operator_code_i(operator_code); set_caller_code_i(caller_code_from, caller_code_to); set_operator_name(mobile_operator); set_region(region);
}
// getters
int MobileNumbersRange::operator_code_i() const
{
return m_operator_code;
}
int MobileNumbersRange::caller_code_from_i() const
{
return m_caller_code_from;
}
int MobileNumbersRange::caller_code_to_i() const
{
return m_caller_code_to;
}
std::string MobileNumbersRange::operator_code() const
{
std::string s = std::to_string(m_operator_code);
if (s.size() < MobileNumberDefines::OPERATOR_CODE_DIGITS)
{
return std::string(MobileNumberDefines::OPERATOR_CODE_DIGITS - s.size(), L'0') + s;
}
return s;
}
std::string MobileNumbersRange::caller_code_from() const
{
std::string s = std::to_string(m_caller_code_from);
if (s.size() < MobileNumberDefines::CALLER_CODE_DIGITS)
{
return std::string(MobileNumberDefines::CALLER_CODE_DIGITS - s.size(), L'0') + s;
}
return s;
}
std::string MobileNumbersRange::caller_code_to() const
{
std::string s = std::to_string(m_caller_code_to);
if (s.size() < MobileNumberDefines::CALLER_CODE_DIGITS)
{
return std::string(MobileNumberDefines::CALLER_CODE_DIGITS - s.size(), L'0') + s;
}
return s;
}
std::wstring MobileNumbersRange::operator_name() const
{
return m_operator_name;
}
std::wstring MobileNumbersRange::region() const
{
return m_region;
}
19
lib/mobile_numbers_range.cpp
// setters
void MobileNumbersRange::set_operator_code_i(int operator_code)
{
if (operator_code < 0 || operator_code > MobileNumberDefines::MAX_OPERATOR_CODE)
{
throw std::invalid_argument("set_operator_code_i -> operator_code = " + std::to_string(operator_code));
}
m_operator_code = operator_code;
}
void MobileNumbersRange::set_caller_code_i(int caller_code_from, int caller_code_to)
{
if (caller_code_from < 0 || caller_code_from > MobileNumberDefines::MAX_CALLER_CODE)
{
throw std::invalid_argument("set_caller_code_i -> caller_code_from = " + std::to_string(caller_code_from));
}
if (caller_code_to < 0 || caller_code_to > MobileNumberDefines::MAX_CALLER_CODE)
{
throw std::invalid_argument("set_caller_code_i -> caller_code_to = " + std::to_string(caller_code_to));
}
m_caller_code_from = caller_code_from; m_caller_code_to = caller_code_to;
}
void MobileNumbersRange::set_operator_code(const std::wstring &operator_code)
{
set_operator_code(std::string(operator_code.begin(), operator_code.end()));
}
void MobileNumbersRange::set_operator_code(const std::string &operator_code)
{
if (operator_code.size() != MobileNumberDefines::OPERATOR_CODE_DIGITS)
{
throw std::invalid_argument("set_operator_code -> operator_code.size() != " + std::to_string(MobileNumberDefines::OPERATOR_CODE_DIGITS));
}
auto is_operator_code = std::all_of(operator_code.begin(), operator_code.end(), static_cast<int (*)(int)>(std::isdigit));
if (!is_operator_code)
{
throw std::invalid_argument("set_operator_code -> operator_code -- invalid argument: " + std::string(operator_code.begin(), operator_code.end()));
}
m_operator_code = std::stoi(operator_code);
}
void MobileNumbersRange::set_caller_code(const std::wstring &caller_code_from, const std::wstring &caller_code_to)
{
set_caller_code(std::string(caller_code_from.begin(), caller_code_from.end()), std::string(caller_code_to.begin(), caller_code_to.end()));
}
void MobileNumbersRange::set_caller_code(const std::string &caller_code_from, const std::string &caller_code_to)
{
if (caller_code_from.size() != MobileNumberDefines::CALLER_CODE_DIGITS)
{
throw std::invalid_argument("set_caller_code -> caller_code_from.size() != " + std::to_string(MobileNumberDefines::CALLER_CODE_DIGITS));
}
if (caller_code_to.size() != MobileNumberDefines::CALLER_CODE_DIGITS)
{
throw std::invalid_argument("set_caller_code -> caller_code_to.size() != " + std::to_string(MobileNumberDefines::CALLER_CODE_DIGITS));
}
auto is_caller_code_from = std::all_of(caller_code_from.begin(), caller_code_from.end(), static_cast<int (*)(int)>(std::isdigit));
if (!is_caller_code_from)
{
20