64 Commits

Author SHA1 Message Date
Шишов Максим Денисович
0ce6afa43c bug fixes 2020-09-10 17:48:39 +03:00
Шишов Максим Денисович
5bec25a628 bug fixes 2020-09-10 17:48:16 +03:00
Шишов Максим Денисович
7acc2f6b2f indentation in strings 2020-09-10 17:13:02 +03:00
Шишов Максим Денисович
641633f6f0 overall PIMathMatrix tests correction 2020-09-10 16:56:04 +03:00
Шишов Максим Денисович
f98874401f testing another operations 2020-09-10 15:27:09 +03:00
Шишов Максим Денисович
58a132a3a5 PIMathMatrix new tests version 2020-09-10 13:11:31 +03:00
Шишов Максим Денисович
98f77d90cd tests correction 2020-09-10 10:52:09 +03:00
Шишов Максим Денисович
ab16bb3ce0 final tab correction 2020-09-08 16:47:44 +03:00
Шишов Максим Денисович
6d83790358 tab correction 2020-09-08 16:44:01 +03:00
Шишов Максим Денисович
05a32ccf1a doc correction 2020-09-08 16:05:22 +03:00
f1a0a3ec4a Fix code formatting & grammar mistakes 2020-09-03 16:57:46 +03:00
Шишов Максим Денисович
8e7d7a54c4 space correction 2020-09-03 15:50:41 +03:00
Шишов Максим Денисович
9544d5ef0d Rotation remake 2020-09-03 15:23:54 +03:00
Шишов Максим Денисович
4d03ba1210 PIMathMatrix document 2020-09-03 13:54:47 +03:00
Шишов Максим Денисович
defbe3a4d7 PIMathMatrix doc 2020-09-03 13:54:02 +03:00
Шишов Максим Денисович
2913fc284b Merge with pip 3 2020-09-01 12:54:02 +03:00
Шишов Максим Денисович
3dd08bf944 Merge with pip 3 2020-09-01 12:38:13 +03:00
Шишов Максим Денисович
fcf91a26b6 Tests update 2020-09-01 12:10:56 +03:00
a4b3edb3e1 Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-08-31 17:53:26 +03:00
6be22ac39f reemove piSwapBinary 2020-08-31 17:53:18 +03:00
37de1ec099 Merge pull request 'Fixed PIConditionVariable timeout bug on Linux' (#33) from cond_fix into master
Reviewed-on: https://git.shs.tools/SHS/pip/pulls/33
2020-08-31 16:41:59 +03:00
32d060c8ce int 2020-08-31 16:41:01 +03:00
7065cbd9ee Fixed PIConditionVariable timeout bug on Linux 2020-08-31 16:01:35 +03:00
c5f70f4e09 picloud 2020-08-28 17:49:58 +03:00
234d4e73be picloud 2020-08-27 19:40:11 +03:00
e1f2c90790 version 2020-08-26 18:45:27 +03:00
93cf55d323 Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-08-26 18:43:40 +03:00
2ef0ca6946 PIIODevice destructor fix 2020-08-26 18:43:33 +03:00
73bfe03433 PIEthernet disctonnect fix 2020-08-26 18:10:58 +03:00
2a42d2a341 Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-08-26 18:01:23 +03:00
7f2c82dc69 PIEthernet reconnect 2020-08-26 18:01:17 +03:00
fa0475cac6 PIEthernet disctonnect fix 2020-08-26 17:59:28 +03:00
cfebf8cf23 cloud test 2020-08-26 17:28:56 +03:00
3965e54e38 start develop picloud 2020-08-24 13:23:31 +03:00
f033119a8b version 2.3.0_beta
optimize PIChunkStream::readAll()
optimize PIEvaluator
2020-08-24 02:08:23 +03:00
6b70045914 CMake set_version fix 2020-08-21 22:12:11 +03:00
cc580d9385 Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-08-19 16:48:17 +03:00
05607ccf0e static_assert 2020-08-19 16:48:08 +03:00
fec68299c1 remove install duplicate 2020-08-19 16:22:01 +03:00
ccd6a9888f tree changes 2020-08-19 00:47:05 +03:00
c582d8ff46 PIStringList new constructor 2020-08-18 22:58:30 +03:00
9834ac177b debian version fix, "Maj.Min.Rev-Build-suffix" instead of "Maj.Min.Rev-suffix-Build" 2020-08-15 21:24:57 +03:00
31f0d88157 version 2.2.1
std::initializer_list supports for vector and dequeue
2020-08-14 18:00:28 +03:00
e76a07a3f3 binlog fixes 2020-08-13 18:03:25 +03:00
31a347250f version 2.2.0
remove deprecated members
PIVariantTypes::File add "is_save" flag
PIBinaryLog clear
2020-08-13 12:59:29 +03:00
294831df17 binlog user header 2020-08-12 20:01:24 +03:00
e77d3a86a9 opencl MacOS fix 2020-08-11 21:18:51 +03:00
66010c83eb export headers workaround 2020-08-11 20:59:12 +03:00
57a9ccb854 version 2.0.0_prealpha
PIFile::put() and get()
2020-08-11 20:09:34 +03:00
3ba6a7b0e8 rename PIBlockingDequeue -> PIBlockingQueue 2020-08-11 19:05:47 +03:00
8c3349d84a fix PIThreadPoolExecutor and PIBlockingDequeue 2020-08-11 17:26:44 +03:00
dac318c624 <T>_MAKE_VERSION macro add in "set_version()" CMake generated header 2020-08-06 17:25:16 +03:00
e08f805525 small fixes 2020-08-06 15:17:15 +03:00
26742a1fc3 PIFile::readAll patch 2020-08-06 15:01:31 +03:00
70a7363f76 some features
in main.cpp fastest Variant implementation
2020-08-05 00:53:27 +03:00
8405b564a4 Merged master and tests 2020-07-27 12:41:53 +03:00
Шишов Максим Денисович
494b09847e Merge branch 'tests' of https://git.shs.tools/SHS/pip into tests 2020-07-24 15:58:05 +03:00
Шишов Максим Денисович
f1951ee711 CMAKE NEEEEEW 2020-07-24 15:56:51 +03:00
c3257c7c50 Удалить 'CMakeLists.txt.user' 2020-07-24 15:28:11 +03:00
Шишов Максим Денисович
13bafdc7c1 core test 2020-07-24 15:26:37 +03:00
Шишов Максим Денисович
f71fbb0068 new cmake 2020-07-24 15:24:13 +03:00
Шишов Максим Денисович
bb635f6c51 matrix testing 2020-07-23 17:29:37 +03:00
Шишов Максим Денисович
d8e47afe13 matrix tests 2020-07-23 17:28:10 +03:00
dbb84885e3 pimatmatrix test 2020-07-16 16:33:31 +03:00
257 changed files with 3569 additions and 1189 deletions

View File

@@ -1,10 +1,10 @@
cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(pip)
set(_PIP_MAJOR 1)
set(_PIP_MINOR 99)
set(_PIP_REVISION 3)
set(_PIP_SUFFIX _prebeta)
set(_PIP_MAJOR 2)
set(_PIP_MINOR 5)
set(_PIP_REVISION 0)
set(_PIP_SUFFIX _beta)
set(_PIP_COMPANY SHS)
set(_PIP_DOMAIN org.SHS)
@@ -66,10 +66,10 @@ macro(pip_module NAME LIBS LABEL INCLUDES MSG)
set(HS)
set(PHS)
set(CRES)
file(GLOB_RECURSE CPPS "lib/${NAME}/*.cpp")
file(GLOB_RECURSE HS "lib/${NAME}/*.h")
file(GLOB_RECURSE PHS "lib/${NAME}/*_p.h")
file(GLOB_RECURSE RES "lib/${NAME}/*conf.h")
file(GLOB_RECURSE CPPS "libs/${NAME}/*.cpp")
file(GLOB_RECURSE HS "libs/${NAME}/*.h")
file(GLOB_RECURSE PHS "libs/${NAME}/*_p.h")
file(GLOB_RECURSE RES "libs/${NAME}/*conf.h")
list(REMOVE_ITEM HS "${PHS}")
list(APPEND HDRS ${HS})
list(APPEND PHDRS ${PHS})
@@ -112,8 +112,6 @@ macro(pip_module NAME LIBS LABEL INCLUDES MSG)
if (NOT "${INCLUDES}" STREQUAL "")
target_include_directories(${_target} PRIVATE ${INCLUDES})
endif()
generate_export_header(${_target})
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/${_target}_export.h")
list(APPEND PIP_EXPORTS "${DEF_NAME}_EXPORT")
target_link_libraries(${_target} ${LINK_LIBS})
list(APPEND PIP_MODULES ${_target})
@@ -210,8 +208,8 @@ get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME)
# Main lib
file(GLOB PIP_FOLDERS LIST_DIRECTORIES TRUE "${CMAKE_CURRENT_SOURCE_DIR}/lib/main/*")
list(APPEND PIP_FOLDERS "${CMAKE_CURRENT_SOURCE_DIR}/lib/main")
file(GLOB PIP_FOLDERS LIST_DIRECTORIES TRUE "${CMAKE_CURRENT_SOURCE_DIR}/libs/main/*")
list(APPEND PIP_FOLDERS "${CMAKE_CURRENT_SOURCE_DIR}/libs/main")
set(PIP_MAIN_FOLDERS)
foreach(F ${PIP_FOLDERS})
if (IS_DIRECTORY "${F}")
@@ -384,6 +382,15 @@ set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}")
pip_module(main "${LIBS_MAIN}" "PIP main library" "" "")
generate_export_header(pip)
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_export.h")
foreach(_m ${PIP_SRC_MODULES})
set_target_properties(pip PROPERTIES DEFINE_SYMBOL pip_${_m}_EXPORTS)
generate_export_header(pip BASE_NAME "pip_${_m}")
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_${_m}_export.h")
endforeach()
set_target_properties(pip PROPERTIES DEFINE_SYMBOL pip_EXPORTS)
if (NOT CROSSTOOLS)
if (NOT PIP_FREERTOS)
@@ -462,7 +469,11 @@ if (NOT CROSSTOOLS)
if(${CMAKE_VERSION} VERSION_LESS "3.7.0")
target_link_libraries(_opencl_lib OpenCL)
endif()
pip_module(opencl "${_opencl_lib}" "PIP OpenCL support" "" " (${OpenCL_VERSION_STRING})")
set(_opencl_inc "${OpenCL_INCLUDE_DIRS}")
if(APPLE)
set(_opencl_inc "${OpenCL_INCLUDE_DIRS}/Headers")
endif()
pip_module(opencl "${_opencl_lib}" "PIP OpenCL support" "${_opencl_inc}" " (${OpenCL_VERSION_STRING})")
endif()
@@ -479,15 +490,15 @@ if (NOT CROSSTOOLS)
endif()
find_package(Lua QUIET)
if (LUA_FOUND)
pip_module(lua "LUA" "PIP Lua support" "${LUA_INCLUDE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd" " (${LUA_VERSION_STRING})")
list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd/LuaBridge")
pip_module(lua "LUA" "PIP Lua support" "${LUA_INCLUDE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd" " (${LUA_VERSION_STRING})")
list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd/LuaBridge")
endif()
# Test program
if(PIP_UTILS)
add_executable(pip_test "main.cpp")
target_link_libraries(pip_test pip)
target_link_libraries(pip_test pip pip_cloud)
if (LUA_FOUND)
target_link_libraries(pip_test pip_lua ${LUA_LIBRARIES})
endif()
@@ -524,7 +535,6 @@ if(LIB)
if(WIN32)
if(MINGW)
if (NOT CROSSTOOLS)
install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip)
install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip)
if(HDR_DIRS)
install(DIRECTORY ${HDR_DIRS} DESTINATION ${MINGW_INCLUDE}/pip)
@@ -612,7 +622,7 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
set(DOXY_QHP_SECT_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"")
set(DOXY_EXAMPLE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/examples\"")
set(DOXY_IMAGE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/images\"")
set(DOXY_EXCLUDE "\"${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd\"")
set(DOXY_EXCLUDE "\"${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd\"")
if(DOXYGEN_DOT_EXECUTABLE)
string(REPLACE "\\" "" _DOT_PATH "${DOXYGEN_DOT_PATH}")
set(DOXY_DOT_PATH "\"${_DOT_PATH}\"")
@@ -623,7 +633,7 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
foreach(F ${PIP_MAIN_FOLDERS})
list(APPEND DOXY_INPUT "\"${F}\"")
endforeach(F)
string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/lib\"")
string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/libs\"")
string(REPLACE ";" " " DOXY_INCLUDE_PATH "${DOXY_INPUT}")
string(REPLACE ";" " " DOXY_DEFINES "${PIP_EXPORTS};DOXYGEN;PIOBJECT;PIOBJECT_SUBCLASS")
add_documentation(doc doc/Doxyfile.in)
@@ -632,6 +642,23 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
endif()
set(_max_len 0)
foreach(_m ${PIP_SRC_MODULES})
string(LENGTH "${_m}" _clen)
if (_clen GREATER _max_len)
set(_max_len ${_clen})
endif()
endforeach()
macro(expand_to_length _out _str _len)
set(${_out} "${_str}")
while(TRUE)
string(LENGTH "${${_out}}" _clen)
if (_clen GREATER_EQUAL ${_len})
break()
endif()
string(APPEND ${_out} " ")
endwhile()
endmacro()
list(REMOVE_ITEM LIBS_STATUS ${PIP_MODULES})
message("----------PIP----------")
@@ -657,7 +684,8 @@ endif()
message("")
message(" Modules:")
foreach(_m ${PIP_SRC_MODULES})
message(" ${_m}: ${PIP_MSG_${_m}}")
expand_to_length(_m_e "${_m}" ${_max_len})
message(" ${_m_e}: ${PIP_MSG_${_m}}")
endforeach()
message("")
if (PIP_TESTS_LIST)

