Обновление

This commit is contained in:
Andrei Astafev 2020-04-27 10:25:29 +03:00
parent 94616ba6bc
commit d264077648
34 changed files with 836 additions and 889 deletions

View File

@ -9,7 +9,6 @@ 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)
@ -47,6 +46,8 @@ 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})

View File

@ -1,10 +0,0 @@
#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_

View File

@ -1,5 +1,10 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#ifndef MYX_BASE_CONFIG_CPP_
#define MYX_BASE_CONFIG_CPP_
#ifndef MYXLIB_HEADER_ONLY
#include <myx/base/config.hpp>
#else
#pragma once
#endif
#include <myx/base/config-inl.hpp>
#endif // MYX_BASE_CONFIG_CPP_

View File

@ -23,7 +23,7 @@
#endif // ifdef MYXLIB_BUILD_LIBRARIES
#ifdef MYXLIB_HEADER_ONLY
#include "config-inl.hpp"
#include "config.cpp"
#endif
#endif // MYX_BASE_CONFIG_HPP_

View File

@ -12,10 +12,7 @@ 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}/current_executable-inl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/paths-inl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt-inl.hpp)
${CMAKE_CURRENT_SOURCE_DIR}/paths_mt.hpp)
set(TRGT_headers ${TRGT_hpp})
# cmake-format: on
@ -54,6 +51,8 @@ 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})

View File

@ -1,41 +0,0 @@
#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_

View File

@ -1,5 +1,41 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#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
#endif
#include <myx/filesystem/current_executable-inl.hpp>
#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_

View File

@ -45,7 +45,7 @@ public:
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "current_executable-inl.hpp"
#include "current_executable.cpp"
#endif
#endif // MYX_FILESYSTEM_CURRENT_EXECUTABLE_HPP_

View File

@ -1,359 +0,0 @@
#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_

View File

@ -1,5 +1,359 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#ifndef MYX_BASE_PATHS_CPP_
#define MYX_BASE_PATHS_CPP_
#ifndef MYXLIB_HEADER_ONLY
#include <myx/filesystem/paths.hpp>
#else
#pragma once
#endif
#include <myx/filesystem/paths-inl.hpp>
#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_CPP_

View File

@ -223,7 +223,7 @@ public:
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "paths-inl.hpp"
#include "paths.cpp"
#endif
#endif // MYX_FILESYSTEM_PATHS_HPP_

View File

@ -1,44 +0,0 @@
#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_

View File

@ -1,5 +1,44 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#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
#endif
#include <myx/filesystem/paths_mt-inl.hpp>
#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_CPP_

View File

@ -53,7 +53,7 @@ public:
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "paths_mt-inl.hpp"
#include "paths_mt.cpp"
#endif
#endif // MYX_FILESYSTEM_PATHS_MT_HPP_

View File

@ -14,15 +14,10 @@ set(TRGT_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
@ -65,6 +60,8 @@ 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})

View File

@ -1,51 +0,0 @@
#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_

View File

@ -1,5 +1,51 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_CPP_
#define MYX_MATH_ALMOST_EQUAL_RELATIVE_CPP_
#ifndef MYXLIB_HEADER_ONLY
#include <myx/math/almost_equal_relative.hpp>
#else
#pragma once
#endif
#include <myx/math/almost_equal_relative-inl.hpp>
#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_CPP_

View File

