Compare commits
No commits in common. "87f4c854d859116337cd1dc4da820c9494e9e78e" and "94616ba6bc93418d19df82a262ff1c03088b2c28" have entirely different histories.
87f4c854d8
...
94616ba6bc
@ -43,6 +43,7 @@ find_package(Qt5 COMPONENTS Core Network REQUIRED)
|
||||
add_subdirectory(src/myx/base)
|
||||
add_subdirectory(src/myx/filesystem)
|
||||
add_subdirectory(src/myx/qt)
|
||||
add_subdirectory(src/myx/math)
|
||||
|
||||
# Примеры
|
||||
if(MYXLIB_BUILD_EXAMPLES OR MYXLIB_BUILD_EXAMPLES_HO)
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 23be253a8db87d51c25a67ffc41c452e5b8f58d5
|
||||
Subproject commit 9df188963e5980d305dd50d721978ccdd997a8c3
|
@ -1 +1 @@
|
||||
Subproject commit 959608f6b5d8c6e4add9f9e7422109bc6b795a5f
|
||||
Subproject commit 0cd764fc187ab3b66cb31a5549f13b3336858894
|
@ -1 +1 @@
|
||||
Subproject commit 00bbf686cdb5bd32ba7105bec1234c85aee6f0aa
|
||||
Subproject commit d0bc6e71e9c613eaaecca62eaf445d647f5216ed
|
@ -11,8 +11,8 @@
|
||||
namespace MF = myx::filesystem;
|
||||
|
||||
// Переменные для защиты экземпляра класса MF::PathsMT
|
||||
std::atomic< MF::PathsMT* > MF::PathsMT::sInstance;
|
||||
std::mutex MF::PathsMT::sMutex;
|
||||
std::atomic< MF::PathsMT* > MF::PathsMT::mInstance;
|
||||
std::mutex MF::PathsMT::mMutex;
|
||||
|
||||
|
||||
int main( int argc, char** argv )
|
||||
|
@ -1,4 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="ru_RU">
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../examples/qt/01_translators/translators.cpp" line="16"/>
|
||||
<source>Yes</source>
|
||||
<translation>Да</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../examples/qt/01_translators/translators.cpp" line="18"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Отмена</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
@ -9,6 +9,7 @@ set(TRGT_cpp
|
||||
# Список заголовочных файлов
|
||||
set(TRGT_hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/limits.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/enum_bitmask_operations.hpp)
|
||||
|
||||
@ -46,8 +47,6 @@ if(MYXLIB_BUILD_LIBRARIES)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
else()
|
||||
install(FILES ${TRGT_cpp} COMPONENT base-dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
||||
endif()
|
||||
|
||||
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
||||
|
10
src/myx/base/config-inl.hpp
Normal file
10
src/myx/base/config-inl.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef MYX_BASE_CONFIG_INL_HPP_
|
||||
#define MYX_BASE_CONFIG_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/base/config.hpp>
|
||||
#endif
|
||||
|
||||
#endif // MYX_BASE_CONFIG_INL_HPP_
|
@ -1,10 +1,5 @@
|
||||
#ifndef MYX_BASE_CONFIG_CPP_
|
||||
#define MYX_BASE_CONFIG_CPP_
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/base/config.hpp>
|
||||
#else
|
||||
#pragma once
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#endif // MYX_BASE_CONFIG_CPP_
|
||||
#include <myx/base/config-inl.hpp>
|
||||
|
@ -23,7 +23,7 @@
|
||||
#endif // ifdef MYXLIB_BUILD_LIBRARIES
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "config.cpp"
|
||||
#include "config-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_BASE_CONFIG_HPP_
|
||||
|
@ -12,7 +12,7 @@ namespace base {
|
||||
template< typename Enum >
|
||||
struct EnableBitMaskOperators
|
||||
{
|
||||
static const bool kEnable = false;
|
||||
static const bool k_Enable = false;
|
||||
};
|
||||
|
||||
template< typename Enum >
|
||||
@ -47,12 +47,11 @@ operator |( Enum lhs, Enum rhs )
|
||||
* ENABLE_BITMASK_OPERATORS(ns::Permissions)
|
||||
*/
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define ENABLE_BITMASK_OPERATORS( x ) \
|
||||
template<> \
|
||||
struct myx::base::EnableBitMaskOperators< x > \
|
||||
{ \
|
||||
static const bool kEnable = true; \
|
||||
static const bool k_Enable = true; \
|
||||
};
|
||||
|
||||
#endif // ifndef MYX_BASE_ENUM_BITWISE_OPERATIONS_HPP_
|
||||
|
@ -12,17 +12,17 @@ namespace base {
|
||||
/**
|
||||
* @brief Константа, представляющая значение, не являющееся числом, для типа float
|
||||
*/
|
||||
constexpr float kFloatNAN { std::numeric_limits< float >::quiet_NaN() };
|
||||
constexpr float k_FloatNAN { std::numeric_limits< float >::quiet_NaN() };
|
||||
|
||||
/**
|
||||
* @brief Константа, представляющая значение, не являющееся числом, для типа double
|
||||
*/
|
||||
constexpr double kDoubleNAN { std::numeric_limits< double >::quiet_NaN() };
|
||||
constexpr double k_DoubleNAN { std::numeric_limits< double >::quiet_NaN() };
|
||||
|
||||
/**
|
||||
* @brief Константа, представляющая значение, не являющееся числом, для типа long double
|
||||
*/
|
||||
constexpr double kLongDoubleNAN { std::numeric_limits< long double >::quiet_NaN() };
|
||||
constexpr double k_LongDoubleNAN { std::numeric_limits< long double >::quiet_NaN() };
|
||||
|
||||
} // namespace base
|
||||
|
||||
|
@ -12,7 +12,10 @@ set(TRGT_cpp
|
||||
set(TRGT_hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/current_executable.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/paths.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.hpp)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/current_executable-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/paths-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt-inl.hpp)
|
||||
|
||||
set(TRGT_headers ${TRGT_hpp})
|
||||
# cmake-format: on
|
||||
@ -51,8 +54,6 @@ if(MYXLIB_BUILD_LIBRARIES)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
else()
|
||||
install(FILES ${TRGT_cpp} COMPONENT base-dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
||||
endif()
|
||||
|
||||
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
||||
|
41
src/myx/filesystem/current_executable-inl.hpp
Normal file
41
src/myx/filesystem/current_executable-inl.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef MYX_BASE_CURRENT_EXECUTABLE_INL_HPP_
|
||||
#define MYX_BASE_CURRENT_EXECUTABLE_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/filesystem/current_executable.hpp>
|
||||
#endif
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace filesystem {
|
||||
|
||||
#if !defined ( __linux__ )
|
||||
error "Class CurrentExecutable is supported only in Linux"
|
||||
#endif
|
||||
|
||||
MYXLIB_INLINE CurrentExecutable::CurrentExecutable() :
|
||||
m_procFilePath( QStringLiteral( "/proc/self/exe" ) )
|
||||
{
|
||||
m_canonicalFilePath = m_procFilePath.canonicalFilePath();
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QFileInfo& CurrentExecutable::canonicalFilePath() const
|
||||
{
|
||||
return( m_canonicalFilePath );
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_BASE_CURRENT_EXECUTABLE_INL_HPP_
|
@ -1,41 +1,5 @@
|
||||
#ifndef MYX_BASE_CURRENT_EXECUTABLE_CPP_
|
||||
#define MYX_BASE_CURRENT_EXECUTABLE_CPP_
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/filesystem/current_executable.hpp>
|
||||
#else
|
||||
#pragma once
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace filesystem {
|
||||
|
||||
#if !defined ( __linux__ )
|
||||
error "Class CurrentExecutable is supported only in Linux"
|
||||
#endif
|
||||
|
||||
MYXLIB_INLINE CurrentExecutable::CurrentExecutable() :
|
||||
m_procFilePath( QStringLiteral( "/proc/self/exe" ) )
|
||||
{
|
||||
m_canonicalFilePath = m_procFilePath.canonicalFilePath();
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QFileInfo& CurrentExecutable::canonicalFilePath() const
|
||||
{
|
||||
return( m_canonicalFilePath );
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_BASE_CURRENT_EXECUTABLE_CPP_
|
||||
#include <myx/filesystem/current_executable-inl.hpp>
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "current_executable.cpp"
|
||||
#include "current_executable-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_
|
||||
|
359
src/myx/filesystem/paths-inl.hpp
Normal file
359
src/myx/filesystem/paths-inl.hpp
Normal file
@ -0,0 +1,359 @@
|
||||
#ifndef MYX_BASE_PATHS_INL_HPP_
|
||||
#define MYX_BASE_PATHS_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/filesystem/paths.hpp>
|
||||
#endif
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
#include <myx/filesystem/current_executable.hpp>
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace filesystem {
|
||||
|
||||
MYXLIB_INLINE Paths::Paths() = default;
|
||||
|
||||
MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType()
|
||||
{
|
||||
QRegExp binUnityRegexp( "/s*bin/unity$" );
|
||||
QRegExp binRegexp( "/s*bin$" );
|
||||
auto binaryDir = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
||||
|
||||
if ( binUnityRegexp.indexIn( binaryDir ) >= 0 )
|
||||
{
|
||||
binaryDir.remove( binUnityRegexp );
|
||||
|
||||
QFileInfo etcDirInfo { binaryDir + "/etc" };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { binaryDir + "/files/log" };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return ( HierarchyType::kDevelopment );
|
||||
}
|
||||
|
||||
if ( binRegexp.indexIn( binaryDir ) == -1 )
|
||||
{
|
||||
return ( HierarchyType::kFlat );
|
||||
}
|
||||
|
||||
QRegExp optRegexp( "^/opt(/|/.+/)" + m_projectName + "/" );
|
||||
|
||||
if ( optRegexp.indexIn( binaryDir ) >= 0 )
|
||||
{
|
||||
binaryDir.remove( binRegexp );
|
||||
QFileInfo etcDirInfo { binaryDir + "/etc" };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { binaryDir + "/files/log" };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return ( HierarchyType::kOpt );
|
||||
}
|
||||
|
||||
if ( binaryDir.startsWith( QStringLiteral( "/usr/local" ) ) )
|
||||
{
|
||||
QFileInfo etcDirInfo { "/usr/local/etc/" + m_projectName };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { "/usr/local/share/" + m_projectName };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { "/var/lib/" + m_projectName };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { "/var/log/" + m_projectName };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return ( HierarchyType::kUsr );
|
||||
}
|
||||
if ( binaryDir.startsWith( QStringLiteral( "/usr" ) ) )
|
||||
{
|
||||
QFileInfo etcDirInfo { "/etc/" + m_projectName };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { "/usr/share/" + m_projectName };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { "/var/lib/" + m_projectName };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { "/var/log/" + m_projectName };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return ( HierarchyType::kUsr );
|
||||
}
|
||||
|
||||
if ( binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/.local/bin" ) ||
|
||||
binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/bin" ) )
|
||||
{
|
||||
QFileInfo etcDirInfo { m_userConfigDirectory.canonicalPath() };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { m_userConstDataDirectory.canonicalPath() };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { m_userVarDataDirectory.canonicalPath() };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { m_userLogDirectory.canonicalPath() };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return( HierarchyType::kHome );
|
||||
}
|
||||
|
||||
binaryDir.remove( binRegexp );
|
||||
|
||||
QFileInfo etcDirInfo { binaryDir + "/etc" };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { binaryDir + "/files/log" };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return ( HierarchyType::kDevelopment );
|
||||
} // Paths::getHierarchyType
|
||||
|
||||
|
||||
MYXLIB_INLINE bool Paths::init( const QString& projectDir, const QString& configFileExtension )
|
||||
{
|
||||
m_projectName = projectDir.isEmpty() ? m_currentExecutable.m_canonicalFilePath.fileName()
|
||||
: projectDir;
|
||||
m_configFileExtension = configFileExtension.isEmpty() ? QStringLiteral( "conf" )
|
||||
: configFileExtension;
|
||||
m_configFileName = m_projectName + "." + m_configFileExtension;
|
||||
|
||||
m_homeDirectory = QDir::homePath();
|
||||
m_tempDirectory = QDir::tempPath();
|
||||
|
||||
auto configHome = QString::fromLocal8Bit( qgetenv( "XDG_CONFIG_HOME" ) );
|
||||
if ( configHome.isEmpty() )
|
||||
{
|
||||
configHome = m_homeDirectory.canonicalPath() + "/.config";
|
||||
}
|
||||
m_userConfigDirectory = configHome + "/" + m_projectName;
|
||||
|
||||
auto dataHome = QString::fromLocal8Bit( qgetenv( "XDG_DATA_HOME" ) );
|
||||
if ( dataHome.isEmpty() )
|
||||
{
|
||||
dataHome = m_homeDirectory.canonicalPath() + "/.local/share";
|
||||
}
|
||||
dataHome += "/" + m_projectName;
|
||||
m_userConstDataDirectory = dataHome + "/data";
|
||||
m_userVarDataDirectory = dataHome + "/lib";
|
||||
m_userLogDirectory = dataHome + "/log";
|
||||
|
||||
m_hierarchyType = getHierarchyType();
|
||||
|
||||
if ( m_hierarchyType == HierarchyType::kFlat )
|
||||
{
|
||||
m_systemConstDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
||||
m_systemVarDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
||||
m_systemConfigDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
||||
m_systemLogDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
||||
}
|
||||
|
||||
m_configFilePath = m_systemConfigDirectory.canonicalPath() + "/" + m_configFileName;
|
||||
|
||||
return( true );
|
||||
} // Paths::updatePaths
|
||||
|
||||
|
||||
MYXLIB_INLINE bool Paths::makeDefaultDirectories()
|
||||
{
|
||||
bool status = true;
|
||||
|
||||
if ( !m_userConfigDirectory.mkpath( m_userConfigDirectory.absolutePath() ) ) { status = false; }
|
||||
if ( !m_userVarDataDirectory.mkpath( m_userVarDataDirectory.absolutePath() ) ) { status = false; }
|
||||
if ( !m_userConstDataDirectory.mkpath( m_userConstDataDirectory.absolutePath() ) ) { status = false; }
|
||||
if ( !m_userLogDirectory.mkpath( m_userLogDirectory.absolutePath() ) ) { status = false; }
|
||||
return( status );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE QString Paths::findConfigFile( const QString& defaultConfigFile )
|
||||
{
|
||||
if ( !defaultConfigFile.isEmpty() && QFileInfo( defaultConfigFile ).isReadable() )
|
||||
{
|
||||
m_configFilePath = defaultConfigFile;
|
||||
return( defaultConfigFile );
|
||||
}
|
||||
|
||||
auto fileName = QString::fromLocal8Bit( qgetenv( QCoreApplication::applicationName()
|
||||
.toUpper().toUtf8() + "_CONFIG" ) );
|
||||
if ( QFileInfo( fileName ).isReadable() )
|
||||
{
|
||||
m_configFilePath = fileName;
|
||||
return( fileName );
|
||||
}
|
||||
|
||||
if ( QFileInfo( m_configFilePath ).isReadable() )
|
||||
{
|
||||
return( m_configFilePath.absoluteFilePath() );
|
||||
}
|
||||
|
||||
return( QString() );
|
||||
} // Paths::findConfigFile
|
||||
|
||||
|
||||
MYXLIB_INLINE QDir Paths::executableFileDirectory() const
|
||||
{
|
||||
return( m_currentExecutable.m_canonicalFilePath.dir() );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::userConfigDirectory() const
|
||||
{
|
||||
return( m_userConfigDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::systemConfigDirectory() const
|
||||
{
|
||||
return( m_systemConfigDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QFileInfo& Paths::configFilePath() const
|
||||
{
|
||||
return( m_configFilePath );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QString& Paths::configFileName() const
|
||||
{
|
||||
return( m_configFileName );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QString& Paths::configFileExtension() const
|
||||
{
|
||||
return( m_configFileExtension );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::userVarDataDirectory() const
|
||||
{
|
||||
return( m_userVarDataDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::systemVarDataDirectory() const
|
||||
{
|
||||
return( m_systemVarDataDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::userConstDataDirectory() const
|
||||
{
|
||||
return( m_userConstDataDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::systemConstDataDirectory() const
|
||||
{
|
||||
return( m_systemConstDataDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::userLogDirectory() const
|
||||
{
|
||||
return( m_userLogDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::systemLogDirectory() const
|
||||
{
|
||||
return( m_systemLogDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::tempDirectory() const
|
||||
{
|
||||
return( m_tempDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::homeDirectory() const
|
||||
{
|
||||
return( m_homeDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QString& Paths::projectName() const
|
||||
{
|
||||
return( m_projectName );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE QString Paths::executableFileName() const
|
||||
{
|
||||
return( m_currentExecutable.m_canonicalFilePath.fileName() );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QFileInfo& Paths::executableFilePath() const
|
||||
{
|
||||
return( m_currentExecutable.m_canonicalFilePath );
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_BASE_PATHS_INL_HPP_
|
@ -1,359 +1,5 @@
|
||||
#ifndef MYX_BASE_PATHS_CPP_
|
||||
#define MYX_BASE_PATHS_CPP_
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/filesystem/paths.hpp>
|
||||
#else
|
||||
#pragma once
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
#include <myx/filesystem/current_executable.hpp>
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace filesystem {
|
||||
|
||||
MYXLIB_INLINE Paths::Paths() = default;
|
||||
|
||||
MYXLIB_INLINE Paths::HierarchyType Paths::getHierarchyType() // V2008
|
||||
{
|
||||
QRegExp binUnityRegexp( "/s*bin/unity$" );
|
||||
QRegExp binRegexp( "/s*bin$" );
|
||||
auto binaryDir = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
||||
|
||||
if ( binUnityRegexp.indexIn( binaryDir ) >= 0 )
|
||||
{
|
||||
binaryDir.remove( binUnityRegexp );
|
||||
|
||||
QFileInfo etcDirInfo { binaryDir + "/etc" };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { binaryDir + "/files/log" };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return ( HierarchyType::kDevelopment );
|
||||
}
|
||||
|
||||
if ( binRegexp.indexIn( binaryDir ) == -1 )
|
||||
{
|
||||
return ( HierarchyType::kFlat );
|
||||
}
|
||||
|
||||
QRegExp optRegexp( "^/opt(/|/.+/)" + m_projectName + "/" );
|
||||
|
||||
if ( optRegexp.indexIn( binaryDir ) >= 0 )
|
||||
{
|
||||
binaryDir.remove( binRegexp );
|
||||
QFileInfo etcDirInfo { binaryDir + "/etc" };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { binaryDir + "/files/log" };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return ( HierarchyType::kOpt );
|
||||
}
|
||||
|
||||
if ( binaryDir.startsWith( QStringLiteral( "/usr/local" ) ) )
|
||||
{
|
||||
QFileInfo etcDirInfo { "/usr/local/etc/" + m_projectName };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { "/usr/local/share/" + m_projectName };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { "/var/lib/" + m_projectName };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { "/var/log/" + m_projectName };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return ( HierarchyType::kUsr );
|
||||
}
|
||||
if ( binaryDir.startsWith( QStringLiteral( "/usr" ) ) )
|
||||
{
|
||||
QFileInfo etcDirInfo { "/etc/" + m_projectName };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { "/usr/share/" + m_projectName };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { "/var/lib/" + m_projectName };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { "/var/log/" + m_projectName };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return ( HierarchyType::kUsr );
|
||||
}
|
||||
|
||||
if ( binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/.local/bin" ) ||
|
||||
binaryDir.startsWith( m_homeDirectory.canonicalPath() + "/bin" ) )
|
||||
{
|
||||
QFileInfo etcDirInfo { m_userConfigDirectory.canonicalPath() };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { m_userConstDataDirectory.canonicalPath() };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { m_userVarDataDirectory.canonicalPath() };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { m_userLogDirectory.canonicalPath() };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return( HierarchyType::kHome );
|
||||
}
|
||||
|
||||
binaryDir.remove( binRegexp );
|
||||
|
||||
QFileInfo etcDirInfo { binaryDir + "/etc" };
|
||||
if ( !etcDirInfo.isDir() || !etcDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo constDataDirInfo { binaryDir + "/files/data" };
|
||||
if ( !constDataDirInfo.isDir() || !constDataDirInfo.isReadable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo varDataDirInfo { binaryDir + "/files/lib" };
|
||||
if ( !varDataDirInfo.isDir() || !varDataDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
QFileInfo logDirInfo { binaryDir + "/files/log" };
|
||||
if ( !logDirInfo.isDir() || !logDirInfo.isWritable() ) { return( HierarchyType::kFlat ); }
|
||||
|
||||
m_systemConfigDirectory = etcDirInfo.canonicalFilePath();
|
||||
m_systemConstDataDirectory = constDataDirInfo.canonicalFilePath();
|
||||
m_systemVarDataDirectory = varDataDirInfo.canonicalFilePath();
|
||||
m_systemLogDirectory = logDirInfo.canonicalFilePath();
|
||||
|
||||
return ( HierarchyType::kDevelopment );
|
||||
} // Paths::getHierarchyType
|
||||
|
||||
|
||||
MYXLIB_INLINE bool Paths::init( const QString& projectDir, const QString& configFileExtension )
|
||||
{
|
||||
m_projectName = projectDir.isEmpty() ? m_currentExecutable.m_canonicalFilePath.fileName()
|
||||
: projectDir;
|
||||
m_configFileExtension = configFileExtension.isEmpty() ? QStringLiteral( "conf" )
|
||||
: configFileExtension;
|
||||
m_configFileName = m_projectName + "." + m_configFileExtension;
|
||||
|
||||
m_homeDirectory = QDir::homePath();
|
||||
m_tempDirectory = QDir::tempPath();
|
||||
|
||||
auto configHome = QString::fromLocal8Bit( qgetenv( "XDG_CONFIG_HOME" ) );
|
||||
if ( configHome.isEmpty() )
|
||||
{
|
||||
configHome = m_homeDirectory.canonicalPath() + "/.config";
|
||||
}
|
||||
m_userConfigDirectory = configHome + "/" + m_projectName;
|
||||
|
||||
auto dataHome = QString::fromLocal8Bit( qgetenv( "XDG_DATA_HOME" ) );
|
||||
if ( dataHome.isEmpty() )
|
||||
{
|
||||
dataHome = m_homeDirectory.canonicalPath() + "/.local/share";
|
||||
}
|
||||
dataHome += "/" + m_projectName;
|
||||
m_userConstDataDirectory = dataHome + "/data";
|
||||
m_userVarDataDirectory = dataHome + "/lib";
|
||||
m_userLogDirectory = dataHome + "/log";
|
||||
|
||||
m_hierarchyType = getHierarchyType();
|
||||
|
||||
if ( m_hierarchyType == HierarchyType::kFlat )
|
||||
{
|
||||
m_systemConstDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
||||
m_systemVarDataDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
||||
m_systemConfigDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
||||
m_systemLogDirectory = m_currentExecutable.m_canonicalFilePath.canonicalPath();
|
||||
}
|
||||
|
||||
m_configFilePath = m_systemConfigDirectory.canonicalPath() + "/" + m_configFileName;
|
||||
|
||||
return( true );
|
||||
} // Paths::updatePaths
|
||||
|
||||
|
||||
MYXLIB_INLINE bool Paths::makeDefaultDirectories()
|
||||
{
|
||||
bool status = true;
|
||||
|
||||
if ( !m_userConfigDirectory.mkpath( m_userConfigDirectory.absolutePath() ) ) { status = false; }
|
||||
if ( !m_userVarDataDirectory.mkpath( m_userVarDataDirectory.absolutePath() ) ) { status = false; }
|
||||
if ( !m_userConstDataDirectory.mkpath( m_userConstDataDirectory.absolutePath() ) ) { status = false; }
|
||||
if ( !m_userLogDirectory.mkpath( m_userLogDirectory.absolutePath() ) ) { status = false; }
|
||||
return( status );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE QString Paths::findConfigFile( const QString& defaultConfigFile )
|
||||
{
|
||||
if ( !defaultConfigFile.isEmpty() && QFileInfo( defaultConfigFile ).isReadable() )
|
||||
{
|
||||
m_configFilePath = defaultConfigFile;
|
||||
return( defaultConfigFile );
|
||||
}
|
||||
|
||||
auto fileName = QString::fromLocal8Bit( qgetenv( QCoreApplication::applicationName()
|
||||
.toUpper().toUtf8() + "_CONFIG" ) );
|
||||
if ( QFileInfo( fileName ).isReadable() )
|
||||
{
|
||||
m_configFilePath = fileName;
|
||||
return( fileName );
|
||||
}
|
||||
|
||||
if ( QFileInfo( m_configFilePath ).isReadable() )
|
||||
{
|
||||
return( m_configFilePath.absoluteFilePath() );
|
||||
}
|
||||
|
||||
return( QString() );
|
||||
} // Paths::findConfigFile
|
||||
|
||||
|
||||
MYXLIB_INLINE QDir Paths::executableFileDirectory() const
|
||||
{
|
||||
return( m_currentExecutable.m_canonicalFilePath.dir() );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::userConfigDirectory() const
|
||||
{
|
||||
return( m_userConfigDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::systemConfigDirectory() const
|
||||
{
|
||||
return( m_systemConfigDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QFileInfo& Paths::configFilePath() const
|
||||
{
|
||||
return( m_configFilePath );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QString& Paths::configFileName() const
|
||||
{
|
||||
return( m_configFileName );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QString& Paths::configFileExtension() const
|
||||
{
|
||||
return( m_configFileExtension );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::userVarDataDirectory() const
|
||||
{
|
||||
return( m_userVarDataDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::systemVarDataDirectory() const
|
||||
{
|
||||
return( m_systemVarDataDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::userConstDataDirectory() const
|
||||
{
|
||||
return( m_userConstDataDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::systemConstDataDirectory() const
|
||||
{
|
||||
return( m_systemConstDataDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::userLogDirectory() const
|
||||
{
|
||||
return( m_userLogDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::systemLogDirectory() const
|
||||
{
|
||||
return( m_systemLogDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::tempDirectory() const
|
||||
{
|
||||
return( m_tempDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QDir& Paths::homeDirectory() const
|
||||
{
|
||||
return( m_homeDirectory );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QString& Paths::projectName() const
|
||||
{
|
||||
return( m_projectName );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE QString Paths::executableFileName() const
|
||||
{
|
||||
return( m_currentExecutable.m_canonicalFilePath.fileName() );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE const QFileInfo& Paths::executableFilePath() const
|
||||
{
|
||||
return( m_currentExecutable.m_canonicalFilePath );
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_BASE_PATHS_CPP_
|
||||
#include <myx/filesystem/paths-inl.hpp>
|
||||
|
@ -102,8 +102,8 @@ public:
|
||||
*/
|
||||
static Paths& instance()
|
||||
{
|
||||
static Paths sPaths;
|
||||
return( sPaths );
|
||||
static Paths p;
|
||||
return( p );
|
||||
}
|
||||
|
||||
|
||||
@ -223,7 +223,7 @@ public:
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "paths.cpp"
|
||||
#include "paths-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_FILESYSTEM_PATHS_HPP_
|
||||
|
44
src/myx/filesystem/paths_mt-inl.hpp
Normal file
44
src/myx/filesystem/paths_mt-inl.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef MYX_BASE_PATHS_MT_INL_HPP_
|
||||
#define MYX_BASE_PATHS_MT_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/filesystem/paths_mt.hpp>
|
||||
#endif
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
#include <myx/filesystem/current_executable.hpp>
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace filesystem {
|
||||
|
||||
MYXLIB_INLINE PathsMT::PathsMT() = default;
|
||||
|
||||
MYXLIB_INLINE PathsMT& PathsMT::instance()
|
||||
{
|
||||
volatile PathsMT* localInstance = mInstance.load( std::memory_order_acquire );
|
||||
if ( localInstance == nullptr )
|
||||
{
|
||||
std::lock_guard< std::mutex > myLock( mMutex );
|
||||
localInstance = mInstance.load( std::memory_order_relaxed );
|
||||
if ( localInstance == nullptr ) // -V1036
|
||||
{
|
||||
localInstance = new PathsMT();
|
||||
mInstance.store( const_cast< PathsMT* >( localInstance ), std::memory_order_release ); // NOLINT
|
||||
}
|
||||
}
|
||||
return( const_cast< PathsMT& >( *localInstance ) ); // NOLINT
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_BASE_PATHS_MT_INL_HPP_
|
@ -1,44 +1,5 @@
|
||||
#ifndef MYX_BASE_PATHS_MT_CPP_
|
||||
#define MYX_BASE_PATHS_MT_CPP_
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/filesystem/paths_mt.hpp>
|
||||
#else
|
||||
#pragma once
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
#include <myx/filesystem/current_executable.hpp>
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace filesystem {
|
||||
|
||||
MYXLIB_INLINE PathsMT::PathsMT() = default;
|
||||
|
||||
MYXLIB_INLINE PathsMT& PathsMT::instance()
|
||||
{
|
||||
volatile PathsMT* localInstance = sInstance.load( std::memory_order_acquire );
|
||||
if ( localInstance == nullptr )
|
||||
{
|
||||
std::lock_guard< std::mutex > myLock( sMutex );
|
||||
localInstance = sInstance.load( std::memory_order_relaxed );
|
||||
if ( localInstance == nullptr ) // -V1036
|
||||
{
|
||||
localInstance = new PathsMT();
|
||||
sInstance.store( const_cast< PathsMT* >( localInstance ), std::memory_order_release ); // NOLINT
|
||||
}
|
||||
}
|
||||
return( const_cast< PathsMT& >( *localInstance ) ); // NOLINT
|
||||
}
|
||||
|
||||
} // namespace filesystem
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_BASE_PATHS_MT_CPP_
|
||||
#include <myx/filesystem/paths_mt-inl.hpp>
|
||||
|
@ -31,8 +31,8 @@ class PathsMT : public Paths
|
||||
PathsMT();
|
||||
~PathsMT() = default;
|
||||
|
||||
static std::atomic< PathsMT* > sInstance;
|
||||
static std::mutex sMutex;
|
||||
static std::atomic< PathsMT* > mInstance;
|
||||
static std::mutex mMutex;
|
||||
|
||||
|
||||
public:
|
||||
@ -53,7 +53,7 @@ public:
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "paths_mt.cpp"
|
||||
#include "paths_mt-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_FILESYSTEM_PATHS_MT_HPP_
|
||||
|
75
src/myx/math/CMakeLists.txt
Normal file
75
src/myx/math/CMakeLists.txt
Normal file
@ -0,0 +1,75 @@
|
||||
# Название основной цели и имя библиотеки в текущем каталоге
|
||||
set(TRGT math)
|
||||
|
||||
# cmake-format: off
|
||||
# Список файлов исходных текстов
|
||||
set(TRGT_cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative_and_abs.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps_and_abs.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/constants.cpp)
|
||||
|
||||
# Список заголовочных файлов
|
||||
set(TRGT_hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/all.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative_and_abs.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_relative_and_abs-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps_and_abs.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/almost_equal_ulps_and_abs-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/constants.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/constants-inl.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/float_cmp_types.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/functions.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/radar.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/units.hpp)
|
||||
|
||||
set(TRGT_headers ${TRGT_hpp})
|
||||
# cmake-format: on
|
||||
|
||||
add_library(${TRGT}-header-only INTERFACE)
|
||||
target_sources(${TRGT}-header-only INTERFACE ${TRGT_headers})
|
||||
target_include_directories(
|
||||
${TRGT}-header-only SYSTEM INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
|
||||
if(MYXLIB_BUILD_LIBRARIES)
|
||||
|
||||
add_common_library(${TRGT} OUTPUT_NAME myx-${TRGT} SOURCES ${TRGT_cpp} ${TRGT_headers})
|
||||
common_target_properties(${TRGT})
|
||||
|
||||
# Создание цели для проверки утилитой clang-tidy
|
||||
add_clang_tidy_check(${TRGT} ${TRGT_sources} ${TRGT_headers})
|
||||
|
||||
# Создание цели для проверки утилитой clang-analyze
|
||||
add_clang_analyze_check(${TRGT} ${TRGT_sources} ${TRGT_headers})
|
||||
|
||||
# Создание цели для проверки утилитой clazy
|
||||
add_clazy_check(${TRGT} ${TRGT_sources} ${TRGT_headers})
|
||||
|
||||
# Создание цели для проверки утилитой pvs-studio
|
||||
add_pvs_check(${TRGT})
|
||||
|
||||
# Создание цели для автоматического форматирования кода
|
||||
add_format_sources(${TRGT} ${TRGT_sources} ${TRGT_headers})
|
||||
|
||||
target_compile_definitions(${TRGT} PUBLIC MYXLIB_BUILD_LIBRARIES)
|
||||
target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||
|
||||
cotire(${TRGT})
|
||||
install(TARGETS ${TRGT}_static COMPONENT libs-dev ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
||||
install(FILES ${TRGT_headers} COMPONENT base-dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
||||
|
||||
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base -P
|
||||
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
15
src/myx/math/all.hpp
Normal file
15
src/myx/math/all.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef MYX_MATH_ALL_HPP_
|
||||
#define MYX_MATH_ALL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/math/almost_equal_relative.hpp>
|
||||
#include <myx/math/almost_equal_relative_and_abs.hpp>
|
||||
#include <myx/math/almost_equal_ulps.hpp>
|
||||
#include <myx/math/almost_equal_ulps_and_abs.hpp>
|
||||
#include <myx/math/constants.hpp>
|
||||
#include <myx/math/functions.hpp>
|
||||
#include <myx/math/radar.hpp>
|
||||
#include <myx/math/units.hpp>
|
||||
|
||||
#endif
|
51
src/myx/math/almost_equal_relative-inl.hpp
Normal file
51
src/myx/math/almost_equal_relative-inl.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_INL_HPP_
|
||||
#define MYX_MATH_ALMOST_EQUAL_RELATIVE_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/math/almost_equal_relative.hpp>
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
MYXLIB_INLINE bool almost_equal_relative( const float a, const float b,
|
||||
const float maxRelDiff )
|
||||
{
|
||||
float diff = fabsf( a - b );
|
||||
float aN = fabsf( a );
|
||||
float bN = fabsf( b );
|
||||
float largest = ( bN > aN ) ? bN : aN;
|
||||
|
||||
if ( diff <= largest * maxRelDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
return( false );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE bool almost_equal_relative( const double a, const double b,
|
||||
const double maxRelDiff )
|
||||
{
|
||||
double diff = fabs( a - b );
|
||||
double aN = fabs( a );
|
||||
double bN = fabs( b );
|
||||
double largest = ( bN > aN ) ? bN : aN;
|
||||
|
||||
if ( diff <= largest * maxRelDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
return( false );
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_INL_HPP_
|
5
src/myx/math/almost_equal_relative.cpp
Normal file
5
src/myx/math/almost_equal_relative.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#include <myx/math/almost_equal_relative-inl.hpp>
|
39
src/myx/math/almost_equal_relative.hpp
Normal file
39
src/myx/math/almost_equal_relative.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_HPP_
|
||||
#define MYX_MATH_ALMOST_EQUAL_RELATIVE_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
#include <cfloat>
|
||||
|
||||
// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
/**
|
||||
* @brief Проверка на равенство двух аргументов типа float.
|
||||
* Параметр maxRelDiff определяет максимальную относительную допустимую разницу,
|
||||
* при которой аргументы считаются равными.
|
||||
*/
|
||||
bool almost_equal_relative( float a, float b,
|
||||
float maxRelDiff = FLT_EPSILON );
|
||||
/**
|
||||
* @brief Проверка на равенство двух аргументов типа double.
|
||||
* Параметр maxRelDiff определяет максимальную относительную допустимую разницу,
|
||||
* при которой аргументы считаются равными.
|
||||
*/
|
||||
bool almost_equal_relative( double a, double b,
|
||||
double maxRelDiff = DBL_EPSILON );
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "almost_equal_relative-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_MATH_ALMOST_EQUAL_RELATIVE_HPP_
|
65
src/myx/math/almost_equal_relative_and_abs-inl.hpp
Normal file
65
src/myx/math/almost_equal_relative_and_abs-inl.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
#ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_INL_HPP_
|
||||
#define MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/math/almost_equal_relative_and_abs.hpp>
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
MYXLIB_INLINE bool almost_equal_relative_and_abs( const float a, const float b,
|
||||
const float maxAbsDiff, const float maxRelDiff )
|
||||
{
|
||||
// Check if the numbers are really close -- needed
|
||||
// when comparing numbers near zero.
|
||||
float diff = fabsf( a - b );
|
||||
if ( diff <= maxAbsDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
|
||||
float aN = fabsf( a );
|
||||
float bN = fabsf( b );
|
||||
float largest = ( bN > aN ) ? bN : aN;
|
||||
|
||||
if ( diff <= largest * maxRelDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
return( false );
|
||||
}
|
||||
|
||||
|
||||
MYXLIB_INLINE bool almost_equal_relative_and_abs( const double a, const double b,
|
||||
const double maxAbsDiff, const double maxRelDiff )
|
||||
{
|
||||
// Check if the numbers are really close -- needed
|
||||
// when comparing numbers near zero.
|
||||
double diff = fabs( a - b );
|
||||
if ( diff <= maxAbsDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
|
||||
double aN = fabs( a );
|
||||
double bN = fabs( b );
|
||||
double largest = ( bN > aN ) ? bN : aN;
|
||||
|
||||
if ( diff <= largest * maxRelDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
return( false );
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_INL_HPP_
|
5
src/myx/math/almost_equal_relative_and_abs.cpp
Normal file
5
src/myx/math/almost_equal_relative_and_abs.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#include <myx/math/almost_equal_relative_and_abs-inl.hpp>
|
39
src/myx/math/almost_equal_relative_and_abs.hpp
Normal file
39
src/myx/math/almost_equal_relative_and_abs.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_HPP_
|
||||
#define MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
#include <cfloat>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
/**
|
||||
* @brief Проверка на равенство двух аргументов типа float.
|
||||
* Параметр maxAbsDiff определяет максимальную абсолютную допустимую разницу.
|
||||
* Параметр maxRelDiff определяет максимальную относительную допустимую разницу,
|
||||
* при которой аргументы считаются равными.
|
||||
*/
|
||||
bool almost_equal_relative_and_abs( float a, float b,
|
||||
float maxAbsDiff, float maxRelDiff = FLT_EPSILON );
|
||||
/**
|
||||
* @brief Проверка на равенство двух аргументов типа double.
|
||||
* Параметр maxAbsDiff определяет максимальную абсолютную допустимую разницу.
|
||||
* Параметр maxRelDiff определяет максимальную относительную допустимую разницу,
|
||||
* при которой аргументы считаются равными.
|
||||
*/
|
||||
bool almost_equal_relative_and_abs( double a, double b,
|
||||
double maxAbsDiff, double maxRelDiff = DBL_EPSILON );
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "almost_equal_relative_and_abs-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_HPP_
|
93
src/myx/math/almost_equal_ulps-inl.hpp
Normal file
93
src/myx/math/almost_equal_ulps-inl.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef MYX_MATH_ALMOST_EQUAL_ULPS_INL_HPP_
|
||||
#define MYX_MATH_ALMOST_EQUAL_ULPS_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/math/almost_equal_ulps.hpp>
|
||||
#endif
|
||||
|
||||
#include <myx/math/float_cmp_types.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
MYXLIB_INLINE bool almost_equal_ulps( const float a, const float b,
|
||||
const int maxUlpsDiff )
|
||||
{
|
||||
FloatCmp uA( a );
|
||||
FloatCmp uB( b );
|
||||
|
||||
// Если знаки разные, то числа не равны.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
||||
if ( uA.negative() != uB.negative() )
|
||||
{
|
||||
// Кроме случая, когда +0==-0
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
if ( a == b ) // -V550
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
return( false );
|
||||
}
|
||||
|
||||
// Разница в младших битах.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
||||
auto ulpsDiff = std::abs( uA.i - uB.i );
|
||||
if ( ulpsDiff <= maxUlpsDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
return( false );
|
||||
} // almost_equal_ulps
|
||||
|
||||
|
||||
MYXLIB_INLINE bool almost_equal_ulps( const double a, const double b,
|
||||
const int maxUlpsDiff )
|
||||
{
|
||||
DoubleCmp uA( a );
|
||||
DoubleCmp uB( b );
|
||||
|
||||
// Если знаки разные, то числа не равны.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
||||
if ( uA.negative() != uB.negative() )
|
||||
{
|
||||
// Кроме случая, когда +0==-0
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
if ( a == b ) // -V550
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
return( false );
|
||||
}
|
||||
|
||||
// Разница в младших битах.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
||||
auto ulpsDiff = std::abs( uA.i - uB.i );
|
||||
if ( ulpsDiff <= maxUlpsDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
return( false );
|
||||
} // almost_equal_ulps
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // ifndef MYX_MATH_ALMOST_EQUAL_ULPS_INL_HPP_
|
5
src/myx/math/almost_equal_ulps.cpp
Normal file
5
src/myx/math/almost_equal_ulps.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#include <myx/math/almost_equal_ulps-inl.hpp>
|
38
src/myx/math/almost_equal_ulps.hpp
Normal file
38
src/myx/math/almost_equal_ulps.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef MYX_MATH_ALMOST_EQUAL_ULPS_HPP_
|
||||
#define MYX_MATH_ALMOST_EQUAL_ULPS_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
#include <myx/math/float_cmp_types.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
/**
|
||||
* @brief Проверка на равенство двух аргументов типа float.
|
||||
* Параметр maxUlpsDiff определяет максимальную разницу между аргументами,
|
||||
* при которой они считаются равными.
|
||||
*/
|
||||
bool almost_equal_ulps( float a, float b,
|
||||
int maxUlpsDiff );
|
||||
/**
|
||||
* @brief Проверка на равенство двух аргументов типа double.
|
||||
* Параметр maxUlpsDiff определяет максимальную разницу между аргументами,
|
||||
* при которой они считаются равными.
|
||||
*/
|
||||
bool almost_equal_ulps( double a, double b,
|
||||
int maxUlpsDiff );
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "almost_equal_ulps-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_MATH_ALMOST_EQUAL_ULPS_HPP_
|
87
src/myx/math/almost_equal_ulps_and_abs-inl.hpp
Normal file
87
src/myx/math/almost_equal_ulps_and_abs-inl.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef MYX_MATH_ALMOST_EQUAL_ULPS_INL_HPP_
|
||||
#define MYX_MATH_ALMOST_EQUAL_ULPS_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/math/almost_equal_ulps_and_abs.hpp>
|
||||
#endif
|
||||
|
||||
#include <myx/math/float_cmp_types.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
MYXLIB_INLINE bool almost_equal_ulps_and_abs( const float a, const float b,
|
||||
const float maxAbsDiff, const int maxUlpsDiff )
|
||||
{
|
||||
// Check if the numbers are really close -- needed
|
||||
// when comparing numbers near zero.
|
||||
float absDiff = fabsf( a - b );
|
||||
if ( absDiff <= maxAbsDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
|
||||
FloatCmp uA( a );
|
||||
FloatCmp uB( b );
|
||||
|
||||
// Different signs means they do not match.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
||||
if ( uA.negative() != uB.negative() )
|
||||
{
|
||||
return( false );
|
||||
}
|
||||
|
||||
// Find the difference in ULPs.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
||||
int ulpsDiff = std::abs( uA.i - uB.i );
|
||||
if ( ulpsDiff <= maxUlpsDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
|
||||
return( false );
|
||||
} // almost_equal_ulps_and_abs
|
||||
|
||||
|
||||
MYXLIB_INLINE bool almost_equal_ulps_and_abs( const double a, const double b,
|
||||
const double maxAbsDiff, const int maxUlpsDiff )
|
||||
{
|
||||
// Check if the numbers are really close -- needed
|
||||
// when comparing numbers near zero.
|
||||
double absDiff = fabs( a - b );
|
||||
if ( absDiff <= maxAbsDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
|
||||
DoubleCmp uA( a );
|
||||
DoubleCmp uB( b );
|
||||
|
||||
// Different signs means they do not match.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
||||
if ( uA.negative() != uB.negative() )
|
||||
{
|
||||
return( false );
|
||||
}
|
||||
|
||||
// Find the difference in ULPs.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
||||
auto ulpsDiff = std::abs( uA.i - uB.i );
|
||||
if ( ulpsDiff <= maxUlpsDiff )
|
||||
{
|
||||
return( true );
|
||||
}
|
||||
|
||||
return( false );
|
||||
} // almost_equal_ulps_and_abs
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // ifndef MYX_MATH_ALMOST_EQUAL_ULPS_INL_HPP_
|
5
src/myx/math/almost_equal_ulps_and_abs.cpp
Normal file
5
src/myx/math/almost_equal_ulps_and_abs.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#include <myx/math/almost_equal_ulps_and_abs-inl.hpp>
|
37
src/myx/math/almost_equal_ulps_and_abs.hpp
Normal file
37
src/myx/math/almost_equal_ulps_and_abs.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef MYX_MATH_ALMOST_EQUAL_ULPS_HPP_
|
||||
#define MYX_MATH_ALMOST_EQUAL_ULPS_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
/**
|
||||
* @brief Проверка на равенство двух аргументов типа float.
|
||||
* Параметр maxAbsDiff определяет максимальную абсолютную допустимую разницу.
|
||||
* Параметр maxUlpsDiff определяет максимальную разницу между аргументами,
|
||||
* при которой они считаются равными.
|
||||
*/
|
||||
bool almost_equal_ulps_and_abs( float a, float b,
|
||||
float maxAbsDiff, int maxUlpsDiff );
|
||||
/**
|
||||
* @brief Проверка на равенство двух аргументов типа double.
|
||||
* Параметр maxAbsDiff определяет максимальную абсолютную допустимую разницу.
|
||||
* Параметр maxUlpsDiff определяет максимальную разницу между аргументами,
|
||||
* при которой они считаются равными.
|
||||
*/
|
||||
bool almost_equal_ulps_and_abs( double a, double b,
|
||||
double maxAbsDiff, int maxUlpsDiff );
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "almost_equal_ulps_and_abs-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_MATH_ALMOST_EQUAL_ULPS_HPP_
|
18
src/myx/math/constants-inl.hpp
Normal file
18
src/myx/math/constants-inl.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef MYX_MATH_CONSTANTS_INL_HPP_
|
||||
#define MYX_MATH_CONSTANTS_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/math/constants.hpp>
|
||||
#endif
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // ifndef MYX_MATH_CONSTANTS_INL_HPP_
|
5
src/myx/math/constants.cpp
Normal file
5
src/myx/math/constants.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#include <myx/math/constants-inl.hpp>
|
25
src/myx/math/constants.hpp
Normal file
25
src/myx/math/constants.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef MYX_MATH_CONSTANTS_HPP_
|
||||
#define MYX_MATH_CONSTANTS_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
const auto ImpedanceOfFreeSpace = ( M_PI * 119.9169832 );
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "constants-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // MYX_MATH_CONSTANTS_HPP_
|
56
src/myx/math/float_cmp_types.hpp
Normal file
56
src/myx/math/float_cmp_types.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef MYX_MATH_FLOAT_CMP_TYPES_HPP_
|
||||
#define MYX_MATH_FLOAT_CMP_TYPES_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* @brief Объединение для получения знака аргумента типа float.
|
||||
*/
|
||||
union FloatCmp
|
||||
{
|
||||
int32_t i;
|
||||
float f;
|
||||
|
||||
/**
|
||||
* @brief Инициализация.
|
||||
*/
|
||||
explicit FloatCmp( float num = 0.0F ) : f( num )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция, возращающая true, если значение отрицательное
|
||||
*/
|
||||
bool negative() const
|
||||
{
|
||||
return( i < 0 );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Объединение для получения знака аргумента типа double.
|
||||
*/
|
||||
union DoubleCmp
|
||||
{
|
||||
int64_t i;
|
||||
double d;
|
||||
|
||||
/**
|
||||
* @brief Инициализация.
|
||||
*/
|
||||
explicit DoubleCmp( double num = 0.0L ) : d( num )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Функция, возращающая true, если значение отрицательное
|
||||
*/
|
||||
bool negative() const
|
||||
{
|
||||
return( i < 0 );
|
||||
}
|
||||
};
|
||||
|
||||
#endif // MYX_MATH_FLOAT_CMP_TYPES_HPP_
|
30
src/myx/math/functions.hpp
Normal file
30
src/myx/math/functions.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef MYX_MATH_FUNCTIONS_HPP_
|
||||
#define MYX_MATH_FUNCTIONS_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/math/special_functions/pow.hpp>
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
/*!
|
||||
* \brief pow2 Возведение в квадрат
|
||||
* \param value Значение
|
||||
* \return Квадрат значения
|
||||
*/
|
||||
template < typename T >
|
||||
auto pow2( T const& value ) -> decltype( boost::math::pow< 2 >( value ) )
|
||||
{
|
||||
return( boost::math::pow< 2 >( value ) );
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
|
||||
#endif // MYX_MATH_FUNCTIONS_HPP_
|
48
src/myx/math/radar.hpp
Normal file
48
src/myx/math/radar.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef MYX_MATH_RADAR_HPP_
|
||||
#define MYX_MATH_RADAR_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
/*!
|
||||
* \brief geometric_target_visibility Геометрическая видимость цели
|
||||
* \param earthRadius Радиус Земли
|
||||
* \param antennaHeight Высота антенны
|
||||
* \param targetHeight Высота цели
|
||||
* \return Максимальная дальность видимости цели
|
||||
*/
|
||||
template < typename T >
|
||||
T geometric_target_visibility( const T& earthRadius, const T& antennaHeight, const T& targetHeight )
|
||||
{
|
||||
// static_assert( std::is_arithmetic< T >::value || std::is_same< T, quantity< length_d > >::value, "Arithmetic type is required." );
|
||||
static_assert( std::is_arithmetic< T >::value, "Arithmetic type is required." );
|
||||
return ( sqrt( 2 * earthRadius * antennaHeight ) + sqrt( 2 * earthRadius * targetHeight ) );
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief radar_target_visibility Видимость цели по лучу
|
||||
* \param earthRadius Радиус Земли
|
||||
* \param antennaHeight Высота антенны
|
||||
* \param targetHeight Высота цели
|
||||
* \return Максимальная дальность видимости цели
|
||||
*/
|
||||
template < typename T >
|
||||
T radar_target_visibility( T effectiveEarthRadius, T antennaHeight, T targetHeight )
|
||||
{
|
||||
// static_assert( std::is_arithmetic< T >::value || std::is_same< T, quantity< length_d > >::value, "Arithmetic type is required." );
|
||||
static_assert( std::is_arithmetic< T >::value, "Arithmetic type is required." );
|
||||
return ( sqrt( 2 * effectiveEarthRadius * antennaHeight ) + sqrt( 2 * effectiveEarthRadius * targetHeight ) );
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_MATH_RADAR_HPP_
|
93
src/myx/math/units.hpp
Normal file
93
src/myx/math/units.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef MYX_MATH_UNITS_HPP_
|
||||
#define MYX_MATH_UNITS_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace math {
|
||||
|
||||
/*!
|
||||
* \brief radians_to_degrees Перевод из радиан в градусы
|
||||
* \param radians Значение в радианах
|
||||
* \return Значение в градусах
|
||||
*/
|
||||
template < typename T >
|
||||
T radians_to_degrees( const T& radians, typename std::enable_if< std::is_floating_point< T >::value >::type* /*unused*/ = 0 )
|
||||
{
|
||||
static_assert( std::is_arithmetic< T >::value, "Arithmetic type is required." );
|
||||
return( radians * M_1_PI * 180.0 );
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief degrees_to_radians Перевод из градусов в радианы
|
||||
* \param degrees Значение в градусах
|
||||
* \return Значение в радианах
|
||||
*/
|
||||
template < typename T >
|
||||
T degrees_to_radians( const T& degrees, typename std::enable_if< std::is_floating_point< T >::value >::type* /*unused*/ = 0 )
|
||||
{
|
||||
static_assert( std::is_arithmetic< T >::value, "Arithmetic type is required." );
|
||||
return( degrees * M_PI / 180.0 );
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief decibel_to_power Перевод из децибелов в мощность $y = 10^{db / 10}$
|
||||
* \param db Децибелы
|
||||
* \return Мощность
|
||||
*/
|
||||
template < typename T >
|
||||
T decibel_to_power( T const& db )
|
||||
{
|
||||
static_assert( std::is_arithmetic< T >::value, "Arithmetic type is required." );
|
||||
return( std::pow( 10, db / 10.0 ) );
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief power_to_decibel Перевод из мощности в децибелы по формуле $y = 10 * \log(x)$
|
||||
* \param power Мощность
|
||||
* \return Децибелы
|
||||
*/
|
||||
template < typename T >
|
||||
T power_to_decibel( T const& power )
|
||||
{
|
||||
static_assert( std::is_arithmetic< T >::value, "Arithmetic type is required." );
|
||||
return( 10 * std::log( power ) );
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief decibel_to_power Перевод из децибелов в амплитуду $y = 10^{db / 20}$
|
||||
* \param db Децибелы
|
||||
* \return Амплитуда
|
||||
*/template < typename T >
|
||||
T decibel_to_magnitude( T const& db )
|
||||
{
|
||||
static_assert( std::is_arithmetic< T >::value, "Arithmetic type is required." );
|
||||
return( std::pow( 10, db / 20.0 ) );
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief magnitude_to_decibel Перевод из амплитуды в децибелы по формуле $y = 20 * \log(x)$
|
||||
* \param magnitude Амплитуда
|
||||
* \return Децибелы
|
||||
*/
|
||||
template < typename T >
|
||||
T magnitude_to_decibel( T const& magnitude )
|
||||
{
|
||||
static_assert( std::is_arithmetic< T >::value, "Arithmetic type is required." );
|
||||
return( 20 * std::log( magnitude ) );
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_MATH_UNITS_HPP_
|
@ -9,7 +9,8 @@ set(TRGT_cpp
|
||||
# Список заголовочных файлов (используется для установки)
|
||||
set(TRGT_hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/backports.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translators.hpp)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translators.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/translators-inl.hpp)
|
||||
|
||||
set(TRGT_headers ${TRGT_hpp})
|
||||
# cmake-format: on
|
||||
@ -47,12 +48,11 @@ if(MYXLIB_BUILD_LIBRARIES)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${TRGT}_shared COMPONENT main LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
else()
|
||||
install(FILES ${TRGT_cpp} COMPONENT base-dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
||||
endif()
|
||||
|
||||
generate_pkgconfig(myx-${TRGT} COMPONENT base-dev INSTALL_LIBRARY ${MYXLIB_BUILD_LIBRARIES})
|
||||
install(FILES ${TRGT_headers} COMPONENT base-dev DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
||||
install(FILES ${TRGT_headers} COMPONENT base-dev
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${TRGT})
|
||||
|
||||
# Цель, используемая только для установки заголовочных файлов без компиляции проекта
|
||||
add_custom_target(${TRGT}-install-headers COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=base-dev -P
|
||||
|
67
src/myx/qt/translators-inl.hpp
Normal file
67
src/myx/qt/translators-inl.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef MYX_QT_TRANSLATORS_INL_HPP_
|
||||
#define MYX_QT_TRANSLATORS_INL_HPP_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/qt/translators.hpp>
|
||||
#endif
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QLibraryInfo>
|
||||
#include <QLocale>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace qt {
|
||||
|
||||
MYXLIB_INLINE void append_translators( QTranslatorsList& translators, const QString& appName )
|
||||
{
|
||||
auto* translator = new QTranslator( qApp );
|
||||
|
||||
if ( translator->load( QLocale(),
|
||||
appName, QStringLiteral( "_" ), QStringLiteral( ":/qm" ) ) )
|
||||
{
|
||||
translators.append( translator );
|
||||
}
|
||||
else
|
||||
{
|
||||
translator->deleteLater();
|
||||
}
|
||||
|
||||
translator = new QTranslator( qApp );
|
||||
if ( translator->load( QLocale::system(),
|
||||
QStringLiteral( "qt" ), QStringLiteral( "_" ),
|
||||
QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
|
||||
{
|
||||
translators.append( translator );
|
||||
}
|
||||
else
|
||||
{
|
||||
translator->deleteLater();
|
||||
}
|
||||
|
||||
translator = new QTranslator( qApp );
|
||||
if ( translator->load( "qtbase_" + QLocale::system().name(),
|
||||
QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
|
||||
{
|
||||
translators.append( translator );
|
||||
}
|
||||
else
|
||||
{
|
||||
translator->deleteLater();
|
||||
}
|
||||
|
||||
for ( auto* i : qAsConst( translators ) )
|
||||
{
|
||||
qApp->installTranslator( i );
|
||||
}
|
||||
} // append_translators
|
||||
|
||||
} // namespace qt
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_QT_TRANSLATORS_INL_HPP_
|
@ -1,67 +1,5 @@
|
||||
#ifndef MYX_QT_TRANSLATORS_CPP_
|
||||
#define MYX_QT_TRANSLATORS_CPP_
|
||||
|
||||
#include <myx/base/config.hpp>
|
||||
|
||||
#ifndef MYXLIB_HEADER_ONLY
|
||||
#include <myx/qt/translators.hpp>
|
||||
#else
|
||||
#pragma once
|
||||
#ifndef MYXLIB_BUILD_LIBRARIES
|
||||
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
|
||||
#endif
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QLibraryInfo>
|
||||
#include <QLocale>
|
||||
|
||||
namespace myx {
|
||||
|
||||
namespace qt {
|
||||
|
||||
MYXLIB_INLINE void append_translators( QTranslatorsList& translators, const QString& appName )
|
||||
{
|
||||
auto* translator = new QTranslator( qApp );
|
||||
|
||||
if ( translator->load( QLocale(),
|
||||
appName, QStringLiteral( "_" ), QStringLiteral( ":/qm" ) ) )
|
||||
{
|
||||
translators.append( translator );
|
||||
}
|
||||
else
|
||||
{
|
||||
translator->deleteLater();
|
||||
}
|
||||
|
||||
translator = new QTranslator( qApp );
|
||||
if ( translator->load( QLocale::system(),
|
||||
QStringLiteral( "qt" ), QStringLiteral( "_" ),
|
||||
QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
|
||||
{
|
||||
translators.append( translator );
|
||||
}
|
||||
else
|
||||
{
|
||||
translator->deleteLater();
|
||||
}
|
||||
|
||||
translator = new QTranslator( qApp );
|
||||
if ( translator->load( "qtbase_" + QLocale::system().name(),
|
||||
QLibraryInfo::location( QLibraryInfo::TranslationsPath ) ) )
|
||||
{
|
||||
translators.append( translator );
|
||||
}
|
||||
else
|
||||
{
|
||||
translator->deleteLater();
|
||||
}
|
||||
|
||||
for ( auto* i : qAsConst( translators ) )
|
||||
{
|
||||
qApp->installTranslator( i );
|
||||
}
|
||||
} // append_translators
|
||||
|
||||
} // namespace qt
|
||||
|
||||
} // namespace myx
|
||||
|
||||
#endif // MYX_QT_TRANSLATORS_CPP_
|
||||
#include <myx/qt/translators-inl.hpp>
|
||||
|
@ -21,7 +21,7 @@ void append_translators( QTranslatorsList& translators, const QString& appName )
|
||||
} // namespace myx
|
||||
|
||||
#ifdef MYXLIB_HEADER_ONLY
|
||||
#include "translators.cpp"
|
||||
#include "translators-inl.hpp"
|
||||
#endif
|
||||
|
||||
#endif // ifndef MYX_QT_TRANSLATORS_HPP_
|
||||
|
Loading…
Reference in New Issue
Block a user