View File

@@ -14,7 +14,9 @@ Create variable <target>_VERSION with full version name
If OUTPUT then generate header <file> with
version macros - <target>_VERSION_<NAME>
Also create macro <target>_VERSION_NAME with full string version
Also create macro <target>_VERSION_NAME with full string version and
macro <target>_MAKE_VERSION(major, minor, revision) that returns
byte-packed integer version.
Attention: macro <target>_VERSION is byte-packed integer version!
@@ -165,11 +167,12 @@ set(_dt_delim "::")
macro(set_version _T)
set(_VERSION_ 1) # macro version
set(_VERSION_ 2) # macro version
set(_name)
set(_is_name 1)
set(_is_out 0)
set(_out)
#message("set_version \"${_T}\"")
foreach(_i ${ARGN})
if (_is_out)
set(_is_out 0)
@@ -177,13 +180,16 @@ macro(set_version _T)
elseif ("x${_i}" STREQUAL "xOUTPUT")
set(_is_out 1)
elseif(_is_name)
#message("set_version component \"${_i}\"")
set(_is_name 0)
if (_i IN_LIST __version_names)
else()
message(FATAL_ERROR "Invalid version component \"${_i}\"!")
endif()
set(_name ${_i})
set(${_T}_VERSION_${_name})
else()
#message("set_version value \"${_name}\" = \"${_i}\"")
set(_is_name 1)
set(${_T}_VERSION_${_name} ${_i})
endif()
@@ -239,7 +245,8 @@ macro(set_version _T)
#define ${_TN}_VERSION_BUILD ${${_T}_VERSION_BUILD}
#define ${_TN}_VERSION_SUFFIX \"${${_T}_VERSION_SUFFIX}\"
#define ${_TN}_VERSION_NAME \"${${_T}_VERSION}\"
#define ${_TN}_VERSION ((${_TN}_VERSION_MAJOR << 16) | (${_TN}_VERSION_MINOR << 8) | ${_TN}_VERSION_REVISION)
#define ${_TN}_MAKE_VERSION(major, minor, revision) ((major << 16) | (minor << 8) | revision)
#define ${_TN}_VERSION ${_TN}_MAKE_VERSION(${_TN}_VERSION_MAJOR, ${_TN}_VERSION_MINOR, ${_TN}_VERSION_REVISION)
// Tools
@@ -656,7 +663,8 @@ macro(deploy_target _T)
set(_TARGET_OS "linux")
endif()
string(REPLACE "_" "-" _DEBNAME "${_T}")
string(REPLACE "_" "-" _DEBVERSION "${${_T}_VERSION}${_build}+${_TARGET_OS}")
set(_DEBVERSION "${${_T}_VERSION_MAJOR}.${${_T}_VERSION_MINOR}.${${_T}_VERSION_REVISION}${_build}${${_T}_VERSION_FULLSUFFIX}+${_TARGET_OS}")
string(REPLACE "_" "-" _DEBVERSION "${_DEBVERSION}")
string(TOLOWER "${_DEBNAME}" _DEBNAME)
set(_DEB_ARCH)
if("_${MY_ARCH}" STREQUAL "_arm64")