@ -33,7 +33,7 @@ bool almost_equal_relative( double a, double b,
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "almost_equal_relative-inl.hpp"
#include "almost_equal_relative.cpp"
#endif
#endif // MYX_MATH_ALMOST_EQUAL_RELATIVE_HPP_

View File

@ -1,65 +0,0 @@
#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_

View File

@ -1,5 +1,65 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#ifndef MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_CPP_
#define MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_CPP_
#ifndef MYXLIB_HEADER_ONLY
#include <myx/math/almost_equal_relative_and_abs.hpp>
#else
#pragma once
#endif
#include <myx/math/almost_equal_relative_and_abs-inl.hpp>
#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_CPP_

View File

@ -33,7 +33,7 @@ bool almost_equal_relative_and_abs( double a, double b,
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "almost_equal_relative_and_abs-inl.hpp"
#include "almost_equal_relative_and_abs.cpp"
#endif
#endif // MYX_MATH_ALMOST_EQUAL_RELATIVE_AND_ABS_HPP_

View File

@ -1,93 +0,0 @@
#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_

View File

@ -1,5 +1,93 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#ifndef MYX_MATH_ALMOST_EQUAL_ULPS_CPP_
#define MYX_MATH_ALMOST_EQUAL_ULPS_CPP_
#ifndef MYXLIB_HEADER_ONLY
#include <myx/math/almost_equal_ulps.hpp>
#else
#pragma once
#endif
#include <myx/math/almost_equal_ulps-inl.hpp>
#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_CPP_

View File

@ -32,7 +32,7 @@ bool almost_equal_ulps( double a, double b,
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "almost_equal_ulps-inl.hpp"
#include "almost_equal_ulps.cpp"
#endif
#endif // MYX_MATH_ALMOST_EQUAL_ULPS_HPP_

View File

@ -1,87 +0,0 @@
#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_

View File

@ -1,5 +1,87 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#ifndef MYX_MATH_ALMOST_EQUAL_ULPS_CPP_
#define MYX_MATH_ALMOST_EQUAL_ULPS_CPP_
#ifndef MYXLIB_HEADER_ONLY
#include <myx/math/almost_equal_ulps_and_abs.hpp>
#else
#pragma once
#endif
#include <myx/math/almost_equal_ulps_and_abs-inl.hpp>
#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_CPP_

View File

@ -31,7 +31,7 @@ bool almost_equal_ulps_and_abs( double a, double b,
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "almost_equal_ulps_and_abs-inl.hpp"
#include "almost_equal_ulps_and_abs.cpp"
#endif
#endif // MYX_MATH_ALMOST_EQUAL_ULPS_HPP_

View File

@ -1,18 +0,0 @@
#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_

View File

@ -1,5 +1,18 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#ifndef MYX_MATH_CONSTANTS_CPP_
#define MYX_MATH_CONSTANTS_CPP_
#ifndef MYXLIB_HEADER_ONLY
#include <myx/math/constants.hpp>
#else
#pragma once
#endif
#include <myx/math/constants-inl.hpp>
namespace myx {
namespace math {
} // namespace math
} // namespace myx
#endif // ifndef MYX_MATH_CONSTANTS_CPP_

View File

@ -19,7 +19,7 @@ const auto ImpedanceOfFreeSpace = ( M_PI * 119.9169832 );
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "constants-inl.hpp"
#include "constants.cpp"
#endif
#endif // MYX_MATH_CONSTANTS_HPP_

View File

@ -9,8 +9,7 @@ set(TRGT_cpp
# Список заголовочных файлов (используется для установки)
set(TRGT_hpp
${CMAKE_CURRENT_SOURCE_DIR}/backports.hpp
${CMAKE_CURRENT_SOURCE_DIR}/translators.hpp
${CMAKE_CURRENT_SOURCE_DIR}/translators-inl.hpp)
${CMAKE_CURRENT_SOURCE_DIR}/translators.hpp)
set(TRGT_headers ${TRGT_hpp})
# cmake-format: on
@ -48,11 +47,12 @@ 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

View File

@ -1,67 +0,0 @@
#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_

View File

@ -1,5 +1,67 @@
#ifndef MYXLIB_BUILD_LIBRARIES
#error Define MYXLIB_BUILD_LIBRARIES to compile this file.
#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
#endif
#include <myx/qt/translators-inl.hpp>
#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_

View File

@ -21,7 +21,7 @@ void append_translators( QTranslatorsList& translators, const QString& appName )
} // namespace myx
#ifdef MYXLIB_HEADER_ONLY
#include "translators-inl.hpp"
#include "translators.cpp"
#endif
#endif // ifndef MYX_QT_TRANSLATORS_HPP_