View File

@@ -49,6 +49,9 @@ PIVector<char> vec(4u, 'p');
piForeachC (char i, vec)
cout << i << ", ";
// p, p, p, p,
piCout << PIVector<int>({1, 2, 3});
// 1, 2, 3
//! [PIVector::PIVector]
//! [PIVector::at_c]
PIVector<int> vec;

View File

@@ -1,25 +0,0 @@
/*
PIP - Platform Independent Primitives
PICloud Server
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piccloudserver.h"
PICloudServer::PICloudServer() {
}

View File

@@ -1,40 +0,0 @@
/*! \file piccloudserver.h
* \brief PICloud Server
*/
/*
PIP - Platform Independent Primitives
PICloud Server
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICCLOUDSERVER_H
#define PICCLOUDSERVER_H
#include "pip_cloud_export.h"
#include "piiodevice.h"
class PIP_CLOUD_EXPORT PICloudServer {
public:
//!
explicit PICloudServer();
private:
};
#endif // PICCLOUDSERVER_H

View File

@@ -1,574 +0,0 @@
/*! \file pimathmatrix.h
* \brief PIMathMatrix
*/
/*
PIP - Platform Independent Primitives
PIMathMatrix
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIMATHMATRIX_H
#define PIMATHMATRIX_H
#include "pimathvector.h"
#include "pimathcomplex.h"
template<typename T>
inline bool _PIMathMatrixNullCompare(const T v) {
return (piAbs(v) < T(1E-200));
}
template<>
inline bool _PIMathMatrixNullCompare<complexf >(const complexf v) {
return (abs(v) < float(1E-200));
}
template<>
inline bool _PIMathMatrixNullCompare<complexd >(const complexd v) {
return (abs(v) < double(1E-200));
}
/// Matrix templated
#define PIMM_FOR(r, c) for (uint c = 0; c < Cols; ++c) { for (uint r = 0; r < Rows; ++r) {
#define PIMM_FOR_WB(r, c) for (uint c = 0; c < Cols; ++c) for (uint r = 0; r < Rows; ++r) // without brakes
#define PIMM_FOR_I(r, c) for (uint r = 0; r < Rows; ++r) { for (uint c = 0; c < Cols; ++c) {
#define PIMM_FOR_I_WB(r, c) for (uint r = 0; r < Rows; ++r) for (uint c = 0; c < Cols; ++c) // without brakes
#define PIMM_FOR_C(v) for (uint v = 0; v < Cols; ++v)
#define PIMM_FOR_R(v) for (uint v = 0; v < Rows; ++v)
#pragma pack(push, 1)
template<uint Rows, uint Cols = Rows, typename Type = double>
class PIP_EXPORT PIMathMatrixT {
typedef PIMathMatrixT<Rows, Cols, Type> _CMatrix;
typedef PIMathMatrixT<Cols, Rows, Type> _CMatrixI;
typedef PIMathVectorT<Rows, Type> _CMCol;
typedef PIMathVectorT<Cols, Type> _CMRow;
public:
PIMathMatrixT() {resize(Rows, Cols);}
PIMathMatrixT(const PIVector<Type> & val) {resize(Rows, Cols); int i = 0; PIMM_FOR_I_WB(r, c) m[r][c] = val[i++];}
static _CMatrix identity() {_CMatrix tm = _CMatrix(); PIMM_FOR_WB(r, c) tm.m[r][c] = (c == r ? Type(1) : Type(0)); return tm;}
static _CMatrix filled(const Type & v) {_CMatrix tm; PIMM_FOR_WB(r, c) tm.m[r][c] = v; return tm;}
static _CMatrix rotation(double angle) {return _CMatrix();}
static _CMatrix rotationX(double angle) {return _CMatrix();}
static _CMatrix rotationY(double angle) {return _CMatrix();}
static _CMatrix rotationZ(double angle) {return _CMatrix();}
static _CMatrix scaleX(double factor) {return _CMatrix();}
static _CMatrix scaleY(double factor) {return _CMatrix();}
static _CMatrix scaleZ(double factor) {return _CMatrix();}
uint cols() const {return Cols;}
uint rows() const {return Rows;}
_CMCol col(uint index) {_CMCol tv; PIMM_FOR_R(i) tv[i] = m[i][index]; return tv;}
_CMRow row(uint index) {_CMRow tv; PIMM_FOR_C(i) tv[i] = m[index][i]; return tv;}
_CMatrix & setCol(uint index, const _CMCol & v) {PIMM_FOR_R(i) m[i][index] = v[i]; return *this;}
_CMatrix & setRow(uint index, const _CMRow & v) {PIMM_FOR_C(i) m[index][i] = v[i]; return *this;}
_CMatrix & swapRows(uint r0, uint r1) {Type t; PIMM_FOR_C(i) {t = m[r0][i]; m[r0][i] = m[r1][i]; m[r1][i] = t;} return *this;}
_CMatrix & swapCols(uint c0, uint c1) {Type t; PIMM_FOR_R(i) {t = m[i][c0]; m[i][c0] = m[i][c1]; m[i][c1] = t;} return *this;}
_CMatrix & fill(const Type & v) {PIMM_FOR_WB(r, c) m[r][c] = v; return *this;}
bool isSquare() const {return cols() == rows();}
bool isIdentity() const {PIMM_FOR_WB(r, c) if ((c == r) ? m[r][c] != Type(1) : m[r][c] != Type(0)) return false; return true;}
bool isNull() const {PIMM_FOR_WB(r, c) if (m[r][c] != Type(0)) return false; return true;}
Type & at(uint row, uint col) {return m[row][col];}
Type at(uint row, uint col) const {return m[row][col];}
Type * operator [](uint row) {return m[row];}
const Type * operator [](uint row) const {return m[row];}
_CMatrix & operator =(const _CMatrix & sm) {memcpy(m, sm.m, sizeof(Type) * Cols * Rows); return *this;}
bool operator ==(const _CMatrix & sm) const {PIMM_FOR_WB(r, c) if (m[r][c] != sm.m[r][c]) return false; return true;}
bool operator !=(const _CMatrix & sm) const {return !(*this == sm);}
void operator +=(const _CMatrix & sm) {PIMM_FOR_WB(r, c) m[r][c] += sm.m[r][c];}
void operator -=(const _CMatrix & sm) {PIMM_FOR_WB(r, c) m[r][c] -= sm.m[r][c];}
void operator *=(const Type & v) {PIMM_FOR_WB(r, c) m[r][c] *= v;}
void operator /=(const Type & v) {PIMM_FOR_WB(r, c) m[r][c] /= v;}
_CMatrix operator -() const {_CMatrix tm; PIMM_FOR_WB(r, c) tm.m[r][c] = -m[r][c]; return tm;}
_CMatrix operator +(const _CMatrix & sm) const {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(r, c) tm.m[r][c] += sm.m[r][c]; return tm;}
_CMatrix operator -(const _CMatrix & sm) const {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(r, c) tm.m[r][c] -= sm.m[r][c]; return tm;}
_CMatrix operator *(const Type & v) const {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(r, c) tm.m[r][c] *= v; return tm;}
_CMatrix operator /(const Type & v) const {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(r, c) tm.m[r][c] /= v; return tm;}
Type determinant(bool * ok = 0) const {
_CMatrix m(*this);
bool k;
Type ret = Type(0);
m.toUpperTriangular(&k);
if (ok) *ok = k;
if (!k) return ret;
ret = Type(1);
for (uint c = 0; c < Cols; ++c)
for (uint r = 0; r < Rows; ++r)
if (r == c)
ret *= m[r][c];
return ret;
}
_CMatrix & toUpperTriangular(bool * ok = 0) {
if (Cols != Rows) {
if (ok != 0) *ok = false;
return *this;
}
_CMatrix smat(*this);
bool ndet;
uint crow;
Type mul;
for (uint i = 0; i < Cols; ++i) {
ndet = true;
for (uint j = 0; j < Rows; ++j) if (smat.m[i][j] != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
}
for (uint i = 0; i < Cols; ++i) {
crow = i;
while (smat.m[i][i] == Type(0))
smat.swapRows(i, ++crow);
for (uint j = i + 1; j < Rows; ++j) {
mul = smat.m[i][j] / smat.m[i][i];
for (uint k = i; k < Cols; ++k) smat.m[k][j] -= mul * smat.m[k][i];
}
if (i < Cols - 1) {
if (fabs(smat.m[i+1][i+1]) < Type(1E-200)) {
if (ok != 0) *ok = false;
return *this;
}
}
}
if (ok != 0) *ok = true;
memcpy(m, smat.m, sizeof(Type) * Cols * Rows);
return *this;
}
_CMatrix & invert(bool * ok = 0) {
if (Cols != Rows) {
if (ok != 0) *ok = false;
return *this;
}
_CMatrix mtmp = _CMatrix::identity(), smat(*this);
bool ndet;
uint crow;
Type mul, iddiv;
for (uint i = 0; i < Cols; ++i) {
ndet = true;
for (uint j = 0; j < Rows; ++j) if (smat.m[i][j] != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
}
for (uint i = 0; i < Cols; ++i) {
crow = i;
while (smat.m[i][i] == Type(0)) {
++crow;
smat.swapRows(i, crow);
mtmp.swapRows(i, crow);
}
for (uint j = i + 1; j < Rows; ++j) {
mul = smat.m[i][j] / smat.m[i][i];
for (uint k = i; k < Cols; ++k) smat.m[k][j] -= mul * smat.m[k][i];
for (uint k = 0; k < Cols; ++k) mtmp.m[k][j] -= mul * mtmp.m[k][i];
}
if (i < Cols - 1) {
if (fabs(smat.m[i+1][i+1]) < Type(1E-200)) {
if (ok != 0) *ok = false;
return *this;
}
}
iddiv = smat.m[i][i];
for (uint j = i; j < Cols; ++j) smat.m[j][i] /= iddiv;
for (uint j = 0; j < Cols; ++j) mtmp.m[j][i] /= iddiv;
}
for (uint i = Cols - 1; i > 0; --i) {
for (uint j = 0; j < i; ++j) {
mul = smat.m[i][j];
smat.m[i][j] -= mul;
for (uint k = 0; k < Cols; ++k) mtmp.m[k][j] -= mtmp.m[k][i] * mul;
}
}
if (ok != 0) *ok = true;
memcpy(m, mtmp.m, sizeof(Type) * Cols * Rows);
return *this;
}
_CMatrix inverted(bool * ok = 0) const {_CMatrix tm(*this); tm.invert(ok); return tm;}
_CMatrixI transposed() const {_CMatrixI tm; PIMM_FOR_WB(r, c) tm[c][r] = m[r][c]; return tm;}
private:
void resize(uint rows_, uint cols_, const Type & new_value = Type()) {r_ = rows_; c_ = cols_; PIMM_FOR_WB(r, c) m[r][c] = new_value;}
int c_, r_;
Type m[Rows][Cols];
};
#pragma pack(pop)
template<> inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::rotation(double angle) {double c = cos(angle), s = sin(angle); PIMathMatrixT<2u, 2u> tm; tm[0][0] = tm[1][1] = c; tm[0][1] = -s; tm[1][0] = s; return tm;}
template<> inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::scaleX(double factor) {PIMathMatrixT<2u, 2u> tm; tm[0][0] = factor; tm[1][1] = 1.; return tm;}
template<> inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::scaleY(double factor) {PIMathMatrixT<2u, 2u> tm; tm[0][0] = 1.; tm[1][1] = factor; return tm;}
template<> inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::rotationX(double angle) {double c = cos(angle), s = sin(angle); PIMathMatrixT<3u, 3u> tm; tm[0][0] = 1.; tm[1][1] = tm[2][2] = c; tm[2][1] = s; tm[1][2] = -s; return tm;}
template<> inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::rotationY(double angle) {double c = cos(angle), s = sin(angle); PIMathMatrixT<3u, 3u> tm; tm[1][1] = 1.; tm[0][0] = tm[2][2] = c; tm[2][0] = -s; tm[0][2] = s; return tm;}
template<> inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::rotationZ(double angle) {double c = cos(angle), s = sin(angle); PIMathMatrixT<3u, 3u> tm; tm[2][2] = 1.; tm[0][0] = tm[1][1] = c; tm[1][0] = s; tm[0][1] = -s; return tm;}
template<> inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::scaleX(double factor) {PIMathMatrixT<3u, 3u> tm; tm[1][1] = tm[2][2] = 1.; tm[0][0] = factor; return tm;}
template<> inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::scaleY(double factor) {PIMathMatrixT<3u, 3u> tm; tm[0][0] = tm[2][2] = 1.; tm[1][1] = factor; return tm;}
template<> inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::scaleZ(double factor) {PIMathMatrixT<3u, 3u> tm; tm[0][0] = tm[1][1] = 1.; tm[2][2] = factor; return tm;}
#ifdef PIP_STD_IOSTREAM
template<uint Rows, uint Cols, typename Type>
inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT<Rows, Cols, Type> & m) {s << "{"; PIMM_FOR_I(r, c) s << m[r][c]; if (c < Cols - 1 || r < Rows - 1) s << ", ";} if (r < Rows - 1) s << std::endl << " ";} s << "}"; return s;}
#endif
template<uint Rows, uint Cols, typename Type>
inline PICout operator <<(PICout s, const PIMathMatrixT<Rows, Cols, Type> & m) {s << "{"; PIMM_FOR_I(r, c) s << m[r][c]; if (c < Cols - 1 || r < Rows - 1) s << ", ";} if (r < Rows - 1) s << PICoutManipulators::NewLine << " ";} s << "}"; return s;}
/// Multiply matrices {Rows0 x CR} on {CR x Cols1}, result is {Rows0 x Cols1}
template<uint CR, uint Rows0, uint Cols1, typename Type>
inline PIMathMatrixT<Rows0, Cols1, Type> operator *(const PIMathMatrixT<Rows0, CR, Type> & fm,
const PIMathMatrixT<CR, Cols1, Type> & sm) {
PIMathMatrixT<Rows0, Cols1, Type> tm;
Type t;
for (uint j = 0; j < Rows0; ++j) {
for (uint i = 0; i < Cols1; ++i) {
t = Type(0);
for (uint k = 0; k < CR; ++k)
t += fm[j][k] * sm[k][i];
tm[j][i] = t;
}
}
return tm;
}
/// Multiply matrix {Rows x Cols} on vector {Cols}, result is vector {Rows}
template<uint Cols, uint Rows, typename Type>
inline PIMathVectorT<Rows, Type> operator *(const PIMathMatrixT<Rows, Cols, Type> & fm,
const PIMathVectorT<Cols, Type> & sv) {
PIMathVectorT<Rows, Type> tv;
Type t;
for (uint j = 0; j < Rows; ++j) {
t = Type(0);
for (uint i = 0; i < Cols; ++i)
t += fm[j][i] * sv[i];
tv[j] = t;
}
return tv;
}
/// Multiply vector {Rows} on matrix {Rows x Cols}, result is vector {Cols}
template<uint Cols, uint Rows, typename Type>
inline PIMathVectorT<Cols, Type> operator *(const PIMathVectorT<Rows, Type> & sv,
const PIMathMatrixT<Rows, Cols, Type> & fm) {
PIMathVectorT<Cols, Type> tv;
Type t;
for (uint j = 0; j < Cols; ++j) {
t = Type(0);
for (uint i = 0; i < Rows; ++i)
t += fm[i][j] * sv[i];
tv[j] = t;
}
return tv;
}
/// Multiply value(T) on matrix {Rows x Cols}, result is vector {Rows}
template<uint Cols, uint Rows, typename Type>
inline PIMathMatrixT<Rows, Cols, Type> operator *(const Type & x, const PIMathMatrixT<Rows, Cols, Type> & v) {
return v * x;
}
typedef PIMathMatrixT<2u, 2u, int> PIMathMatrixT22i;
typedef PIMathMatrixT<3u, 3u, int> PIMathMatrixT33i;
typedef PIMathMatrixT<4u, 4u, int> PIMathMatrixT44i;
typedef PIMathMatrixT<2u, 2u, double> PIMathMatrixT22d;
typedef PIMathMatrixT<3u, 3u, double> PIMathMatrixT33d;
typedef PIMathMatrixT<4u, 4u, double> PIMathMatrixT44d;
template<typename Type>
class PIMathMatrix;
#undef PIMM_FOR
#undef PIMM_FOR_WB
#undef PIMM_FOR_I
#undef PIMM_FOR_I_WB
#undef PIMM_FOR_C
#undef PIMM_FOR_R
/// Matrix
#define PIMM_FOR(c, r) for (uint c = 0; c < _V2D::cols_; ++c) for (uint r = 0; r < _V2D::rows_; ++r)
#define PIMM_FOR_I(c, r) for (uint r = 0; r < _V2D::rows_; ++r) for (uint c = 0; c < _V2D::cols_; ++c)
#define PIMM_FOR_A(v) for (uint v = 0; v < _V2D::mat.size(); ++v)
#define PIMM_FOR_C(v) for (uint v = 0; v < _V2D::cols_; ++v)
#define PIMM_FOR_R(v) for (uint v = 0; v < _V2D::rows_; ++v)
template<typename Type>
class PIP_EXPORT PIMathMatrix : public PIVector2D<Type> {
typedef PIVector2D<Type> _V2D;
typedef PIMathMatrix<Type> _CMatrix;
typedef PIMathVector<Type> _CMCol;
public:
PIMathMatrix(const uint cols = 0, const uint rows = 0, const Type & f = Type()) {_V2D::resize(rows, cols, f);}
PIMathMatrix(const uint cols, const uint rows, const PIVector<Type> & val) {_V2D::resize(rows, cols); int i=0; PIMM_FOR_I(c, r) _V2D::element(r, c) = val[i++];}
PIMathMatrix(const PIVector<PIVector<Type> > & val) {if(!val.isEmpty()) {_V2D::resize(val.size(), val[0].size()); PIMM_FOR_I(c, r) _V2D::element(r, c) = val[r][c];}}
PIMathMatrix(const PIVector2D<Type> & val) {if(!val.isEmpty()) {_V2D::resize(val.rows(), val.cols()); PIMM_FOR_I(c, r) _V2D::element(r, c) = val.element(r, c);}}
static _CMatrix identity(const uint cols, const uint rows) {_CMatrix tm(cols, rows); for (uint r = 0; r < rows; ++r) for (uint c = 0; c < cols; ++c) tm.element(r, c) = (c == r ? Type(1) : Type(0)); return tm;}
static _CMatrix matrixRow(const PIMathVector<Type> & val) {return _CMatrix(val.size(), 1, val.toVector());}
static _CMatrix matrixCol(const PIMathVector<Type> & val) {return _CMatrix(1, val.size(), val.toVector());}
_CMatrix & setCol(uint index, const _CMCol & v) {PIMM_FOR_R(i) _V2D::element(i, index) = v[i]; return *this;}
_CMatrix & setRow(uint index, const _CMCol & v) {PIMM_FOR_C(i) _V2D::element(index, i) = v[i]; return *this;}
_CMatrix & swapCols(uint r0, uint r1) {PIMM_FOR_C(i) {piSwap(_V2D::element(i, r0), _V2D::element(i, r1));} return *this;}
_CMatrix & swapRows(uint c0, uint c1) {PIMM_FOR_R(i) {piSwap(_V2D::element(c0, i), _V2D::element(c1, i));} return *this;}
_CMatrix & fill(const Type & v) {PIMM_FOR_A(i) _V2D::mat[i] = v; return *this;}
bool isSquare() const {return _V2D::cols_ == _V2D::rows_;}
bool isIdentity() const {PIMM_FOR(c, r) if ((c == r) ? _V2D::element(r, c) != Type(1) : _V2D::element(r, c) != Type(0)) return false; return true;}
bool isNull() const {PIMM_FOR_A(i) if (_V2D::mat[i] != Type(0)) return false; return true;}
bool isValid() const {return !PIVector2D<Type>::isEmpty();}
_CMatrix & operator =(const PIVector<PIVector<Type> > & v) {*this = _CMatrix(v); return *this;}
bool operator ==(const _CMatrix & sm) const {PIMM_FOR_A(i) if (_V2D::mat[i] != sm.mat[i]) return false; return true;}
bool operator !=(const _CMatrix & sm) const {return !(*this == sm);}
void operator +=(const _CMatrix & sm) {PIMM_FOR_A(i) _V2D::mat[i] += sm.mat[i];}
void operator -=(const _CMatrix & sm) {PIMM_FOR_A(i) _V2D::mat[i] -= sm.mat[i];}
void operator *=(const Type & v) {PIMM_FOR_A(i) _V2D::mat[i] *= v;}
void operator /=(const Type & v) {PIMM_FOR_A(i) _V2D::mat[i] /= v;}
_CMatrix operator -() const {_CMatrix tm(*this); PIMM_FOR_A(i) tm.mat[i] = -_V2D::mat[i]; return tm;}
_CMatrix operator +(const _CMatrix & sm) const {_CMatrix tm(*this); PIMM_FOR_A(i) tm.mat[i] += sm.mat[i]; return tm;}
_CMatrix operator -(const _CMatrix & sm) const {_CMatrix tm(*this); PIMM_FOR_A(i) tm.mat[i] -= sm.mat[i]; return tm;}
_CMatrix operator *(const Type & v) const {_CMatrix tm(*this); PIMM_FOR_A(i) tm.mat[i] *= v; return tm;}
_CMatrix operator /(const Type & v) const {_CMatrix tm(*this); PIMM_FOR_A(i) tm.mat[i] /= v; return tm;}
Type determinant(bool * ok = 0) const {
_CMatrix m(*this);
bool k;
Type ret = Type(0);
m.toUpperTriangular(&k);
if (ok) *ok = k;
if (!k) return ret;
ret = Type(1);
for (uint c = 0; c < _V2D::cols_; ++c)
for (uint r = 0; r < _V2D::rows_; ++r)
if (r == c)
ret *= m.element(r, c);
return ret;
}
Type trace(bool * ok = 0) const {
Type ret = Type(0);
if (!isSquare()) {
if (ok != 0) *ok = false;
return ret;
}
for (uint i = 0; i < _V2D::cols_; ++i) {
ret += _V2D::element(i, i);
}
if (ok != 0) *ok = true;
return ret;
}
_CMatrix & toUpperTriangular(bool * ok = 0) {
if (!isSquare()) {
if (ok != 0) *ok = false;
return *this;
}
_CMatrix smat(*this);
bool ndet;
uint crow;
Type mul;
for (uint i = 0; i < _V2D::cols_; ++i) {
ndet = true;
for (uint j = 0; j < _V2D::rows_; ++j) if (smat.element(i, j) != 0) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
}
for (uint i = 0; i < _V2D::cols_; ++i) {
crow = i;
while (smat.element(i, i) == Type(0))
smat.swapRows(i, ++crow);
for (uint j = i + 1; j < _V2D::rows_; ++j) {
mul = smat.element(i, j) / smat.element(i, i);
for (uint k = i; k < _V2D::cols_; ++k) smat.element(k, j) -= mul * smat.element(k, i);
}
if (i < _V2D::cols_ - 1) {
if (_PIMathMatrixNullCompare(smat.element(i+1, i+1))) {
if (ok != 0) *ok = false;
return *this;
}
}
}
if (ok != 0) *ok = true;
_V2D::mat.swap(smat.mat);
return *this;
}
_CMatrix & invert(bool * ok = 0, _CMCol * sv = 0) {
if (!isSquare()) {
if (ok != 0) *ok = false;
return *this;
}
_CMatrix mtmp = _CMatrix::identity(_V2D::cols_, _V2D::rows_), smat(*this);
bool ndet;
uint crow;
Type mul, iddiv;
for (uint i = 0; i < _V2D::cols_; ++i) {
ndet = true;
for (uint j = 0; j < _V2D::rows_; ++j) if (smat.element(i, j) != Type(0)) ndet = false;
if (ndet) {
if (ok != 0) *ok = false;
return *this;
}
}
for (uint i = 0; i < _V2D::cols_; ++i) {
crow = i;
while (smat.element(i, i) == Type(0)) {
++crow;
smat.swapRows(i, crow);
mtmp.swapRows(i, crow);
if (sv != 0) sv->swap(i, crow);
}
for (uint j = i + 1; j < _V2D::rows_; ++j) {
mul = smat.element(i, j) / smat.element(i, i);
for (uint k = i; k < _V2D::cols_; ++k) smat.element(k, j) -= mul * smat.element(k, i);
for (uint k = 0; k < _V2D::cols_; ++k) mtmp.element(k, j) -= mul * mtmp.element(k, i);
if (sv != 0) (*sv)[j] -= mul * (*sv)[i];
}
if (i < _V2D::cols_ - 1) {
if (_PIMathMatrixNullCompare(smat.element(i+1, i+1))) {
if (ok != 0) *ok = false;
return *this;
}
}
iddiv = smat.element(i, i);
for (uint j = i; j < _V2D::cols_; ++j) smat.element(j, i) /= iddiv;
for (uint j = 0; j < _V2D::cols_; ++j) mtmp.element(j, i) /= iddiv;
if (sv != 0) (*sv)[i] /= iddiv;
}
for (uint i = _V2D::cols_ - 1; i > 0; --i) {
for (uint j = 0; j < i; ++j) {
mul = smat.element(i, j);
smat.element(i, j) -= mul;
for (uint k = 0; k < _V2D::cols_; ++k) mtmp.element(k, j) -= mul * mtmp.element(k, i);
if (sv != 0) (*sv)[j] -= mul * (*sv)[i];
}
}
if (ok != 0) *ok = true;
PIVector2D<Type>::swap(mtmp);
return *this;
}
_CMatrix inverted(bool * ok = 0) const {_CMatrix tm(*this); tm.invert(ok); return tm;}
_CMatrix transposed() const {_CMatrix tm(_V2D::rows_, _V2D::cols_); PIMM_FOR(c, r) tm.element(c, r) = _V2D::element(r, c); return tm;}
};
#ifdef PIP_STD_IOSTREAM
template<typename Type>
inline std::ostream & operator <<(std::ostream & s, const PIMathMatrix<Type> & m) {s << "{"; for (uint r = 0; r < m.rows(); ++r) { for (uint c = 0; c < m.cols(); ++c) { s << m.element(r, c); if (c < m.cols() - 1 || r < m.rows() - 1) s << ", ";} if (r < m.rows() - 1) s << std::endl << " ";} s << "}"; return s;}
#endif
template<typename Type>
inline PICout operator <<(PICout s, const PIMathMatrix<Type> & m) {s << "Matrix{"; for (uint r = 0; r < m.rows(); ++r) { for (uint c = 0; c < m.cols(); ++c) { s << m.element(r, c); if (c < m.cols() - 1 || r < m.rows() - 1) s << ", ";} if (r < m.rows() - 1) s << PICoutManipulators::NewLine << " ";} s << "}"; return s;}
template<typename Type>
inline PIByteArray & operator <<(PIByteArray & s, const PIMathMatrix<Type> & v) {s << (const PIVector2D<Type> &)v; return s;}
template<typename Type>
inline PIByteArray & operator >>(PIByteArray & s, PIMathMatrix<Type> & v) {s >> (PIVector2D<Type> &)v; return s;}
/// Multiply matrices {CR x Rows0} on {Cols1 x CR}, result is {Cols1 x Rows0}
template<typename Type>
inline PIMathMatrix<Type> operator *(const PIMathMatrix<Type> & fm,
const PIMathMatrix<Type> & sm) {
uint cr = fm.cols(), rows0 = fm.rows(), cols1 = sm.cols();
PIMathMatrix<Type> tm(cols1, rows0);
if (fm.cols() != sm.rows()) return tm;
Type t;
for (uint j = 0; j < rows0; ++j) {
for (uint i = 0; i < cols1; ++i) {
t = Type(0);
for (uint k = 0; k < cr; ++k)
t += fm.element(j, k) * sm.element(k, i);
tm.element(j, i) = t;
}
}
return tm;
}
/// Multiply matrix {Cols x Rows} on vector {Cols}, result is vector {Rows}
template<typename Type>
inline PIMathVector<Type> operator *(const PIMathMatrix<Type> & fm,
const PIMathVector<Type> & sv) {
uint c = fm.cols(), r = fm.rows();
PIMathVector<Type> tv(r);
if (c != sv.size()) return tv;
Type t;
for (uint j = 0; j < r; ++j) {
t = Type(0);
for (uint i = 0; i < c; ++i)
t += fm.element(j, i) * sv[i];
tv[j] = t;
}
return tv;
}
/// Multiply vector {Rows} on matrix {Rows x Cols}, result is vector {Cols}
template<typename Type>
inline PIMathVector<Type> operator *(const PIMathVector<Type> & sv,
const PIMathMatrix<Type> & fm) {
uint c = fm.cols(), r = fm.rows();
PIMathVector<Type> tv(c);
Type t;
for (uint j = 0; j < c; ++j) {
t = Type(0);
for (uint i = 0; i < r; ++i)
t += fm.element(i, j) * sv[i];
tv[j] = t;
}
return tv;
}
/// Multiply value(T) on matrix {Rows x Cols}, result is vector {Rows}
template<typename Type>
inline PIMathMatrix<Type> operator *(const Type & x, const PIMathMatrix<Type> & v) {
return v * x;
}
typedef PIMathMatrix<int> PIMathMatrixi;
typedef PIMathMatrix<double> PIMathMatrixd;
template<typename T>
PIMathMatrix<complex<T> > hermitian(const PIMathMatrix<complex<T> > & m) {
PIMathMatrix<complex<T> > ret(m);
for (uint r = 0; r < ret.rows(); ++r) for (uint c = 0; c < ret.cols(); ++c) ret.element(r, c).imag(-(ret.element(r, c).imag()));
return ret.transposed();
}
#undef PIMM_FOR
#undef PIMM_FOR_I
#undef PIMM_FOR_A
#undef PIMM_FOR_C
#undef PIMM_FOR_R
#endif // PIMATHMATRIX_H

View File

@@ -17,24 +17,33 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piccloudclient.h"
#include "picloudclient.h"
PICloudClient::PICloudClient() {
PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), eth(PIEthernet::TCP_Client) {
}
PICloudClient::~PICloudClient() {
stop();
close();
}
bool PICloudClient::openDevice() {
return false;
}
bool PICloudClient::closeDevice() {
return false;
}
int PICloudClient::readDevice(void * read_to, int max_size) {
return eth.read(read_to, max_size);
}
int PICloudClient::writeDevice(const void * data, int max_size) {
return eth.write(data, max_size);
}

View File

@@ -0,0 +1,81 @@
/*
PIP - Platform Independent Primitives
PICloud Server
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "picloudserver.h"
PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), eth(PIEthernet::TCP_Client) {
}
PICloudServer::~PICloudServer() {
stop();
close();
}
bool PICloudServer::openDevice() {
piCout << "PICloudServer open device" << path();
bool op = eth.connect(path(), false);
if (op) {
CONNECTL(&eth, disconnected, [this](bool){opened_ = false;});
CONNECTU(&eth, threadedReadEvent, this, readed);
eth.startThreadedRead();
sendStart();
return true;
}
eth.close();
return false;
}
bool PICloudServer::closeDevice() {
return eth.close();
}
int PICloudServer::readDevice(void * read_to, int max_size) {
return -1;
}
int PICloudServer::writeDevice(const void * data, int max_size) {
return -1;
}
void PICloudServer::sendStart() {
}
PICloudServer::Client::Client(PICloudServer * srv) : server(srv) {
}
bool PICloudServer::Client::openDevice() {
return server;
}
void PICloudServer::readed(uchar *data, int size) {
}

View File

@@ -17,12 +17,26 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piccloudtcp.h"
#include "picloudtcp.h"
#include "picrypt.h"
#include "pichunkstream.h"
const char hash_def_key[] = "_picrypt_";
PICloudTCP::PICloudTCP() {
PIByteArray & operator <<(PIByteArray & s, const PICloud::Header & v) {
s << v.version << v.type << v.sname;
return s;
}
PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v) {
s >> v.version >> v.type >> v.sname;
return s;
}
PICloud::TCP::TCP() {
}

View File

@@ -1,4 +1,4 @@
/*! \file piccloudclient.h
/*! \file picloudclient.h
* \brief PICloud Client
*/
/*
@@ -20,13 +20,11 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICCLOUDCLIENT_H
#define PICCLOUDCLIENT_H
#ifndef PICLOUDCLIENT_H
#define PICLOUDCLIENT_H
#include "pip_cloud_export.h"
#include "piiodevice.h"
class PIEthernet;
#include "piethernet.h"
class PIP_CLOUD_EXPORT PICloudClient : public PIIODevice
@@ -34,7 +32,7 @@ class PIP_CLOUD_EXPORT PICloudClient : public PIIODevice
PIIODEVICE(PICloudClient)
public:
//!
explicit PICloudClient();
explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
virtual ~PICloudClient();
protected:
@@ -42,7 +40,10 @@ protected:
bool closeDevice();
private:
PIEthernet * eth;
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
PIEthernet eth;
};
#endif // PICCLOUDCLIENT_H
#endif // PICLOUDCLIENT_H

View File

@@ -20,8 +20,8 @@
#ifndef PICLOUDMODULE_H
#define PICLOUDMODULE_H
#include "piccloudtcp.h"
#include "piccloudclient.h"
#include "piccloudserver.h"
#include "picloudtcp.h"
#include "picloudclient.h"
#include "picloudserver.h"
#endif // PICLOUDMODULE_H

View File

@@ -0,0 +1,65 @@
/*! \file picloudserver.h
* \brief PICloud Server
*/
/*
PIP - Platform Independent Primitives
PICloud Server
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICLOUDSERVER_H
#define PICLOUDSERVER_H
#include "pip_cloud_export.h"
#include "piethernet.h"
class PIP_CLOUD_EXPORT PICloudServer : public PIIODevice
{
PIIODEVICE(PICloudServer)
public:
//!
explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
virtual ~PICloudServer();
class Client : public PIIODevice {
PIIODEVICE(PICloudServer::Client)
public:
Client(PICloudServer * srv = nullptr);
protected:
bool openDevice();
private:
PICloudServer * server;
};
EVENT1(newConnection, PICloudServer::Client * , client)
protected:
bool openDevice();
bool closeDevice();
int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size);
private:
EVENT_HANDLER2(void, readed, uchar * , data, int, size);
void sendStart();
PIEthernet eth;
PIVector<Client> clients;
};
#endif // PICLOUDSERVER_H

View File

@@ -1,4 +1,4 @@
/*! \file piccloudtcp.h
/*! \file picloudtcp.h
* \brief PICloud TCP transport
*/
/*
@@ -20,20 +20,45 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICCLOUDTCP_H
#define PICCLOUDTCP_H
#ifndef PICLOUDTCP_H
#define PICLOUDTCP_H
#include "pip_cloud_export.h"
#include "pistring.h"
class PIP_CLOUD_EXPORT PICloudTCP {
public:
//!
PICloudTCP();
namespace PICloud {
enum Version {
Version_1 = 1,
};
enum HeaderType {
Server = 1,
Client = 2,
};
struct PIP_CLOUD_EXPORT Header {
Header() {
version = Version_1;
}
uchar version; // PICloud::Version
uchar type; // PICloud::HeaderType
PIString sname; // server name
};
class PIP_CLOUD_EXPORT TCP {
public:
TCP();
private:
};
#endif // PICCLOUDTCP_H
}
PIP_CLOUD_EXPORT PIByteArray & operator <<(PIByteArray & s, const PICloud::Header & v);
PIP_CLOUD_EXPORT PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v);
#endif // PICLOUDTCP_H

View File

@@ -32,6 +32,10 @@
* \brief Contructs vector with size "size" filled elements "value"
* \details Example: \snippet picontainers.cpp PIVector::PIVector
* \fn PIVector::PIVector(std::initializer_list list);
* \brief Contructs vector from C++11 initializer list
* \details Example: \snippet picontainers.cpp PIVector::PIVector
* \fn const T & PIVector::at(size_t index) const;
* \brief Read-only access to element by index "index"
* \details Example: \snippet picontainers.cpp PIVector::at_c
@@ -371,4 +375,7 @@
* \fn bool PIMapIterator::next()
* \brief Jump to next entry and return if new position is valid.
* \fn void PIMapIterator::reset()
* \brief Reset iterator to initial position.
* */

View File

@@ -42,6 +42,8 @@
#else
# include <malloc.h>
#endif
#include <initializer_list>
#include <type_traits>
#include <string.h>
#include <new>
#ifndef PIP_MEMALIGN_BYTES

View File

@@ -39,6 +39,11 @@ public:
alloc(other.pid_size, true);
newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size);
}
inline PIDeque(std::initializer_list<T> init_list): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
alloc(init_list.size(), true);
newT(pid_data, init_list.begin(), init_list.size());
}
inline PIDeque(const T * data, size_t size): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
alloc(size, true);
@@ -49,6 +54,7 @@ public:
resize(pid_size, f);
}
inline PIDeque(PIDeque<T> && other): pid_data(other.pid_data), pid_size(other.pid_size), pid_rsize(other.pid_rsize), pid_start(other.pid_start) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
other._reset();
}
inline virtual ~PIDeque() {

View File

@@ -364,6 +364,13 @@ public:
}
return false;
}
inline void reset() {
if (rev) {
pos = m.size_s();
} else {
pos = -1;
}
}
private:
const MapType & m;
ssize_t pos;

View File

@@ -44,11 +44,17 @@ public:
alloc(other.piv_size);
newT(piv_data, other.piv_data, piv_size);
}
inline PIVector(std::initializer_list<T> init_list): piv_data(0), piv_size(0), piv_rsize(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
alloc(init_list.size());
newT(piv_data, init_list.begin(), init_list.size());
}
inline PIVector(size_t piv_size, const T & f = T()): piv_data(0), piv_size(0), piv_rsize(0) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
resize(piv_size, f);
}
inline PIVector(PIVector<T> && other): piv_data(other.piv_data), piv_size(other.piv_size), piv_rsize(other.piv_rsize) {
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
other._reset();
}
inline virtual ~PIVector() {

View File

@@ -292,13 +292,6 @@ template<> inline void piSwapBinary(const void *& f, const void *& s) {
}
}
template<> inline void piSwap(double & f, double & s) {piSwapBinary<double>(f, s);}
template<> inline void piSwap(ldouble & f, ldouble & s) {piSwapBinary<ldouble>(f, s);}
#ifdef ARCH_BITS_32
template<> inline void piSwap(float & f, float & s) {piSwapBinary<float>(f, s);}
template<> inline void piSwap(llong & f, llong & s) {piSwapBinary<llong>(f, s);}
template<> inline void piSwap(ullong & f, ullong & s) {piSwapBinary<ullong>(f, s);}
#endif
/*! \brief Function for compare two values without "=" by raw content
* \details Example:\n \snippet piincludes.cpp compareBinary */
@@ -454,20 +447,7 @@ template<> inline float piLetobe(const float & v) {
return a.f;
}
DEPRECATED inline ushort letobe_s(const ushort & v) {return (v << 8) | (v >> 8);}
DEPRECATED inline uint letobe_i(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
#ifdef DOXYGEN
/// \deprecated \brief Use \a piLetobe() instead of this function
ushort letobe_s(ushort v) {return (v << 8) | (v >> 8);}
/// \deprecated \brief Use \a piLetobe() instead of this function
uint letobe_i(uint v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
#endif
/// \brief Generic hash function, impements murmur3/32 algorithm
/// \brief Generic hash function, implements murmur3/32 algorithm
inline uint piHashData(const uchar * data, uint len, uint seed = 0) {
if (!data || len <= 0) return 0u;
uint h = seed;

View File

@@ -396,8 +396,8 @@ PIByteArray & operator >>(PIByteArray & s, PIByteArray & v) {
}
v.resize(sz);
if (sz > 0) {
memcpy(v.data(), s.data(), v.size());
s.remove(0, v.size());
memcpy(v.data(), s.data(), sz);
s.remove(0, sz);
}
return s;
}

View File

@@ -80,11 +80,36 @@ int PIChunkStream::read() {
}
int PIChunkStream::peekVInt(Version version_, PIByteArray * data_, int pos, PIByteArray & hdr, uint & ret) {
switch (version_) {
case Version_1:
memcpy(&ret, data_->data(pos), 4);
return 4;
case Version_2: {
hdr.resize(4);
hdr.fill(uchar(0));
memcpy(hdr.data(), data_->data(pos), piMini(4, data_->size_s() - pos));
uchar hsz = 0;
ret = readVInt(hdr, &hsz);
return hsz;
}
default: break;
}
return 0;
}
void PIChunkStream::readAll() {
data_map.clear();
while (!atEnd()) {
read();
data_map[last_id] = last_data;
if (!data_) return;
int pos = 0, sz = data_->size_s();
uint csz = 0, cid = 0;
PIByteArray hdr;
while (pos < sz) {
pos += peekVInt((Version)version_, data_, pos, hdr, cid);
pos += peekVInt((Version)version_, data_, pos, hdr, csz);
data_map[cid] = PIPair<int, int>(pos, csz);
pos += csz;
}
}
@@ -111,7 +136,7 @@ void PIChunkStream::_init() {
}
uint PIChunkStream::readVInt(PIByteArray & s) {
uint PIChunkStream::readVInt(PIByteArray & s, uchar * bytes_cnt) {
if (s.isEmpty()) return 0;
uchar bytes[4]; s >> bytes[0];
uchar abc = 0;
@@ -122,6 +147,7 @@ uint PIChunkStream::readVInt(PIByteArray & s) {
s >> bytes[abc + 1];
} else break;
}
if (bytes_cnt) *bytes_cnt = (abc + 1);
uint ret = 0;
for (int i = 0; i <= abc; ++i) {
ret += (bytes[i] << (8 * ((int)abc - i)));

View File

@@ -83,7 +83,7 @@ public:
//! Read one chunk from stream and returns its ID
int read();
//! Read all chunks from stream
//! Read all chunks from stream. This function just index input data
void readAll();
//! Returns last readed chunk ID
@@ -100,7 +100,9 @@ public:
//! Place value of chunk with id \"id\" into \"v\". You should call \a readAll() before using this function!
template <typename T>
const PIChunkStream & get(int id, T & v) const {
PIByteArray ba = data_map.value(id);
PIPair<int, int> pos = data_map.value(id);
if (pos.first < 0 || pos.second == 0) return *this;
PIByteArray ba(data_->data(pos.first), pos.second);
if (!ba.isEmpty())
ba >> v;
return *this;
@@ -109,13 +111,14 @@ public:
private:
void _init();
static uint readVInt(PIByteArray & s);
static uint readVInt(PIByteArray & s, uchar * bytes = 0);
static void writeVInt(PIByteArray & s, uint val);
static int peekVInt(Version version_, PIByteArray * data_, int pos, PIByteArray & hdr, uint & ret);
int last_id;
uchar version_;
PIByteArray * data_, last_data, tmp_data;
PIMap<int, PIByteArray> data_map;
PIMap<int, PIPair<int, int>> data_map;
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c);
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c);

Some files were not shown because too many files have changed in this diff Show More