Spaces:
Sleeping
Sleeping
1cc98d02ef4e1cd8a6d2d153318b198a877ea06642d3e1195aba2da22184a6fc
Browse files- third-party/DPVO/Pangolin/components/pango_core/CMakeLists.txt +74 -0
- third-party/DPVO/Pangolin/components/pango_core/include/NaturalSort/LICENSE.md +21 -0
- third-party/DPVO/Pangolin/components/pango_core/include/NaturalSort/README.md +61 -0
- third-party/DPVO/Pangolin/components/pango_core/include/NaturalSort/natural_sort.hpp +281 -0
- third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/config.hpp +16 -0
- third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/linux/dynalo.hpp +76 -0
- third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/macos/dynalo.hpp +76 -0
- third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/windows/dynalo.hpp +107 -0
- third-party/DPVO/Pangolin/components/pango_core/include/dynalo/dynalo.hpp +184 -0
- third-party/DPVO/Pangolin/components/pango_core/include/dynalo/symbol_helper.hpp +72 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/compat/glutbitmap.h +92 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/compat/type_traits.h +49 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/factory/factory.h +31 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/factory/factory_help.h +31 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/factory/factory_registry.h +218 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/pangolin.h +59 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/platform.h +66 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/argagg.hpp +1548 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/assert.h +72 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/avx_math.h +38 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/bitmask.h +73 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/compontent_cast.h +42 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/file_extension.h +77 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/file_utils.h +161 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/fix_size_buffer_queue.h +152 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/format_string.h +87 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/is_streamable.h +35 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/log.h +44 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/memstreambuf.h +55 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/param_set.h +79 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/params.h +97 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/parse.h +108 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/picojson.h +1416 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/posix/condition_variable.h +27 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/posix/semaphore.h +26 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/posix/shared_memory_buffer.h +25 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/range.h +372 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/signal_slot.h +4 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/sigstate.h +75 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/simple_math.h +446 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/threadedfilebuf.h +97 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/timer.h +122 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/transform.h +102 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/true_false_toggle.h +29 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/type_convert.h +180 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/uri.h +48 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/variadic_all.h +44 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/xml/license.txt +52 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/xml/rapidxml.hpp +0 -0
- third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/xml/rapidxml_iterators.hpp +174 -0
third-party/DPVO/Pangolin/components/pango_core/CMakeLists.txt
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
get_filename_component(COMPONENT ${CMAKE_CURRENT_LIST_DIR} NAME)
|
2 |
+
|
3 |
+
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
4 |
+
target_compile_definitions(${COMPONENT} PUBLIC "_OSX_")
|
5 |
+
elseif(WIN32 OR WIN64)
|
6 |
+
target_compile_definitions(${COMPONENT} PUBLIC "_WIN_")
|
7 |
+
elseif(EMSCRIPTEN)
|
8 |
+
target_compile_definitions(${COMPONENT} PUBLIC "_EMSCRIPTEN_")
|
9 |
+
else()
|
10 |
+
target_compile_definitions(${COMPONENT} PUBLIC "_LINUX_")
|
11 |
+
endif()
|
12 |
+
|
13 |
+
target_sources( ${COMPONENT}
|
14 |
+
PRIVATE
|
15 |
+
${CMAKE_CURRENT_LIST_DIR}/src/file_extension.cpp
|
16 |
+
${CMAKE_CURRENT_LIST_DIR}/src/file_utils.cpp
|
17 |
+
${CMAKE_CURRENT_LIST_DIR}/src/sigstate.cpp
|
18 |
+
${CMAKE_CURRENT_LIST_DIR}/src/threadedfilebuf.cpp
|
19 |
+
${CMAKE_CURRENT_LIST_DIR}/src/avx_math.cpp
|
20 |
+
${CMAKE_CURRENT_LIST_DIR}/src/uri.cpp
|
21 |
+
${CMAKE_CURRENT_LIST_DIR}/src/param_set.cpp
|
22 |
+
${CMAKE_CURRENT_LIST_DIR}/src/factory/factory_registry.cpp
|
23 |
+
${CMAKE_CURRENT_LIST_DIR}/src/factory/factory_help.cpp
|
24 |
+
)
|
25 |
+
|
26 |
+
if (UNIX)
|
27 |
+
target_sources( ${COMPONENT} PRIVATE
|
28 |
+
${CMAKE_CURRENT_LIST_DIR}/src/posix/condition_variable.cpp
|
29 |
+
${CMAKE_CURRENT_LIST_DIR}/src/posix/semaphore.cpp
|
30 |
+
${CMAKE_CURRENT_LIST_DIR}/src/posix/shared_memory_buffer.cpp
|
31 |
+
)
|
32 |
+
if (NOT APPLE)
|
33 |
+
target_link_libraries(${COMPONENT} PUBLIC rt)
|
34 |
+
endif()
|
35 |
+
endif()
|
36 |
+
|
37 |
+
|
38 |
+
target_compile_features(${COMPONENT} PUBLIC cxx_decltype_auto )
|
39 |
+
target_include_directories(${COMPONENT} PUBLIC
|
40 |
+
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
|
41 |
+
$<INSTALL_INTERFACE:include>
|
42 |
+
)
|
43 |
+
install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include"
|
44 |
+
DESTINATION ${CMAKE_INSTALL_PREFIX}
|
45 |
+
)
|
46 |
+
|
47 |
+
find_package(Threads QUIET)
|
48 |
+
if(Threads_FOUND)
|
49 |
+
target_link_libraries(${COMPONENT} PUBLIC Threads::Threads)
|
50 |
+
endif()
|
51 |
+
|
52 |
+
## Generate symbol export helper header on MSVC
|
53 |
+
IF(MSVC)
|
54 |
+
include(GenerateExportHeader)
|
55 |
+
GENERATE_EXPORT_HEADER( ${COMPONENT}
|
56 |
+
BASE_NAME PANGOLIN
|
57 |
+
EXPORT_MACRO_NAME PANGOLIN_EXPORT
|
58 |
+
EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/include/pangolin/pangolin_export.h"
|
59 |
+
STATIC_DEFINE PANGOLIN_BUILT_AS_STATIC
|
60 |
+
)
|
61 |
+
target_include_directories(${COMPONENT} PUBLIC
|
62 |
+
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
|
63 |
+
$<INSTALL_INTERFACE:include>
|
64 |
+
)
|
65 |
+
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include"
|
66 |
+
DESTINATION ${CMAKE_INSTALL_PREFIX}
|
67 |
+
)
|
68 |
+
ENDIF()
|
69 |
+
|
70 |
+
if(BUILD_TESTS)
|
71 |
+
add_executable(test_uris ${CMAKE_CURRENT_LIST_DIR}/tests/tests_uri.cpp)
|
72 |
+
target_link_libraries(test_uris PRIVATE Catch2::Catch2 ${COMPONENT})
|
73 |
+
catch_discover_tests(test_uris)
|
74 |
+
endif()
|
third-party/DPVO/Pangolin/components/pango_core/include/NaturalSort/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
The MIT License (MIT)
|
2 |
+
|
3 |
+
Copyright (c) 2016 Gagan Kumar
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in all
|
13 |
+
copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21 |
+
SOFTWARE.
|
third-party/DPVO/Pangolin/components/pango_core/include/NaturalSort/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# NaturalSort
|
2 |
+
C++ Header File for Natural Comparison and Natural Sort
|
3 |
+
|
4 |
+
|
5 |
+
##### Calling Methods
|
6 |
+
|
7 |
+
* __For Natural Sorting__
|
8 |
+
|
9 |
+
void SI::natural::sort(Container<String>);
|
10 |
+
|
11 |
+
void SI::natural::sort(IteratorBegin<String>,IteratorEnd<String>);
|
12 |
+
|
13 |
+
void SI::natural::sort<String,CArraySize>(CArray<String>);
|
14 |
+
|
15 |
+
|
16 |
+
* __For Natural Comparision__
|
17 |
+
|
18 |
+
bool SI::natural::compare<String>(String lhs,String rhs);
|
19 |
+
bool SI::natural::compare<String>(char *const lhs,char *const rhs);
|
20 |
+
|
21 |
+
Here we can have
|
22 |
+
|
23 |
+
std::vector<std::string> as Container<String>
|
24 |
+
String as std::string
|
25 |
+
CArray<String> as std::string[CArraySize]
|
26 |
+
|
27 |
+
|
28 |
+
|
29 |
+
|
30 |
+
|
31 |
+
##### Example
|
32 |
+
|
33 |
+
* __Inputs__
|
34 |
+
|
35 |
+
Hello 100
|
36 |
+
Hello 34
|
37 |
+
Hello 9
|
38 |
+
Hello 25
|
39 |
+
Hello 10
|
40 |
+
Hello 8
|
41 |
+
|
42 |
+
* __Normal Sort Output__
|
43 |
+
|
44 |
+
Hello 10
|
45 |
+
Hello 100
|
46 |
+
Hello 25
|
47 |
+
Hello 34
|
48 |
+
Hello 8
|
49 |
+
Hello 9
|
50 |
+
|
51 |
+
* __Natural Sort Output__
|
52 |
+
|
53 |
+
Hello 8
|
54 |
+
Hello 9
|
55 |
+
Hello 10
|
56 |
+
Hello 25
|
57 |
+
Hello 34
|
58 |
+
Hello 100
|
59 |
+
|
60 |
+
|
61 |
+
|
third-party/DPVO/Pangolin/components/pango_core/include/NaturalSort/natural_sort.hpp
ADDED
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
The MIT License (MIT)
|
3 |
+
Copyright (c) 2016 Gagan Kumar(scopeInfinity)
|
4 |
+
Complete License at https://raw.githubusercontent.com/scopeInfinity/NaturalSort/master/LICENSE.md
|
5 |
+
*/
|
6 |
+
|
7 |
+
/**********************************************************************
|
8 |
+
Calling Methods :
|
9 |
+
|
10 |
+
//For Natural Sorting
|
11 |
+
void SI::natural::sort(Container<String>);
|
12 |
+
void SI::natural::sort(IteratorBegin<String>,IteratorEnd<String>);
|
13 |
+
void SI::natural::sort<String,CArraySize>(CArray<String>);
|
14 |
+
|
15 |
+
//For Natural Comparision
|
16 |
+
bool SI::natural::compare<String>(String lhs,String rhs);
|
17 |
+
bool SI::natural::compare<String>(char *const lhs,char *const rhs);
|
18 |
+
|
19 |
+
Here we can have
|
20 |
+
std::vector<std::string> as Container<String>
|
21 |
+
String as std::string
|
22 |
+
CArray<String> as std::string[CArraySize]
|
23 |
+
|
24 |
+
***********************************************************************/
|
25 |
+
#ifndef SI_sort_HPP
|
26 |
+
#define SI_sort_HPP
|
27 |
+
#include <cctype>
|
28 |
+
#include <algorithm>
|
29 |
+
#include <vector>
|
30 |
+
|
31 |
+
|
32 |
+
namespace SI
|
33 |
+
{
|
34 |
+
namespace natural
|
35 |
+
{
|
36 |
+
namespace detail
|
37 |
+
{
|
38 |
+
/********** Compare Two Character CaseInsensitive ********/
|
39 |
+
template<typename ElementType>
|
40 |
+
bool natural_less(const ElementType &lhs,const ElementType &rhs)
|
41 |
+
{
|
42 |
+
if(tolower(lhs)<tolower(rhs))
|
43 |
+
return true;
|
44 |
+
return false;
|
45 |
+
}
|
46 |
+
|
47 |
+
template<typename ElementType>
|
48 |
+
bool is_not_digit(const ElementType &x)
|
49 |
+
{
|
50 |
+
return !isdigit(x);
|
51 |
+
}
|
52 |
+
|
53 |
+
/********** Compare Two Iterators CaseInsensitive ********/
|
54 |
+
template<typename ElementType,typename Iterator>
|
55 |
+
struct comp_over_iterator
|
56 |
+
{
|
57 |
+
int operator()(const Iterator &lhs,const Iterator &rhs) const
|
58 |
+
{
|
59 |
+
if(natural_less<ElementType>(*lhs,*rhs))
|
60 |
+
return -1;
|
61 |
+
if(natural_less<ElementType>(*rhs,*lhs))
|
62 |
+
return +1;
|
63 |
+
return 0;
|
64 |
+
}
|
65 |
+
};
|
66 |
+
|
67 |
+
/****************************************************
|
68 |
+
Comparing two SubString from (Begin,End Iterator each)
|
69 |
+
with only digits.
|
70 |
+
Usage :
|
71 |
+
int compare_number()(\
|
72 |
+
FirstNumberBeginIterator,FirstNumberEndIterator,isFirstNumberFractionalPart\
|
73 |
+
SecondNumberBeginIterator,SecondNumberEndIterator,isSecondNumberFractionalPart\
|
74 |
+
);
|
75 |
+
|
76 |
+
Returns :
|
77 |
+
-1 - Number1 < Number2
|
78 |
+
0 - Number1 == Number2
|
79 |
+
1 - Number1 > Number2
|
80 |
+
|
81 |
+
***************************************************/
|
82 |
+
|
83 |
+
|
84 |
+
template<typename ValueType, typename Iterator>
|
85 |
+
struct compare_number
|
86 |
+
{
|
87 |
+
private:
|
88 |
+
//If Number is Itself fractional Part
|
89 |
+
int fractional(Iterator lhsBegin,Iterator lhsEnd, Iterator rhsBegin,Iterator rhsEnd)
|
90 |
+
{
|
91 |
+
while(lhsBegin<lhsEnd && rhsBegin<rhsEnd)
|
92 |
+
{
|
93 |
+
int local_compare = comp_over_iterator<ValueType, Iterator>()(lhsBegin,rhsBegin);
|
94 |
+
if(local_compare!=0)
|
95 |
+
return local_compare;
|
96 |
+
lhsBegin++;
|
97 |
+
rhsBegin++;
|
98 |
+
}
|
99 |
+
while(lhsBegin<lhsEnd && *lhsBegin=='0') lhsBegin++;
|
100 |
+
while(rhsBegin<rhsEnd && *rhsBegin=='0') rhsBegin++;
|
101 |
+
if(lhsBegin==lhsEnd && rhsBegin!=rhsEnd)
|
102 |
+
return -1;
|
103 |
+
else if(lhsBegin!=lhsEnd && rhsBegin==rhsEnd)
|
104 |
+
return +1;
|
105 |
+
else //lhsBegin==lhsEnd && rhsBegin==rhsEnd
|
106 |
+
return 0;
|
107 |
+
}
|
108 |
+
int non_fractional(Iterator lhsBegin,Iterator lhsEnd, Iterator rhsBegin,Iterator rhsEnd)
|
109 |
+
{
|
110 |
+
//Skip Inital Zero's
|
111 |
+
while(lhsBegin<lhsEnd && *lhsBegin=='0') lhsBegin++;
|
112 |
+
while(rhsBegin<rhsEnd && *rhsBegin=='0') rhsBegin++;
|
113 |
+
|
114 |
+
//Comparing By Length of Both String
|
115 |
+
if(lhsEnd-lhsBegin<rhsEnd-rhsBegin)
|
116 |
+
return -1;
|
117 |
+
if(lhsEnd-lhsBegin>rhsEnd-rhsBegin)
|
118 |
+
return +1;
|
119 |
+
|
120 |
+
//Equal In length
|
121 |
+
while(lhsBegin<lhsEnd)
|
122 |
+
{
|
123 |
+
int local_compare = comp_over_iterator<ValueType, Iterator>()(lhsBegin,rhsBegin);
|
124 |
+
if(local_compare!=0)
|
125 |
+
return local_compare;
|
126 |
+
lhsBegin++;
|
127 |
+
rhsBegin++;
|
128 |
+
}
|
129 |
+
return 0;
|
130 |
+
}
|
131 |
+
|
132 |
+
|
133 |
+
public:
|
134 |
+
int operator()(\
|
135 |
+
Iterator lhsBegin,Iterator lhsEnd,bool isFractionalPart1,\
|
136 |
+
Iterator rhsBegin,Iterator rhsEnd,bool isFractionalPart2)
|
137 |
+
{
|
138 |
+
if(isFractionalPart1 && !isFractionalPart2)
|
139 |
+
return true; //0<num1<1 && num2>=1
|
140 |
+
if(!isFractionalPart1 && isFractionalPart2)
|
141 |
+
return false; //0<num2<1 && num1>=1
|
142 |
+
|
143 |
+
//isFractionPart1 == isFactionalPart2
|
144 |
+
if(isFractionalPart1)
|
145 |
+
return fractional(lhsBegin,lhsEnd,rhsBegin,rhsEnd);
|
146 |
+
else
|
147 |
+
return non_fractional(lhsBegin,lhsEnd,rhsBegin,rhsEnd);
|
148 |
+
}
|
149 |
+
};
|
150 |
+
|
151 |
+
|
152 |
+
|
153 |
+
|
154 |
+
|
155 |
+
}// namespace detail
|
156 |
+
|
157 |
+
/***********************************************************************
|
158 |
+
Natural Comparision of Two String using both's (Begin and End Iterator)
|
159 |
+
|
160 |
+
Returns :
|
161 |
+
-1 - String1 < String2
|
162 |
+
0 - String1 == String2
|
163 |
+
1 - String1 > String2
|
164 |
+
|
165 |
+
Suffix 1 represents for components of 1st String
|
166 |
+
Suffix 2 represents for components of 2nd String
|
167 |
+
************************************************************************/
|
168 |
+
|
169 |
+
template<typename ElementType, typename Iterator>
|
170 |
+
bool _compare(\
|
171 |
+
const Iterator &lhsBegin,const Iterator &lhsEnd,\
|
172 |
+
const Iterator &rhsBegin,const Iterator &rhsEnd)
|
173 |
+
{
|
174 |
+
Iterator current1 = lhsBegin,current2 = rhsBegin;
|
175 |
+
|
176 |
+
//Flag for Space Found Check
|
177 |
+
bool flag_found_space1 = false,flag_found_space2 = false;
|
178 |
+
|
179 |
+
|
180 |
+
while(current1!=lhsEnd && current2!=rhsEnd)
|
181 |
+
{
|
182 |
+
//Ignore More than One Continous Space
|
183 |
+
|
184 |
+
/******************************************
|
185 |
+
For HandlingComparision Like
|
186 |
+
Hello 9
|
187 |
+
Hello 10
|
188 |
+
Hello 123
|
189 |
+
******************************************/
|
190 |
+
while(flag_found_space1 && current1!=lhsEnd && *current1==' ') current1++;
|
191 |
+
flag_found_space1=false;
|
192 |
+
if(*current1==' ') flag_found_space1 = true;
|
193 |
+
|
194 |
+
while(flag_found_space2 && current2!=rhsEnd && *current2==' ') current2++;
|
195 |
+
flag_found_space2=false;
|
196 |
+
if(*current2==' ') flag_found_space2 = true;
|
197 |
+
|
198 |
+
|
199 |
+
if( !isdigit(*current1 ) || !isdigit(*current2))
|
200 |
+
{
|
201 |
+
// Normal comparision if any of character is non digit character
|
202 |
+
if(detail::natural_less<ElementType>(*current1,*current2))
|
203 |
+
return true;
|
204 |
+
if(detail::natural_less<ElementType>(*current2,*current1))
|
205 |
+
return false;
|
206 |
+
current1++;
|
207 |
+
current2++;
|
208 |
+
}
|
209 |
+
else
|
210 |
+
{
|
211 |
+
/*********************************
|
212 |
+
Capture Numeric Part of Both String
|
213 |
+
and then using it to compare Both
|
214 |
+
|
215 |
+
***********************************/
|
216 |
+
Iterator last_nondigit1 = std::find_if(current1,lhsEnd,detail::is_not_digit<ElementType>);
|
217 |
+
Iterator last_nondigit2 = std::find_if(current2,rhsEnd,detail::is_not_digit<ElementType>);
|
218 |
+
|
219 |
+
int result = detail::compare_number<ElementType, Iterator>()(\
|
220 |
+
current1,last_nondigit1,(current1>lhsBegin && *(current1-1)=='.'), \
|
221 |
+
current2,last_nondigit2,(current2>rhsBegin && *(current2-1)=='.'));
|
222 |
+
if(result<0)
|
223 |
+
return true;
|
224 |
+
if(result>0)
|
225 |
+
return false;
|
226 |
+
current1 = last_nondigit1;
|
227 |
+
current2 = last_nondigit2;
|
228 |
+
}
|
229 |
+
}
|
230 |
+
|
231 |
+
if (current1 == lhsEnd && current2 == rhsEnd) {
|
232 |
+
return false;
|
233 |
+
} else {
|
234 |
+
return current1 == lhsEnd;
|
235 |
+
}
|
236 |
+
}
|
237 |
+
|
238 |
+
template<typename String>
|
239 |
+
inline bool compare(const String &first ,const String &second)
|
240 |
+
{
|
241 |
+
return _compare<typename String::value_type,typename String::const_iterator>(first.begin(),first.end(),second.begin(),second.end());
|
242 |
+
}
|
243 |
+
template<>
|
244 |
+
inline bool compare(char *const &first ,char *const &second)
|
245 |
+
{
|
246 |
+
char* it1 = first;
|
247 |
+
while(*it1!='\0')it1++;
|
248 |
+
char* it2 = second;
|
249 |
+
while(*it2!='\0')it2++;
|
250 |
+
return _compare<char,char*>(first,it1,second,it2);
|
251 |
+
}
|
252 |
+
|
253 |
+
|
254 |
+
template<typename Container>
|
255 |
+
inline void sort(Container &container)
|
256 |
+
{
|
257 |
+
std::sort(container.begin(),container.end(),compare<typename Container::value_type>);
|
258 |
+
}
|
259 |
+
|
260 |
+
template<typename Iterator>
|
261 |
+
inline void sort(const Iterator &first,const Iterator &end)
|
262 |
+
{
|
263 |
+
std::sort(first,end,compare<typename Iterator::value_type>);
|
264 |
+
}
|
265 |
+
|
266 |
+
template<typename ValueType>
|
267 |
+
inline void sort(ValueType* const first,ValueType* const end)
|
268 |
+
{
|
269 |
+
std::sort(first,end,compare<ValueType>);
|
270 |
+
}
|
271 |
+
|
272 |
+
template<typename ValueType,int N>
|
273 |
+
inline void sort(ValueType container[N])
|
274 |
+
{
|
275 |
+
std::sort(&container[0],&container[0]+N,compare<ValueType>);
|
276 |
+
}
|
277 |
+
|
278 |
+
}//namespace natural
|
279 |
+
}//namespace SI
|
280 |
+
|
281 |
+
#endif
|
third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/config.hpp
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#if defined(__linux__) || defined(__linux) || defined(linux) || defined(_LINUX)
|
4 |
+
#define DYNALO_HAS_LINUX
|
5 |
+
#elif defined(_WIN32) || defined(_WIN64)
|
6 |
+
#define DYNALO_HAS_WINDOWS
|
7 |
+
#elif defined(__APPLE__)
|
8 |
+
#define DYNALO_HAS_MACOS
|
9 |
+
#else
|
10 |
+
#error "dynalo/detail/config.hpp OS Not Supported"
|
11 |
+
#endif
|
12 |
+
|
13 |
+
#define DYNALO_VERSION_MAJOR 1
|
14 |
+
#define DYNALO_VERSION_MINOR 0
|
15 |
+
#define DYNALO_VERSION_PATCH 3
|
16 |
+
#define DYNALO_VERSION 0x010003 /**< major minor patch*/
|
third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/linux/dynalo.hpp
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <string>
|
4 |
+
#include <stdexcept>
|
5 |
+
|
6 |
+
#include <dlfcn.h>
|
7 |
+
|
8 |
+
namespace dynalo { namespace detail
|
9 |
+
{
|
10 |
+
|
11 |
+
inline
|
12 |
+
std::string last_error()
|
13 |
+
{
|
14 |
+
return std::string(::dlerror());
|
15 |
+
}
|
16 |
+
|
17 |
+
namespace native
|
18 |
+
{
|
19 |
+
|
20 |
+
using handle = void*;
|
21 |
+
|
22 |
+
inline handle invalid_handle() { return nullptr; }
|
23 |
+
|
24 |
+
enum class resolve
|
25 |
+
{
|
26 |
+
now = RTLD_NOW,
|
27 |
+
lazy = RTLD_LAZY,
|
28 |
+
};
|
29 |
+
|
30 |
+
namespace name
|
31 |
+
{
|
32 |
+
|
33 |
+
inline std::string prefix() { return std::string("lib"); }
|
34 |
+
inline std::string suffix() { return std::string(); }
|
35 |
+
inline std::string extension() { return std::string("so"); }
|
36 |
+
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
inline
|
42 |
+
native::handle open(const std::string& dyn_lib_path, native::resolve symbol_resolution)
|
43 |
+
{
|
44 |
+
native::handle lib_handle = ::dlopen(dyn_lib_path.c_str(), static_cast<int>(symbol_resolution));
|
45 |
+
if (lib_handle == nullptr)
|
46 |
+
{
|
47 |
+
throw std::runtime_error(std::string("Failed to open [dyn_lib_path:") + dyn_lib_path + "]: " + last_error());
|
48 |
+
}
|
49 |
+
|
50 |
+
return lib_handle;
|
51 |
+
}
|
52 |
+
|
53 |
+
inline
|
54 |
+
void close(native::handle lib_handle)
|
55 |
+
{
|
56 |
+
const int rc = ::dlclose(lib_handle);
|
57 |
+
if (rc != 0)
|
58 |
+
{
|
59 |
+
throw std::runtime_error(std::string("Failed to close the dynamic library: ") + last_error());
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
template <typename FunctionSignature>
|
64 |
+
inline
|
65 |
+
FunctionSignature* get_function(native::handle lib_handle, const std::string& func_name)
|
66 |
+
{
|
67 |
+
void* func_ptr = ::dlsym(lib_handle, func_name.c_str());
|
68 |
+
if (func_ptr == nullptr)
|
69 |
+
{
|
70 |
+
throw std::runtime_error(std::string("Failed to get [func_name:") + func_name + "]: " + last_error());
|
71 |
+
}
|
72 |
+
|
73 |
+
return reinterpret_cast<FunctionSignature*>(func_ptr);
|
74 |
+
}
|
75 |
+
|
76 |
+
}}
|
third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/macos/dynalo.hpp
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <string>
|
4 |
+
#include <stdexcept>
|
5 |
+
|
6 |
+
#include <dlfcn.h>
|
7 |
+
|
8 |
+
namespace dynalo { namespace detail
|
9 |
+
{
|
10 |
+
|
11 |
+
inline
|
12 |
+
std::string last_error()
|
13 |
+
{
|
14 |
+
return std::string(::dlerror());
|
15 |
+
}
|
16 |
+
|
17 |
+
namespace native
|
18 |
+
{
|
19 |
+
|
20 |
+
using handle = void*;
|
21 |
+
|
22 |
+
inline handle invalid_handle() { return nullptr; }
|
23 |
+
|
24 |
+
enum class resolve
|
25 |
+
{
|
26 |
+
now = RTLD_NOW,
|
27 |
+
lazy = RTLD_LAZY,
|
28 |
+
};
|
29 |
+
|
30 |
+
namespace name
|
31 |
+
{
|
32 |
+
|
33 |
+
inline std::string prefix() { return std::string("lib"); }
|
34 |
+
inline std::string suffix() { return std::string(); }
|
35 |
+
inline std::string extension() { return std::string("dylib"); }
|
36 |
+
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
inline
|
42 |
+
native::handle open(const std::string& dyn_lib_path, native::resolve symbol_resolution)
|
43 |
+
{
|
44 |
+
native::handle lib_handle = ::dlopen(dyn_lib_path.c_str(), static_cast<int>(symbol_resolution) );
|
45 |
+
if (lib_handle == nullptr)
|
46 |
+
{
|
47 |
+
throw std::runtime_error(std::string("Failed to open [dyn_lib_path:") + dyn_lib_path + "]: " + last_error());
|
48 |
+
}
|
49 |
+
|
50 |
+
return lib_handle;
|
51 |
+
}
|
52 |
+
|
53 |
+
inline
|
54 |
+
void close(native::handle lib_handle)
|
55 |
+
{
|
56 |
+
const int rc = ::dlclose(lib_handle);
|
57 |
+
if (rc != 0)
|
58 |
+
{
|
59 |
+
throw std::runtime_error(std::string("Failed to close the dynamic library: ") + last_error());
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
template <typename FunctionSignature>
|
64 |
+
inline
|
65 |
+
FunctionSignature* get_function(native::handle lib_handle, const std::string& func_name)
|
66 |
+
{
|
67 |
+
void* func_ptr = ::dlsym(lib_handle, func_name.c_str());
|
68 |
+
if (func_ptr == nullptr)
|
69 |
+
{
|
70 |
+
throw std::runtime_error(std::string("Failed to get [func_name:") + func_name + "]: " + last_error());
|
71 |
+
}
|
72 |
+
|
73 |
+
return reinterpret_cast<FunctionSignature*>(func_ptr);
|
74 |
+
}
|
75 |
+
|
76 |
+
}}
|
third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/windows/dynalo.hpp
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <string>
|
4 |
+
#include <stdexcept>
|
5 |
+
|
6 |
+
#include <Windows.h>
|
7 |
+
#include <strsafe.h>
|
8 |
+
|
9 |
+
namespace dynalo { namespace detail
|
10 |
+
{
|
11 |
+
inline
|
12 |
+
std::string last_error()
|
13 |
+
{
|
14 |
+
// https://msdn.microsoft.com/en-us/library/ms680582%28VS.85%29.aspx
|
15 |
+
LPVOID lpMsgBuf;
|
16 |
+
DWORD dw = ::GetLastError();
|
17 |
+
|
18 |
+
::FormatMessage(
|
19 |
+
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
20 |
+
FORMAT_MESSAGE_FROM_SYSTEM |
|
21 |
+
FORMAT_MESSAGE_IGNORE_INSERTS,
|
22 |
+
NULL,
|
23 |
+
dw,
|
24 |
+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
25 |
+
(LPTSTR) &lpMsgBuf,
|
26 |
+
0, NULL );
|
27 |
+
|
28 |
+
LPVOID lpDisplayBuf = (LPVOID)::LocalAlloc(LMEM_ZEROINIT,
|
29 |
+
(::lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR));
|
30 |
+
|
31 |
+
::StringCchPrintf((LPTSTR)lpDisplayBuf,
|
32 |
+
::LocalSize(lpDisplayBuf) / sizeof(TCHAR),
|
33 |
+
TEXT("Failed with error %d: %s"),
|
34 |
+
dw, lpMsgBuf);
|
35 |
+
|
36 |
+
std::string err_str((LPCTSTR)lpDisplayBuf);
|
37 |
+
|
38 |
+
::LocalFree(lpMsgBuf);
|
39 |
+
::LocalFree(lpDisplayBuf);
|
40 |
+
|
41 |
+
return err_str;
|
42 |
+
}
|
43 |
+
|
44 |
+
|
45 |
+
namespace native
|
46 |
+
{
|
47 |
+
|
48 |
+
using handle = HMODULE;
|
49 |
+
|
50 |
+
inline handle invalid_handle() { return nullptr; }
|
51 |
+
|
52 |
+
// Windows LoadLibrary does not offer flexibility to choose.
|
53 |
+
// These values are ignored.
|
54 |
+
enum class resolve
|
55 |
+
{
|
56 |
+
now,
|
57 |
+
lazy,
|
58 |
+
};
|
59 |
+
|
60 |
+
namespace name
|
61 |
+
{
|
62 |
+
|
63 |
+
inline std::string prefix() { return std::string(); }
|
64 |
+
inline std::string suffix() { return std::string(); }
|
65 |
+
inline std::string extension() { return std::string("dll"); }
|
66 |
+
|
67 |
+
}
|
68 |
+
|
69 |
+
}
|
70 |
+
|
71 |
+
inline
|
72 |
+
native::handle open(const std::string& dyn_lib_path, native::resolve /*symbol_resolution*/)
|
73 |
+
{
|
74 |
+
// Windows LoadLibrary behaviour is most similar to RTLD_NOW
|
75 |
+
native::handle lib_handle = ::LoadLibrary(dyn_lib_path.c_str());
|
76 |
+
if (lib_handle == nullptr)
|
77 |
+
{
|
78 |
+
throw std::runtime_error(std::string("Failed to open [dyn_lib_path:") + dyn_lib_path + "]: " + last_error());
|
79 |
+
}
|
80 |
+
|
81 |
+
return lib_handle;
|
82 |
+
}
|
83 |
+
|
84 |
+
inline
|
85 |
+
void close(native::handle lib_handle)
|
86 |
+
{
|
87 |
+
const BOOL rc = ::FreeLibrary(lib_handle);
|
88 |
+
if (rc == 0) // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683152(v=vs.85).aspx
|
89 |
+
{
|
90 |
+
throw std::runtime_error(std::string("Failed to close the dynamic library: ") + last_error());
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
template <typename FunctionSignature>
|
95 |
+
inline
|
96 |
+
FunctionSignature* get_function(native::handle lib_handle, const std::string& func_name)
|
97 |
+
{
|
98 |
+
FARPROC func_ptr = ::GetProcAddress(lib_handle, func_name.c_str());
|
99 |
+
if (func_ptr == nullptr)
|
100 |
+
{
|
101 |
+
throw std::runtime_error(std::string("Failed to get [func_name:") + func_name + "]: " + last_error());
|
102 |
+
}
|
103 |
+
|
104 |
+
return reinterpret_cast<FunctionSignature*>(func_ptr);
|
105 |
+
}
|
106 |
+
|
107 |
+
}}
|
third-party/DPVO/Pangolin/components/pango_core/include/dynalo/dynalo.hpp
ADDED
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include "detail/config.hpp"
|
4 |
+
|
5 |
+
#if defined(DYNALO_HAS_LINUX)
|
6 |
+
#include "detail/linux/dynalo.hpp"
|
7 |
+
#elif defined(DYNALO_HAS_WINDOWS)
|
8 |
+
#include "detail/windows/dynalo.hpp"
|
9 |
+
#elif defined(DYNALO_HAS_MACOS)
|
10 |
+
#include "detail/macos/dynalo.hpp"
|
11 |
+
#endif
|
12 |
+
|
13 |
+
/// DYNAmic LOading of shared libraries and access to their exported functions
|
14 |
+
namespace dynalo
|
15 |
+
{
|
16 |
+
|
17 |
+
namespace native
|
18 |
+
{
|
19 |
+
|
20 |
+
/// Native handle (usuall a pointer) on the loaded shared library
|
21 |
+
using handle = detail::native::handle;
|
22 |
+
|
23 |
+
/// Symbol resolution options
|
24 |
+
using resolve = detail::native::resolve;
|
25 |
+
|
26 |
+
/// @return An invalid library handle
|
27 |
+
inline
|
28 |
+
handle invalid_handle()
|
29 |
+
{
|
30 |
+
return detail::native::invalid_handle();
|
31 |
+
}
|
32 |
+
|
33 |
+
namespace name
|
34 |
+
{
|
35 |
+
|
36 |
+
/// @return The name prefix of a shared library on the current system
|
37 |
+
inline
|
38 |
+
std::string prefix()
|
39 |
+
{
|
40 |
+
return detail::native::name::prefix();
|
41 |
+
}
|
42 |
+
|
43 |
+
/// @return The name suffix of a shared library on the current system
|
44 |
+
inline
|
45 |
+
std::string suffix()
|
46 |
+
{
|
47 |
+
return detail::native::name::suffix();
|
48 |
+
}
|
49 |
+
|
50 |
+
/// @return The file extension of a shared library on the current system
|
51 |
+
inline
|
52 |
+
std::string extension()
|
53 |
+
{
|
54 |
+
return detail::native::name::extension();
|
55 |
+
}
|
56 |
+
|
57 |
+
}
|
58 |
+
|
59 |
+
}
|
60 |
+
|
61 |
+
/// @param lib_name Name of the library without neither the lib prefix, suffix nor file extension
|
62 |
+
///
|
63 |
+
/// @return The native name of the shared library.
|
64 |
+
/// e.g. If @p lib_name is `awesome`,
|
65 |
+
/// then this function will return `libawesome.so` in Linux and `awesome.dll` in Windows
|
66 |
+
inline
|
67 |
+
std::string to_native_name(const std::string& lib_name)
|
68 |
+
{
|
69 |
+
using namespace native::name;
|
70 |
+
if (!extension().empty())
|
71 |
+
{
|
72 |
+
return prefix() + lib_name + suffix() + std::string(".") + extension();
|
73 |
+
}
|
74 |
+
else
|
75 |
+
{
|
76 |
+
return prefix() + lib_name + suffix();
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
/// Loads a shared library
|
81 |
+
///
|
82 |
+
/// @param dyn_lib_path Path to the shared library file to be loaded
|
83 |
+
/// @param resolution Option for how to treat symbol resolution during library opening.
|
84 |
+
///
|
85 |
+
/// @return The handle of the loaded shared library
|
86 |
+
///
|
87 |
+
/// @throw std::runtime_error If it fails to load the library
|
88 |
+
inline
|
89 |
+
native::handle open(const std::string& dyn_lib_path, native::resolve resolution = native::resolve::lazy)
|
90 |
+
{
|
91 |
+
return detail::open(dyn_lib_path, resolution);
|
92 |
+
}
|
93 |
+
|
94 |
+
/// Unloads the shared library which handle is @p lib_handle
|
95 |
+
///
|
96 |
+
/// @param lib_handle The handle of the library to be unloaded
|
97 |
+
///
|
98 |
+
/// @throw std::runtime_error If it fails to unload the shared library
|
99 |
+
inline
|
100 |
+
void close(native::handle lib_handle)
|
101 |
+
{
|
102 |
+
detail::close(lib_handle);
|
103 |
+
}
|
104 |
+
|
105 |
+
/// Looks up a function in the shared library and returns pointer to it
|
106 |
+
///
|
107 |
+
/// @tparam FunctionSignature The signature of the function to be looked up.
|
108 |
+
/// i.e. `return_type(param_types...)`
|
109 |
+
/// e.g. `void(const char*)`, `bool(int, int)`
|
110 |
+
///
|
111 |
+
/// @param lib_handle The handle of the library that contains the function
|
112 |
+
/// @param func_name The name of the function to find
|
113 |
+
///
|
114 |
+
/// @return A pointer to the @p func_name function
|
115 |
+
///
|
116 |
+
/// @throw std::runtime_error If it fails to find the @p func_name function
|
117 |
+
template <typename FunctionSignature>
|
118 |
+
inline
|
119 |
+
FunctionSignature* get_function(native::handle lib_handle, const std::string& func_name)
|
120 |
+
{
|
121 |
+
return detail::get_function<FunctionSignature>(lib_handle, func_name);
|
122 |
+
}
|
123 |
+
|
124 |
+
|
125 |
+
/// A shared library
|
126 |
+
///
|
127 |
+
/// This class wraps the open/close/get_function functions of the dynalo namespace:
|
128 |
+
/// <ul>
|
129 |
+
/// <li>The shared library is loaded in the class' constructor</li>
|
130 |
+
/// <li>You can get pointer to a functio using library::get_function</li>
|
131 |
+
/// <li>The shared library is automatically unloaed in the destructor</li>
|
132 |
+
/// </ul>
|
133 |
+
class library
|
134 |
+
{
|
135 |
+
private:
|
136 |
+
native::handle m_handle;
|
137 |
+
|
138 |
+
public:
|
139 |
+
library() = delete;
|
140 |
+
library(const library&) = delete;
|
141 |
+
library& operator=(const library&) = delete;
|
142 |
+
|
143 |
+
library(library&& other)
|
144 |
+
: m_handle(other.m_handle)
|
145 |
+
{
|
146 |
+
other.m_handle = native::invalid_handle();
|
147 |
+
}
|
148 |
+
|
149 |
+
library& operator=(library&& other)
|
150 |
+
{
|
151 |
+
m_handle = other.m_handle;
|
152 |
+
other.m_handle = native::invalid_handle();
|
153 |
+
return *this;
|
154 |
+
}
|
155 |
+
|
156 |
+
/// Unloads the shared library using dynalo::close
|
157 |
+
~library()
|
158 |
+
{
|
159 |
+
if (m_handle != native::invalid_handle())
|
160 |
+
{
|
161 |
+
dynalo::close(m_handle);
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
/// Loads a shared library using dynalo::open
|
166 |
+
explicit library(const std::string& dyn_lib_path)
|
167 |
+
: m_handle(dynalo::open(dyn_lib_path))
|
168 |
+
{}
|
169 |
+
|
170 |
+
/// Returns a pointer to the @p func_name function using dynalo::get_function
|
171 |
+
template <typename FunctionSignature>
|
172 |
+
FunctionSignature* get_function(const std::string& func_name)
|
173 |
+
{
|
174 |
+
return dynalo::get_function<FunctionSignature>(m_handle, func_name);
|
175 |
+
}
|
176 |
+
|
177 |
+
/// Returns the native handle of the loaded shared library
|
178 |
+
native::handle get_native_handle()
|
179 |
+
{
|
180 |
+
return m_handle;
|
181 |
+
}
|
182 |
+
};
|
183 |
+
|
184 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/dynalo/symbol_helper.hpp
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
// This header can be included multiple times
|
3 |
+
// It should come in handy for switching betwee, exporting and importing symbols
|
4 |
+
//
|
5 |
+
// USAGE
|
6 |
+
//
|
7 |
+
// DYNALO_EXPORT <return type> DYNALO_CALL <function name>(<function argument types...>)
|
8 |
+
//
|
9 |
+
// EXAMPLE
|
10 |
+
//
|
11 |
+
// EXPORTING FUNCTIONS
|
12 |
+
//
|
13 |
+
// #define DYNALO_EXPORT_SYMBOLS
|
14 |
+
// #include <dynalo/symbol_helper.hpp>
|
15 |
+
//
|
16 |
+
// DYNALO_EXPORT int32_t DYNALO_CALL add_integers(const int32_t a, const int32_t b);
|
17 |
+
// DYNALO_EXPORT void DYNALO_CALL print_message(const char* message);
|
18 |
+
//
|
19 |
+
// IMPORTING FUNCTIONS
|
20 |
+
//
|
21 |
+
// #define DYNALO_IMPORT_SYMBOLS
|
22 |
+
// #include <dynalo/symbol_helper.hpp>
|
23 |
+
//
|
24 |
+
// DYNALO_EXPORT int32_t DYNALO_CALL add_integers(const int32_t a, const int32_t b);
|
25 |
+
// DYNALO_EXPORT void DYNALO_CALL print_message(const char* message);
|
26 |
+
//
|
27 |
+
|
28 |
+
#if !defined(DYNALO_DEMANGLE)
|
29 |
+
#if defined(__cplusplus)
|
30 |
+
#define DYNALO_DEMANGLE extern "C"
|
31 |
+
#else
|
32 |
+
#define DYNALO_DEMANGLE
|
33 |
+
#endif
|
34 |
+
#endif
|
35 |
+
|
36 |
+
#if defined(DYNALO_EXPORT_SYMBOLS)
|
37 |
+
#undef DYNALO_EXPORT_SYMBOLS
|
38 |
+
|
39 |
+
#if defined(DYNALO_EXPORT)
|
40 |
+
#undef DYNALO_EXPORT
|
41 |
+
#endif
|
42 |
+
|
43 |
+
#ifdef WIN32
|
44 |
+
#define DYNALO_EXPORT DYNALO_DEMANGLE __declspec(dllexport)
|
45 |
+
#else
|
46 |
+
#define DYNALO_EXPORT DYNALO_DEMANGLE
|
47 |
+
#endif
|
48 |
+
|
49 |
+
#elif defined(DYNALO_IMPORT_SYMBOLS)
|
50 |
+
#undef DYNALO_IMPORT_SYMBOLS
|
51 |
+
|
52 |
+
#if defined(DYNALO_EXPORT)
|
53 |
+
#undef DYNALO_EXPORT
|
54 |
+
#endif
|
55 |
+
|
56 |
+
#ifdef WIN32
|
57 |
+
#define DYNALO_EXPORT DYNALO_DEMANGLE __declspec(dllimport)
|
58 |
+
#else
|
59 |
+
#define DYNALO_EXPORT DYNALO_DEMANGLE extern
|
60 |
+
#endif
|
61 |
+
|
62 |
+
#else
|
63 |
+
#error "dynalo/symbol_helper.hpp Define either DYNALO_EXPORT_SYMBOLS or DYNALO_IMPORT_SYMBOLS"
|
64 |
+
#endif
|
65 |
+
|
66 |
+
#if !defined(DYNALO_CALL)
|
67 |
+
#ifdef _MSC_VER
|
68 |
+
#define DYNALO_CALL __cdecl
|
69 |
+
#else
|
70 |
+
#define DYNALO_CALL
|
71 |
+
#endif
|
72 |
+
#endif
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/compat/glutbitmap.h
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2013 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <pangolin/gl/glplatform.h>
|
31 |
+
#include <pangolin/gl/glfont.h>
|
32 |
+
|
33 |
+
#ifdef HAVE_GLES
|
34 |
+
GLfloat g_raster_pos[4];
|
35 |
+
|
36 |
+
inline void glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
|
37 |
+
{
|
38 |
+
// find object point (x,y,z)' in pixel coords
|
39 |
+
GLdouble projection[16];
|
40 |
+
GLdouble modelview[16];
|
41 |
+
GLint view[4];
|
42 |
+
|
43 |
+
#ifdef HAVE_GLES_2
|
44 |
+
std::copy(pangolin::glEngine().projection.top().m, pangolin::glEngine().projection.top().m+16, projection);
|
45 |
+
std::copy(pangolin::glEngine().modelview.top().m, pangolin::glEngine().modelview.top().m+16, modelview);
|
46 |
+
#else
|
47 |
+
glGetDoublev(GL_PROJECTION_MATRIX, projection );
|
48 |
+
glGetDoublev(GL_MODELVIEW_MATRIX, modelview );
|
49 |
+
#endif
|
50 |
+
glGetIntegerv(GL_VIEWPORT, view );
|
51 |
+
|
52 |
+
pangolin::glProject(x, y, z, modelview, projection, view,
|
53 |
+
g_raster_pos, g_raster_pos + 1, g_raster_pos + 2);
|
54 |
+
}
|
55 |
+
|
56 |
+
inline void glRasterPos2f(GLfloat x, GLfloat y)
|
57 |
+
{
|
58 |
+
glRasterPos3f(x,y,1.0f);
|
59 |
+
}
|
60 |
+
|
61 |
+
inline void glRasterPos2i(GLint x, GLint y)
|
62 |
+
{
|
63 |
+
glRasterPos3f((GLfloat)x, (GLfloat)y, 1.0f );
|
64 |
+
}
|
65 |
+
|
66 |
+
inline void glRasterPos3fv(const GLfloat *v){
|
67 |
+
glRasterPos3f(v[0],v[1],v[2]);
|
68 |
+
}
|
69 |
+
|
70 |
+
inline void glRasterPos2fv(const GLfloat *v){
|
71 |
+
glRasterPos3f(v[0],v[1],1.0f);
|
72 |
+
}
|
73 |
+
#endif // HAVE_GLES
|
74 |
+
|
75 |
+
inline void glutBitmapString(void * /*font*/, const unsigned char *str)
|
76 |
+
{
|
77 |
+
#ifndef HAVE_GLES
|
78 |
+
float g_raster_pos[4];
|
79 |
+
glGetFloatv(GL_CURRENT_RASTER_POSITION, g_raster_pos);
|
80 |
+
#endif
|
81 |
+
|
82 |
+
pangolin::GlFont::I().Text( (const char *)str ).DrawWindow(
|
83 |
+
g_raster_pos[0], g_raster_pos[1], g_raster_pos[2]
|
84 |
+
);
|
85 |
+
}
|
86 |
+
|
87 |
+
inline int glutBitmapLength(void * /*font*/, const unsigned char *str)
|
88 |
+
{
|
89 |
+
return (int)(pangolin::GlFont::I().Text((const char *)str).Width());
|
90 |
+
}
|
91 |
+
|
92 |
+
#define GLUT_BITMAP_HELVETICA_12 0;
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/compat/type_traits.h
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2013 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <pangolin/platform.h>
|
31 |
+
|
32 |
+
#include <typeinfo>
|
33 |
+
|
34 |
+
#include <type_traits>
|
35 |
+
|
36 |
+
// enable_if From Boost
|
37 |
+
namespace pangolin
|
38 |
+
{
|
39 |
+
template <bool B, class T = void>
|
40 |
+
struct enable_if_c {
|
41 |
+
typedef T type;
|
42 |
+
};
|
43 |
+
|
44 |
+
template <class T>
|
45 |
+
struct enable_if_c<false, T> {};
|
46 |
+
|
47 |
+
template <class Cond, class T = void>
|
48 |
+
struct enable_if : public enable_if_c<Cond::value, T> {};
|
49 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/factory/factory.h
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <memory>
|
4 |
+
#include <map>
|
5 |
+
#include <pangolin/utils/param_set.h>
|
6 |
+
|
7 |
+
namespace pangolin
|
8 |
+
{
|
9 |
+
|
10 |
+
class FactoryInterface {
|
11 |
+
public:
|
12 |
+
using Name = std::string;
|
13 |
+
using Precedence = int32_t;
|
14 |
+
|
15 |
+
virtual ~FactoryInterface(){};
|
16 |
+
|
17 |
+
virtual std::map<Name,Precedence> Schemes() const = 0;
|
18 |
+
|
19 |
+
virtual const char* Description() const = 0;
|
20 |
+
|
21 |
+
virtual ParamSet Params() const = 0;
|
22 |
+
};
|
23 |
+
|
24 |
+
template<typename T>
|
25 |
+
class TypedFactoryInterface : public FactoryInterface
|
26 |
+
{
|
27 |
+
public:
|
28 |
+
virtual std::unique_ptr<T> Open(const Uri& uri) = 0;
|
29 |
+
};
|
30 |
+
|
31 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/factory/factory_help.h
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#include <iostream>
|
2 |
+
|
3 |
+
#include <pangolin/factory/factory_registry.h>
|
4 |
+
|
5 |
+
namespace pangolin {
|
6 |
+
|
7 |
+
/// The level of detail to use when printing
|
8 |
+
enum HelpVerbosity{
|
9 |
+
SUMMARY = 0, // Short description
|
10 |
+
SYNOPSIS, // + examples, aliases
|
11 |
+
PARAMS // + list all arguments
|
12 |
+
};
|
13 |
+
|
14 |
+
/// Print to \p out general guidance on how to use Pangolin factory URL's
|
15 |
+
/// \p out the stream to stream the help message to
|
16 |
+
/// \p color whether ANSI Color codes should be used for formatting
|
17 |
+
void PrintSchemeHelp(std::ostream& out = std::cout, bool color = true);
|
18 |
+
|
19 |
+
/// Print to \p out Factories registered to \p registry that match \p scheme_filter.
|
20 |
+
/// \p out the stream to stream the help message to
|
21 |
+
/// \p registry the registy to use
|
22 |
+
/// \p factory_type the typeid(T) of the FactoryInterface T to list
|
23 |
+
/// \p scheme_filter a constraint on schemes to print, or empty if all should be listed
|
24 |
+
/// \p level the level of detail to use when printing (see enum above)
|
25 |
+
/// \p color whether ANSI Color codes should be used for formatting
|
26 |
+
void PrintFactoryRegistryDetails(
|
27 |
+
std::ostream& out, const pangolin::FactoryRegistry& registry, std::type_index factory_type,
|
28 |
+
const std::string& scheme_filter = "", HelpVerbosity level = HelpVerbosity::SYNOPSIS, bool color = true
|
29 |
+
);
|
30 |
+
|
31 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/factory/factory_registry.h
ADDED
@@ -0,0 +1,218 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011-2013 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <vector>
|
31 |
+
#include <map>
|
32 |
+
#include <unordered_set>
|
33 |
+
#include <algorithm>
|
34 |
+
#include <typeindex>
|
35 |
+
#include <regex>
|
36 |
+
#include <exception>
|
37 |
+
|
38 |
+
#include <pangolin/factory/factory.h>
|
39 |
+
|
40 |
+
namespace pangolin
|
41 |
+
{
|
42 |
+
|
43 |
+
/// Registry class for managing FactoryInterface instances.
|
44 |
+
/// Use Factory instantiation to decouple implementation and use
|
45 |
+
/// of interface types and easy configure construction through
|
46 |
+
/// a URI-like syntax.
|
47 |
+
class FactoryRegistry
|
48 |
+
{
|
49 |
+
public:
|
50 |
+
using TypeRegistry = std::vector<std::shared_ptr<FactoryInterface>>;
|
51 |
+
|
52 |
+
/// Singleton instance of FactoryRegistry
|
53 |
+
static std::shared_ptr<FactoryRegistry> I();
|
54 |
+
|
55 |
+
~FactoryRegistry() {}
|
56 |
+
|
57 |
+
/// Register a new TypedFactoryInterface with the registry
|
58 |
+
template<typename T>
|
59 |
+
bool RegisterFactory( const std::shared_ptr<TypedFactoryInterface<T>>& factory )
|
60 |
+
{
|
61 |
+
TypeRegistry& registry = type_registries[typeid(T)];
|
62 |
+
registry.push_back(factory);
|
63 |
+
return true;
|
64 |
+
}
|
65 |
+
|
66 |
+
/// Unregister an existing factory.
|
67 |
+
/// Do nothing if factory isn't registered.
|
68 |
+
template<typename T>
|
69 |
+
void UnregisterFactory(TypedFactoryInterface<T>* factory)
|
70 |
+
{
|
71 |
+
TypeRegistry& registry = type_registries[typeid(T)];
|
72 |
+
|
73 |
+
registry.erase(
|
74 |
+
std::remove_if( registry.begin(), registry.end(),
|
75 |
+
[&](auto& i){ return i.factory.get() == factory;}),
|
76 |
+
registry.end());
|
77 |
+
}
|
78 |
+
|
79 |
+
/// Remove all Factories from all types
|
80 |
+
void UnregisterAllFactories()
|
81 |
+
{
|
82 |
+
type_registries.clear();
|
83 |
+
}
|
84 |
+
|
85 |
+
/// Attempt to Construct an instance of \tparam T using the highest precedence
|
86 |
+
/// \class FactoryInterface which acceps \param uri
|
87 |
+
/// \throws FactoryRegistry::Exception
|
88 |
+
template<typename T>
|
89 |
+
std::unique_ptr<T> Construct(const Uri& uri)
|
90 |
+
{
|
91 |
+
TypeRegistry& registry = type_registries[typeid(T)];
|
92 |
+
|
93 |
+
TypeRegistry candidates;
|
94 |
+
std::copy_if(registry.begin(), registry.end(), std::back_inserter(candidates), [&](auto& factory){
|
95 |
+
const auto schemes = factory->Schemes();
|
96 |
+
return schemes.find(uri.scheme) != schemes.end();
|
97 |
+
});
|
98 |
+
|
99 |
+
if(candidates.size() == 0) {
|
100 |
+
throw NoMatchingSchemeException( uri);
|
101 |
+
}
|
102 |
+
|
103 |
+
// Order candidates by precedence.
|
104 |
+
std::sort(candidates.begin(), candidates.end(), [&](auto& lhs, auto& rhs){
|
105 |
+
// We know that all candidates contain scheme
|
106 |
+
return lhs->Schemes()[uri.scheme] < rhs->Schemes()[uri.scheme];
|
107 |
+
});
|
108 |
+
|
109 |
+
// Try candidates in order
|
110 |
+
for(auto& factory : candidates) {
|
111 |
+
std::unordered_set<std::string> orphan_params = ParamReader( factory->Params(), uri ).FindUnrecognizedUriParams();
|
112 |
+
if( orphan_params.size() == 0 )
|
113 |
+
{
|
114 |
+
TypedFactoryInterface<T>* factoryT = dynamic_cast<TypedFactoryInterface<T>*>(factory.get());
|
115 |
+
if(factoryT) {
|
116 |
+
std::unique_ptr<T> video = factoryT->Open(uri);
|
117 |
+
if(video) return video;
|
118 |
+
}
|
119 |
+
}else{
|
120 |
+
throw ParameterMismatchException(uri, orphan_params);
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
throw NoFactorySucceededException(uri);
|
125 |
+
}
|
126 |
+
|
127 |
+
const TypeRegistry& GetFactories(std::type_index type) const
|
128 |
+
{
|
129 |
+
const auto& ifac = type_registries.find(type);
|
130 |
+
if(ifac != type_registries.end()) {
|
131 |
+
return ifac->second;
|
132 |
+
}else{
|
133 |
+
throw std::runtime_error("No factories for this type.");
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
template<typename T>
|
138 |
+
const TypeRegistry& GetFactories() const {
|
139 |
+
return GetFactories(typeid(T));
|
140 |
+
}
|
141 |
+
|
142 |
+
/// Base class for FactoryRegistry Exceptions
|
143 |
+
class Exception : public std::exception {
|
144 |
+
public:
|
145 |
+
Exception(const Uri& uri) : uri(uri) {
|
146 |
+
err = "Unable to open URI";
|
147 |
+
err += "\n full_uri: " + uri.full_uri;
|
148 |
+
err += "\n scheme: " + uri.scheme;
|
149 |
+
err += "\n params:\n";
|
150 |
+
for(const auto& p : uri.params) {
|
151 |
+
err += " " + p.first + " = " + p.second + "\n";
|
152 |
+
}
|
153 |
+
}
|
154 |
+
virtual const char* what() const throw() override {
|
155 |
+
return err.c_str();
|
156 |
+
}
|
157 |
+
const Uri uri;
|
158 |
+
std::string err;
|
159 |
+
};
|
160 |
+
|
161 |
+
class NoMatchingSchemeException : public Exception {
|
162 |
+
public:
|
163 |
+
NoMatchingSchemeException(const Uri& uri) : Exception(uri) {
|
164 |
+
err += " No matching scheme.";
|
165 |
+
}
|
166 |
+
};
|
167 |
+
|
168 |
+
class NoFactorySucceededException : public Exception {
|
169 |
+
public:
|
170 |
+
NoFactorySucceededException(const Uri& uri) : Exception(uri) {
|
171 |
+
err += " No factory succeeded.";
|
172 |
+
}
|
173 |
+
};
|
174 |
+
|
175 |
+
class ParameterMismatchException : public Exception {
|
176 |
+
public:
|
177 |
+
ParameterMismatchException(const Uri& uri, const std::unordered_set<std::string>& unrecognized_params) :
|
178 |
+
Exception(uri), unrecognized_params(unrecognized_params) {
|
179 |
+
std::stringstream ss;
|
180 |
+
for(const auto& p : unrecognized_params ) ss << p << ",";
|
181 |
+
err += " Unrecognized options for scheme (" + ss.str() + ")";
|
182 |
+
}
|
183 |
+
const std::unordered_set<std::string> unrecognized_params;
|
184 |
+
};
|
185 |
+
|
186 |
+
private:
|
187 |
+
std::map<std::type_index, TypeRegistry> type_registries;
|
188 |
+
};
|
189 |
+
|
190 |
+
/// Macro to define factory entry point. Add a corresponding line in your cmake:
|
191 |
+
/// `PangolinRegisterFactory(MyInterfaceType MyFactoryType)`
|
192 |
+
/// in order to have the method added to an initialization method for MyInterfaceType
|
193 |
+
///
|
194 |
+
/// \tparam x is the factory interface class (such as WindowInterface, VideoInterface, etc)
|
195 |
+
/// \return true iff registration was successful.
|
196 |
+
#define PANGOLIN_REGISTER_FACTORY(x) \
|
197 |
+
bool Register ## x ## Factory()
|
198 |
+
// {
|
199 |
+
// return FactoryRegistry::I()->RegisterFactory<x>(std::make_shared<MyFactoryClass>());
|
200 |
+
// }
|
201 |
+
|
202 |
+
/// Macro to define factory entry point with automatic static initialization.
|
203 |
+
/// Use this instead of the macro above to automatically register a factory when the compilation
|
204 |
+
/// unit is loaded, and you can guarentee the symbols will remain.
|
205 |
+
/// e.g. within a dynamic library which you will explicitly load, or within the same
|
206 |
+
/// compilation unit as your main().
|
207 |
+
///
|
208 |
+
/// \tparam x is the factory interface class (such as WindowInterface, VideoInterface, etc)
|
209 |
+
/// \return true iff registration was successful.
|
210 |
+
// Forward declaration; static load variable; definition
|
211 |
+
#define PANGOLIN_REGISTER_FACTORY_WITH_STATIC_INITIALIZER(x) \
|
212 |
+
bool Register ## x ## Factory(); \
|
213 |
+
static const bool Load ## x ## Success = Register ## x ## Factory(); \
|
214 |
+
bool Register ## x ## Factory()
|
215 |
+
// {
|
216 |
+
// return FactoryRegistry::I()->RegisterFactory<x>(std::make_shared<MyFactoryClass>());
|
217 |
+
// }
|
218 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/pangolin.h
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
// This header is here for compatibility when building
|
31 |
+
// all of Pangolin. You are recommended to include only
|
32 |
+
// what you need, especially when building without a
|
33 |
+
// particular feature, such as GUI for Video, otherwise
|
34 |
+
// you'll receive errors.
|
35 |
+
|
36 |
+
#include <pangolin/platform.h>
|
37 |
+
|
38 |
+
#include <pangolin/display/display.h>
|
39 |
+
#include <pangolin/display/view.h>
|
40 |
+
#include <pangolin/display/widgets.h>
|
41 |
+
#include <pangolin/gl/colour.h>
|
42 |
+
#include <pangolin/gl/gl.h>
|
43 |
+
#include <pangolin/gl/gldraw.h>
|
44 |
+
#include <pangolin/gl/glstate.h>
|
45 |
+
#include <pangolin/gl/glvbo.h>
|
46 |
+
#include <pangolin/handler/handler.h>
|
47 |
+
#include <pangolin/image/image_io.h>
|
48 |
+
#include <pangolin/plot/plotter.h>
|
49 |
+
#include <pangolin/var/varextra.h>
|
50 |
+
#include <pangolin/video/video.h>
|
51 |
+
#include <pangolin/video/video_input.h>
|
52 |
+
#include <pangolin/video/video_output.h>
|
53 |
+
|
54 |
+
#ifdef _ANDROID_
|
55 |
+
# include <pangolin/display/device/display_android.h>
|
56 |
+
#endif
|
57 |
+
|
58 |
+
// Let other libraries headers know about Pangolin
|
59 |
+
#define HAVE_PANGOLIN
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/platform.h
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
// Include portable printf-style format macros
|
31 |
+
#define __STDC_FORMAT_MACROS
|
32 |
+
|
33 |
+
#define PANGOLIN_UNUSED(x) (void)(x)
|
34 |
+
|
35 |
+
#ifdef __GNUC__
|
36 |
+
# define PANGOLIN_DEPRECATED(x) __attribute__((deprecated(x)))
|
37 |
+
#elif defined(_MSC_VER)
|
38 |
+
# define PANGOLIN_DEPRECATED(x) __declspec(deprecated(x))
|
39 |
+
#else
|
40 |
+
# define PANGOLIN_DEPRECATED(x)
|
41 |
+
#endif
|
42 |
+
|
43 |
+
#ifdef _MSC_VER
|
44 |
+
# define __thread __declspec(thread)
|
45 |
+
# include <pangolin/pangolin_export.h>
|
46 |
+
#else
|
47 |
+
# define PANGOLIN_EXPORT
|
48 |
+
#endif //_MSVC_
|
49 |
+
|
50 |
+
// HOST / DEVICE Annotations
|
51 |
+
#ifdef __CUDACC__
|
52 |
+
# include <cuda_runtime.h>
|
53 |
+
# define PANGO_HOST_DEVICE __host__ __device__
|
54 |
+
#else
|
55 |
+
# define PANGO_HOST_DEVICE
|
56 |
+
#endif
|
57 |
+
|
58 |
+
// Workaround for Apple-Clangs lack of thread_local support
|
59 |
+
#if defined(__clang__)
|
60 |
+
# if !__has_feature(cxx_thread_local)
|
61 |
+
# define PANGO_NO_THREADLOCAL
|
62 |
+
# endif
|
63 |
+
#endif
|
64 |
+
|
65 |
+
#include <pangolin/utils/assert.h>
|
66 |
+
#include <pangolin/utils/log.h>
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/argagg.hpp
ADDED
@@ -0,0 +1,1548 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* @file
|
3 |
+
* @brief
|
4 |
+
* Defines a very simple command line argument parser.
|
5 |
+
*
|
6 |
+
* @copyright
|
7 |
+
* Copyright (c) 2017 Viet The Nguyen
|
8 |
+
*
|
9 |
+
* @copyright
|
10 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
11 |
+
* of this software and associated documentation files (the "Software"), to
|
12 |
+
* deal in the Software without restriction, including without limitation the
|
13 |
+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
14 |
+
* sell copies of the Software, and to permit persons to whom the Software is
|
15 |
+
* furnished to do so, subject to the following conditions:
|
16 |
+
*
|
17 |
+
* @copyright
|
18 |
+
* The above copyright notice and this permission notice shall be included in
|
19 |
+
* all copies or substantial portions of the Software.
|
20 |
+
*
|
21 |
+
* @copyright
|
22 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
27 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
28 |
+
* IN THE SOFTWARE.
|
29 |
+
*/
|
30 |
+
#pragma once
|
31 |
+
#ifndef ARGAGG_ARGAGG_ARGAGG_HPP
|
32 |
+
#define ARGAGG_ARGAGG_ARGAGG_HPP
|
33 |
+
|
34 |
+
#ifdef __unix__
|
35 |
+
#include <stdio.h>
|
36 |
+
#include <unistd.h>
|
37 |
+
#endif // #ifdef __unix__
|
38 |
+
|
39 |
+
#include <algorithm>
|
40 |
+
#include <array>
|
41 |
+
#include <cstdlib>
|
42 |
+
#include <cstring>
|
43 |
+
#include <cctype>
|
44 |
+
#include <iterator>
|
45 |
+
#include <ostream>
|
46 |
+
#include <sstream>
|
47 |
+
#include <stdexcept>
|
48 |
+
#include <string>
|
49 |
+
#include <unordered_map>
|
50 |
+
#include <utility>
|
51 |
+
#include <vector>
|
52 |
+
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @brief
|
56 |
+
* There are only two hard things in Computer Science: cache invalidation and
|
57 |
+
* naming things (Phil Karlton).
|
58 |
+
*
|
59 |
+
* The names of types have to be succint and clear. This has turned out to be a
|
60 |
+
* more difficult thing than I expected. Here you'll find a quick overview of
|
61 |
+
* the type names you'll find in this namespace (and thus "library").
|
62 |
+
*
|
63 |
+
* When a program is invoked it is passed a number of "command line arguments".
|
64 |
+
* Each of these "arguments" is a string (C-string to be more precise). An
|
65 |
+
* "option" is a command line argument that has special meaning. This library
|
66 |
+
* recognizes a command line argument as a potential option if it starts with a
|
67 |
+
* dash ('-') or double-dash ('--').
|
68 |
+
*
|
69 |
+
* A "parser" is a set of "definitions" (not a literal std::set but rather a
|
70 |
+
* std::vector). A parser is represented by the argagg::parser struct.
|
71 |
+
*
|
72 |
+
* A "definition" is a structure with four components that define what
|
73 |
+
* "options" are recognized. The four components are the name of the option,
|
74 |
+
* the strings that represent the option, the option's help text, and how many
|
75 |
+
* arguments the option should expect. "Flags" are the individual strings that
|
76 |
+
* represent the option ("-v" and "--verbose" are flags for the "verbose"
|
77 |
+
* option). A definition is represented by the argagg::definition struct.
|
78 |
+
*
|
79 |
+
* Note at this point that the word "option" can be used interchangeably to
|
80 |
+
* mean the notion of an option and the actual instance of an option given a
|
81 |
+
* set of command line arguments. To be unambiguous we use a "definition" to
|
82 |
+
* represent the notion of an option and an "option result" to represent an
|
83 |
+
* actual option parsed from a set of command line arguments. An "option
|
84 |
+
* result" is represented by the argagg::option_result struct.
|
85 |
+
*
|
86 |
+
* There's one more wrinkle to this: an option can show up multiple times in a
|
87 |
+
* given set of command line arguments. For example, "-n 1 -n 2 -n 3". This
|
88 |
+
* will parse into three distinct argagg::option_result instances, but all of
|
89 |
+
* them correspond to the same argagg::definition. We aggregate these into the
|
90 |
+
* argagg::option_results struct which represents "all parser results for a
|
91 |
+
* given option definition". This argagg::option_results is basically a
|
92 |
+
* std::vector of argagg::option_result.
|
93 |
+
*
|
94 |
+
* Options aren't the only thing parsed though. Positional arguments are also
|
95 |
+
* parsed. Thus a parser produces a result that contains both option results
|
96 |
+
* and positional arguments. The parser results are represented by the
|
97 |
+
* argagg::parser_results struct. All option results are stored in a mapping
|
98 |
+
* from option name to the argagg::option_results. All positional arguments are
|
99 |
+
* simply stored in a vector of C-strings.
|
100 |
+
*/
|
101 |
+
namespace argagg {
|
102 |
+
|
103 |
+
|
104 |
+
/**
|
105 |
+
* @brief
|
106 |
+
* This exception is thrown when a long option is parsed and is given an
|
107 |
+
* argument using the "=" syntax but the option doesn't expect an argument.
|
108 |
+
*/
|
109 |
+
struct unexpected_argument_error
|
110 |
+
: public std::runtime_error {
|
111 |
+
using std::runtime_error::runtime_error;
|
112 |
+
};
|
113 |
+
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @brief
|
117 |
+
* This exception is thrown when an option is parsed unexpectedly such as when
|
118 |
+
* an argument was expected for a previous option or if an option was found
|
119 |
+
* that has not been defined.
|
120 |
+
*/
|
121 |
+
struct unexpected_option_error
|
122 |
+
: public std::runtime_error {
|
123 |
+
using std::runtime_error::runtime_error;
|
124 |
+
};
|
125 |
+
|
126 |
+
|
127 |
+
/**
|
128 |
+
* @brief
|
129 |
+
* This exception is thrown when an option requires an argument but is not
|
130 |
+
* provided one. This can happen if another flag was found after the option or
|
131 |
+
* if we simply reach the end of the command line arguments.
|
132 |
+
*/
|
133 |
+
struct option_lacks_argument_error
|
134 |
+
: public std::runtime_error {
|
135 |
+
using std::runtime_error::runtime_error;
|
136 |
+
};
|
137 |
+
|
138 |
+
|
139 |
+
/**
|
140 |
+
* @brief
|
141 |
+
* This exception is thrown when an option's flag is invalid. This can be the
|
142 |
+
* case if the flag is not prefixed by one or two hyphens or contains non
|
143 |
+
* alpha-numeric characters after the hypens. See is_valid_flag_definition()
|
144 |
+
* for more details.
|
145 |
+
*/
|
146 |
+
struct invalid_flag
|
147 |
+
: public std::runtime_error {
|
148 |
+
using std::runtime_error::runtime_error;
|
149 |
+
};
|
150 |
+
|
151 |
+
|
152 |
+
/**
|
153 |
+
* @brief
|
154 |
+
* The set of template instantiations that convert C-strings to other types for
|
155 |
+
* the option_result::as(), option_results::as(), parser_results::as(), and
|
156 |
+
* parser_results::all_as() methods are placed in this namespace.
|
157 |
+
*/
|
158 |
+
namespace convert {
|
159 |
+
|
160 |
+
/**
|
161 |
+
* @brief
|
162 |
+
* Explicit instantiations of this function are used to convert arguments to
|
163 |
+
* types.
|
164 |
+
*/
|
165 |
+
template <typename T>
|
166 |
+
T arg(const char* arg);
|
167 |
+
|
168 |
+
}
|
169 |
+
|
170 |
+
|
171 |
+
/**
|
172 |
+
* @brief
|
173 |
+
* Represents a single option parse result.
|
174 |
+
*
|
175 |
+
* You can check if this has an argument by using the implicit boolean
|
176 |
+
* conversion.
|
177 |
+
*/
|
178 |
+
struct option_result {
|
179 |
+
|
180 |
+
/**
|
181 |
+
* @brief
|
182 |
+
* Argument parsed for this single option. If no argument was parsed this
|
183 |
+
* will be set to nullptr.
|
184 |
+
*/
|
185 |
+
const char* arg;
|
186 |
+
|
187 |
+
/**
|
188 |
+
* @brief
|
189 |
+
* Converts the argument parsed for this single option instance into the
|
190 |
+
* given type using the type matched conversion function
|
191 |
+
* argagg::convert::arg(). If there was not an argument parsed for this
|
192 |
+
* single option instance then a argagg::option_lacks_argument_error
|
193 |
+
* exception is thrown. The specific conversion function may throw other
|
194 |
+
* exceptions.
|
195 |
+
*/
|
196 |
+
template <typename T>
|
197 |
+
T as() const;
|
198 |
+
|
199 |
+
/**
|
200 |
+
* @brief
|
201 |
+
* Converts the argument parsed for this single option instance into the
|
202 |
+
* given type using the type matched conversion function
|
203 |
+
* argagg::convert::arg(). If there was not an argument parsed for this
|
204 |
+
* single option instance then the provided default value is returned
|
205 |
+
* instead. If the conversion function throws an exception then it is ignored
|
206 |
+
* and the default value is returned.
|
207 |
+
*/
|
208 |
+
template <typename T>
|
209 |
+
T as(const T& t) const;
|
210 |
+
|
211 |
+
/**
|
212 |
+
* @brief
|
213 |
+
* Since we have the argagg::option_result::as() API we might as well alias
|
214 |
+
* it as an implicit conversion operator. This performs implicit conversion
|
215 |
+
* using the argagg::option_result::as() method.
|
216 |
+
*
|
217 |
+
* @note
|
218 |
+
* An implicit boolean conversion specialization exists which returns false
|
219 |
+
* if there is no argument for this single option instance and true
|
220 |
+
* otherwise. This specialization DOES NOT convert the argument to a bool. If
|
221 |
+
* you need to convert the argument to a bool then use the as() API.
|
222 |
+
*/
|
223 |
+
template <typename T>
|
224 |
+
operator T () const;
|
225 |
+
|
226 |
+
};
|
227 |
+
|
228 |
+
|
229 |
+
/**
|
230 |
+
* @brief
|
231 |
+
* Represents multiple option parse results for a single option. If treated as
|
232 |
+
* a single parse result it defaults to the last parse result. Note that an
|
233 |
+
* instance of this struct is always created even if no option results are
|
234 |
+
* parsed for a given definition. In that case it will simply be empty.
|
235 |
+
*
|
236 |
+
* To check if the associated option showed up at all simply use the implicit
|
237 |
+
* boolean conversion or check if count() is greater than zero.
|
238 |
+
*/
|
239 |
+
struct option_results {
|
240 |
+
|
241 |
+
/**
|
242 |
+
* @brief
|
243 |
+
* All option parse results for this option.
|
244 |
+
*/
|
245 |
+
std::vector<option_result> all;
|
246 |
+
|
247 |
+
/**
|
248 |
+
* @brief
|
249 |
+
* Gets the number of times the option shows up.
|
250 |
+
*/
|
251 |
+
std::size_t count() const;
|
252 |
+
|
253 |
+
/**
|
254 |
+
* @brief
|
255 |
+
* Gets a single option parse result by index.
|
256 |
+
*/
|
257 |
+
option_result& operator [] (std::size_t index);
|
258 |
+
|
259 |
+
/**
|
260 |
+
* @brief
|
261 |
+
* Gets a single option result by index.
|
262 |
+
*/
|
263 |
+
const option_result& operator [] (std::size_t index) const;
|
264 |
+
|
265 |
+
/**
|
266 |
+
* @brief
|
267 |
+
* Converts the argument parsed for the LAST option parse result for the
|
268 |
+
* parent definition to the provided type. For example, if this was for "-f 1
|
269 |
+
* -f 2 -f 3" then calling this method for an integer type will return 3. If
|
270 |
+
* there are no option parse results then a std::out_of_range exception is
|
271 |
+
* thrown. Any exceptions thrown by option_result::as() are not
|
272 |
+
* handled.
|
273 |
+
*/
|
274 |
+
template <typename T>
|
275 |
+
T as() const;
|
276 |
+
|
277 |
+
/**
|
278 |
+
* @brief
|
279 |
+
* Converts the argument parsed for the LAST option parse result for the
|
280 |
+
* parent definition to the provided type. For example, if this was for "-f 1
|
281 |
+
* -f 2 -f 3" then calling this method for an integer type will return 3. If
|
282 |
+
* there are no option parse results then the provided default value is
|
283 |
+
* returned instead.
|
284 |
+
*/
|
285 |
+
template <typename T>
|
286 |
+
T as(const T& t) const;
|
287 |
+
|
288 |
+
/**
|
289 |
+
* @brief
|
290 |
+
* Since we have the option_results::as() API we might as well alias
|
291 |
+
* it as an implicit conversion operator. This performs implicit conversion
|
292 |
+
* using the option_results::as() method.
|
293 |
+
*
|
294 |
+
* @note
|
295 |
+
* An implicit boolean conversion specialization exists which returns false
|
296 |
+
* if there is no argument for this single option instance and true
|
297 |
+
* otherwise. This specialization DOES NOT convert the argument to a bool. If
|
298 |
+
* you need to convert the argument to a bool then use the as() API.
|
299 |
+
*/
|
300 |
+
template <typename T>
|
301 |
+
operator T () const;
|
302 |
+
|
303 |
+
};
|
304 |
+
|
305 |
+
|
306 |
+
/**
|
307 |
+
* @brief
|
308 |
+
* Represents all results of the parser including options and positional
|
309 |
+
* arguments.
|
310 |
+
*/
|
311 |
+
struct parser_results {
|
312 |
+
|
313 |
+
/**
|
314 |
+
* @brief
|
315 |
+
* Returns the name of the program from the original arguments list. This is
|
316 |
+
* always the first argument.
|
317 |
+
*/
|
318 |
+
const char* program;
|
319 |
+
|
320 |
+
/**
|
321 |
+
* @brief
|
322 |
+
* Maps from definition name to the structure which contains the parser
|
323 |
+
* results for that definition.
|
324 |
+
*/
|
325 |
+
std::unordered_map<std::string, option_results> options;
|
326 |
+
|
327 |
+
/**
|
328 |
+
* @brief
|
329 |
+
* Vector of positional arguments.
|
330 |
+
*/
|
331 |
+
std::vector<const char*> pos;
|
332 |
+
|
333 |
+
/**
|
334 |
+
* @brief
|
335 |
+
* Used to check if an option was specified at all.
|
336 |
+
*/
|
337 |
+
bool has_option(const std::string& name) const;
|
338 |
+
|
339 |
+
/**
|
340 |
+
* @brief
|
341 |
+
* Get the parser results for the given definition. If the definition never
|
342 |
+
* showed up then the exception from the unordered_map access will bubble
|
343 |
+
* through so check if the flag exists in the first place with has_option().
|
344 |
+
*/
|
345 |
+
option_results& operator [] (const std::string& name);
|
346 |
+
|
347 |
+
/**
|
348 |
+
* @brief
|
349 |
+
* Get the parser results for the given definition. If the definition never
|
350 |
+
* showed up then the exception from the unordered_map access will bubble
|
351 |
+
* through so check if the flag exists in the first place with has_option().
|
352 |
+
*/
|
353 |
+
const option_results& operator [] (const std::string& name) const;
|
354 |
+
|
355 |
+
/**
|
356 |
+
* @brief
|
357 |
+
* Gets the number of positional arguments.
|
358 |
+
*/
|
359 |
+
std::size_t count() const;
|
360 |
+
|
361 |
+
/**
|
362 |
+
* @brief
|
363 |
+
* Gets a positional argument by index.
|
364 |
+
*/
|
365 |
+
const char* operator [] (std::size_t index) const;
|
366 |
+
|
367 |
+
/**
|
368 |
+
* @brief
|
369 |
+
* Gets a positional argument converted to the given type.
|
370 |
+
*/
|
371 |
+
template <typename T>
|
372 |
+
T as(std::size_t i = 0) const;
|
373 |
+
|
374 |
+
/**
|
375 |
+
* @brief
|
376 |
+
* Gets all positional arguments converted to the given type.
|
377 |
+
*/
|
378 |
+
template <typename T>
|
379 |
+
std::vector<T> all_as() const;
|
380 |
+
|
381 |
+
};
|
382 |
+
|
383 |
+
|
384 |
+
/**
|
385 |
+
* @brief
|
386 |
+
* An option definition which essentially represents what an option is.
|
387 |
+
*/
|
388 |
+
struct definition {
|
389 |
+
|
390 |
+
/**
|
391 |
+
* @brief
|
392 |
+
* Name of the option. Option parser results are keyed by this name.
|
393 |
+
*/
|
394 |
+
const std::string name;
|
395 |
+
|
396 |
+
/**
|
397 |
+
* @brief
|
398 |
+
* List of strings to match that correspond to this option. Should be fully
|
399 |
+
* specified with hyphens (e.g. "-v" or "--verbose").
|
400 |
+
*/
|
401 |
+
std::vector<std::string> flags;
|
402 |
+
|
403 |
+
/**
|
404 |
+
* @brief
|
405 |
+
* Help string for this option.
|
406 |
+
*/
|
407 |
+
std::string help;
|
408 |
+
|
409 |
+
/**
|
410 |
+
* @brief
|
411 |
+
* Number of arguments this option requires. Must be 0 or 1. All other values
|
412 |
+
* have undefined behavior. Okay, the code actually works with positive
|
413 |
+
* values in general, but it's unorthodox command line behavior.
|
414 |
+
*/
|
415 |
+
unsigned int num_args;
|
416 |
+
|
417 |
+
/**
|
418 |
+
* @brief
|
419 |
+
* Returns true if this option does not want any arguments.
|
420 |
+
*/
|
421 |
+
bool wants_no_arguments() const;
|
422 |
+
|
423 |
+
/**
|
424 |
+
* @brief
|
425 |
+
* Returns true if this option requires arguments.
|
426 |
+
*/
|
427 |
+
bool requires_arguments() const;
|
428 |
+
|
429 |
+
};
|
430 |
+
|
431 |
+
|
432 |
+
/**
|
433 |
+
* @brief
|
434 |
+
* Checks whether or not a command line argument should be processed as an
|
435 |
+
* option flag. This is very similar to is_valid_flag_definition() but must
|
436 |
+
* allow for short flag groups (e.g. "-abc") and equal-assigned long flag
|
437 |
+
* arguments (e.g. "--output=foo.txt").
|
438 |
+
*/
|
439 |
+
bool cmd_line_arg_is_option_flag(
|
440 |
+
const char* s);
|
441 |
+
|
442 |
+
|
443 |
+
/**
|
444 |
+
* @brief
|
445 |
+
* Checks whether a flag in an option definition is valid. I suggest reading
|
446 |
+
* through the function source to understand what dictates a valid.
|
447 |
+
*/
|
448 |
+
bool is_valid_flag_definition(
|
449 |
+
const char* s);
|
450 |
+
|
451 |
+
|
452 |
+
/**
|
453 |
+
* @brief
|
454 |
+
* Tests whether or not a valid flag is short. Assumes the provided cstring is
|
455 |
+
* already a valid flag.
|
456 |
+
*/
|
457 |
+
bool flag_is_short(
|
458 |
+
const char* s);
|
459 |
+
|
460 |
+
|
461 |
+
/**
|
462 |
+
* @brief
|
463 |
+
* Contains two maps which aid in option parsing. The first map, @ref
|
464 |
+
* short_map, maps from a short flag (just a character) to a pointer to the
|
465 |
+
* original @ref definition that the flag represents. The second map, @ref
|
466 |
+
* long_map, maps from a long flag (an std::string) to a pointer to the
|
467 |
+
* original @ref definition that the flag represents.
|
468 |
+
*
|
469 |
+
* This object is usually a temporary that only exists during the parsing
|
470 |
+
* operation. It is typically constructed using @ref validate_definitions().
|
471 |
+
*/
|
472 |
+
struct parser_map {
|
473 |
+
|
474 |
+
/**
|
475 |
+
* @brief
|
476 |
+
* Maps from a short flag (just a character) to a pointer to the original
|
477 |
+
* @ref definition that the flag represents.
|
478 |
+
*/
|
479 |
+
std::array<const definition*, 256> short_map;
|
480 |
+
|
481 |
+
/**
|
482 |
+
* @brief
|
483 |
+
* Maps from a long flag (an std::string) to a pointer to the original @ref
|
484 |
+
* definition that the flag represents.
|
485 |
+
*/
|
486 |
+
std::unordered_map<std::string, const definition*> long_map;
|
487 |
+
|
488 |
+
/**
|
489 |
+
* @brief
|
490 |
+
* Returns true if the provided short flag exists in the map object.
|
491 |
+
*/
|
492 |
+
bool known_short_flag(
|
493 |
+
const char flag) const;
|
494 |
+
|
495 |
+
/**
|
496 |
+
* @brief
|
497 |
+
* If the short flag exists in the map object then it is returned by this
|
498 |
+
* method. If it doesn't then nullptr will be returned.
|
499 |
+
*/
|
500 |
+
const definition* get_definition_for_short_flag(
|
501 |
+
const char flag) const;
|
502 |
+
|
503 |
+
/**
|
504 |
+
* @brief
|
505 |
+
* Returns true if the provided long flag exists in the map object.
|
506 |
+
*/
|
507 |
+
bool known_long_flag(
|
508 |
+
const std::string& flag) const;
|
509 |
+
|
510 |
+
/**
|
511 |
+
* @brief
|
512 |
+
* If the long flag exists in the map object then it is returned by this
|
513 |
+
* method. If it doesn't then nullptr will be returned.
|
514 |
+
*/
|
515 |
+
const definition* get_definition_for_long_flag(
|
516 |
+
const std::string& flag) const;
|
517 |
+
|
518 |
+
};
|
519 |
+
|
520 |
+
|
521 |
+
/**
|
522 |
+
* @brief
|
523 |
+
* Validates a collection (specifically an std::vector) of @ref definition
|
524 |
+
* objects by checking if the contained flags are valid. If the set of @ref
|
525 |
+
* definition objects is not valid then an exception is thrown. Upon successful
|
526 |
+
* validation a @ref parser_map object is returned.
|
527 |
+
*/
|
528 |
+
parser_map validate_definitions(
|
529 |
+
const std::vector<definition>& definitions);
|
530 |
+
|
531 |
+
|
532 |
+
/**
|
533 |
+
* @brief
|
534 |
+
* A list of option definitions used to inform how to parse arguments.
|
535 |
+
*/
|
536 |
+
struct parser {
|
537 |
+
|
538 |
+
/**
|
539 |
+
* @brief
|
540 |
+
* Vector of the option definitions which inform this parser how to parse
|
541 |
+
* the command line arguments.
|
542 |
+
*/
|
543 |
+
std::vector<definition> definitions;
|
544 |
+
|
545 |
+
/**
|
546 |
+
* @brief
|
547 |
+
* Parses the provided command line arguments and returns the results as
|
548 |
+
* @ref parser_results.
|
549 |
+
*
|
550 |
+
* @note
|
551 |
+
* This method is not thread-safe and assumes that no modifications are made
|
552 |
+
* to the definitions member field during the extent of this method call.
|
553 |
+
*/
|
554 |
+
parser_results parse(int argc, const char** argv) const;
|
555 |
+
|
556 |
+
/**
|
557 |
+
* @brief
|
558 |
+
* Through strict interpretation of pointer casting rules, despite this being
|
559 |
+
* a safe operation, C++ doesn't allow implicit casts from <tt>char**</tt> to
|
560 |
+
* <tt>const char**</tt> so here's an overload that performs a const_cast,
|
561 |
+
* which is typically frowned upon but is safe here.
|
562 |
+
*/
|
563 |
+
parser_results parse(int argc, char** argv) const;
|
564 |
+
|
565 |
+
};
|
566 |
+
|
567 |
+
|
568 |
+
/**
|
569 |
+
* @brief
|
570 |
+
* A convenience output stream that will accumulate what is streamed to it and
|
571 |
+
* then, on destruction, format the accumulated string using the fmt program
|
572 |
+
* (via the argagg::fmt_string() function) to the provided std::ostream.
|
573 |
+
*
|
574 |
+
* Example use:
|
575 |
+
*
|
576 |
+
* @code
|
577 |
+
* {
|
578 |
+
* argagg::fmt_ostream f(std::cerr);
|
579 |
+
* f << "Usage: " << really_long_string << std::endl;
|
580 |
+
* } // on destruction here the formatted string will be streamed to std::cerr
|
581 |
+
* @endcode
|
582 |
+
*
|
583 |
+
* @note
|
584 |
+
* This only has formatting behavior if the <tt>__unix__</tt> preprocessor
|
585 |
+
* definition is defined since formatting relies on the POSIX API for forking,
|
586 |
+
* executing a process, and reading/writing to/from file descriptors. If that
|
587 |
+
* preprocessor definition is not defined then this class has the same overall
|
588 |
+
* behavior except the output string is not formatted (basically streams
|
589 |
+
* whatever the accumulated string is). See arggg::fmt_string().
|
590 |
+
*/
|
591 |
+
struct fmt_ostream : public std::ostringstream {
|
592 |
+
|
593 |
+
/**
|
594 |
+
* @brief
|
595 |
+
* Reference to the final output stream that the formatted string will be
|
596 |
+
* streamed to.
|
597 |
+
*/
|
598 |
+
std::ostream& output;
|
599 |
+
|
600 |
+
/**
|
601 |
+
* @brief
|
602 |
+
* Construct to output to the provided output stream when this object is
|
603 |
+
* destroyed.
|
604 |
+
*/
|
605 |
+
fmt_ostream(std::ostream& output);
|
606 |
+
|
607 |
+
/**
|
608 |
+
* @brief
|
609 |
+
* Special destructor that will format the accumulated string using fmt (via
|
610 |
+
* the argagg::fmt_string() function) and stream it to the std::ostream
|
611 |
+
* stored.
|
612 |
+
*/
|
613 |
+
~fmt_ostream();
|
614 |
+
|
615 |
+
};
|
616 |
+
|
617 |
+
|
618 |
+
/**
|
619 |
+
* @brief
|
620 |
+
* Processes the provided string using the fmt util and returns the resulting
|
621 |
+
* output as a string. Not the most efficient (in time or space) but gets the
|
622 |
+
* job done.
|
623 |
+
*
|
624 |
+
* This function is cowardly so if there are any errors encountered such as a
|
625 |
+
* syscall returning -1 then the input string is returned.
|
626 |
+
*
|
627 |
+
* @note
|
628 |
+
* This only has formatting behavior if the <tt>__unix__</tt> preprocessor
|
629 |
+
* definition is defined since it relies on the POSIX API for forking,
|
630 |
+
* executing a process, reading/writing to/from file descriptors, and the
|
631 |
+
* existence of the fmt util.
|
632 |
+
*/
|
633 |
+
std::string fmt_string(const std::string& s);
|
634 |
+
|
635 |
+
|
636 |
+
} // namespace argagg
|
637 |
+
|
638 |
+
|
639 |
+
/**
|
640 |
+
* @brief
|
641 |
+
* Writes the option help to the given stream.
|
642 |
+
*/
|
643 |
+
std::ostream& operator << (std::ostream& os, const argagg::parser& x);
|
644 |
+
|
645 |
+
|
646 |
+
// ---- end of declarations, header-only implementations follow ----
|
647 |
+
|
648 |
+
|
649 |
+
namespace argagg {
|
650 |
+
|
651 |
+
|
652 |
+
template <typename T>
|
653 |
+
T option_result::as() const
|
654 |
+
{
|
655 |
+
if (this->arg) {
|
656 |
+
return convert::arg<T>(this->arg);
|
657 |
+
} else {
|
658 |
+
throw option_lacks_argument_error("option has no argument");
|
659 |
+
}
|
660 |
+
}
|
661 |
+
|
662 |
+
|
663 |
+
template <typename T>
|
664 |
+
T option_result::as(const T& t) const
|
665 |
+
{
|
666 |
+
if (this->arg) {
|
667 |
+
try {
|
668 |
+
return convert::arg<T>(this->arg);
|
669 |
+
} catch (...) {
|
670 |
+
return t;
|
671 |
+
}
|
672 |
+
} else {
|
673 |
+
// I actually think this will never happen. To call this method you have
|
674 |
+
// to access a specific option_result for an option. If there's a
|
675 |
+
// specific option_result then the option was found. If the option
|
676 |
+
// requires an argument then it will definitely have an argument
|
677 |
+
// otherwise the parser would have complained.
|
678 |
+
return t;
|
679 |
+
}
|
680 |
+
}
|
681 |
+
|
682 |
+
|
683 |
+
template <typename T>
|
684 |
+
option_result::operator T () const
|
685 |
+
{
|
686 |
+
return this->as<T>();
|
687 |
+
}
|
688 |
+
|
689 |
+
|
690 |
+
template <> inline
|
691 |
+
option_result::operator bool () const
|
692 |
+
{
|
693 |
+
return this->arg != nullptr;
|
694 |
+
}
|
695 |
+
|
696 |
+
|
697 |
+
inline
|
698 |
+
std::size_t option_results::count() const
|
699 |
+
{
|
700 |
+
return this->all.size();
|
701 |
+
}
|
702 |
+
|
703 |
+
|
704 |
+
inline
|
705 |
+
option_result& option_results::operator [] (std::size_t index)
|
706 |
+
{
|
707 |
+
return this->all[index];
|
708 |
+
}
|
709 |
+
|
710 |
+
|
711 |
+
inline
|
712 |
+
const option_result& option_results::operator [] (std::size_t index) const
|
713 |
+
{
|
714 |
+
return this->all[index];
|
715 |
+
}
|
716 |
+
|
717 |
+
|
718 |
+
template <typename T>
|
719 |
+
T option_results::as() const
|
720 |
+
{
|
721 |
+
if (this->all.size() == 0) {
|
722 |
+
throw std::out_of_range("no option arguments to convert");
|
723 |
+
}
|
724 |
+
return this->all.back().as<T>();
|
725 |
+
}
|
726 |
+
|
727 |
+
|
728 |
+
template <typename T>
|
729 |
+
T option_results::as(const T& t) const
|
730 |
+
{
|
731 |
+
if (this->all.size() == 0) {
|
732 |
+
return t;
|
733 |
+
}
|
734 |
+
return this->all.back().as<T>(t);
|
735 |
+
}
|
736 |
+
|
737 |
+
|
738 |
+
template <typename T>
|
739 |
+
option_results::operator T () const
|
740 |
+
{
|
741 |
+
return this->as<T>();
|
742 |
+
}
|
743 |
+
|
744 |
+
|
745 |
+
template <> inline
|
746 |
+
option_results::operator bool () const
|
747 |
+
{
|
748 |
+
return this->all.size() > 0;
|
749 |
+
}
|
750 |
+
|
751 |
+
|
752 |
+
inline
|
753 |
+
bool parser_results::has_option(const std::string& name) const
|
754 |
+
{
|
755 |
+
const auto it = this->options.find(name);
|
756 |
+
return ( it != this->options.end()) && it->second.all.size() > 0;
|
757 |
+
}
|
758 |
+
|
759 |
+
|
760 |
+
inline
|
761 |
+
option_results& parser_results::operator [] (const std::string& name)
|
762 |
+
{
|
763 |
+
return this->options.at(name);
|
764 |
+
}
|
765 |
+
|
766 |
+
|
767 |
+
inline
|
768 |
+
const option_results&
|
769 |
+
parser_results::operator [] (const std::string& name) const
|
770 |
+
{
|
771 |
+
return this->options.at(name);
|
772 |
+
}
|
773 |
+
|
774 |
+
|
775 |
+
inline
|
776 |
+
std::size_t parser_results::count() const
|
777 |
+
{
|
778 |
+
return this->pos.size();
|
779 |
+
}
|
780 |
+
|
781 |
+
|
782 |
+
inline
|
783 |
+
const char* parser_results::operator [] (std::size_t index) const
|
784 |
+
{
|
785 |
+
return this->pos[index];
|
786 |
+
}
|
787 |
+
|
788 |
+
|
789 |
+
template <typename T>
|
790 |
+
T parser_results::as(std::size_t i) const
|
791 |
+
{
|
792 |
+
return convert::arg<T>(this->pos[i]);
|
793 |
+
}
|
794 |
+
|
795 |
+
|
796 |
+
template <typename T>
|
797 |
+
std::vector<T> parser_results::all_as() const
|
798 |
+
{
|
799 |
+
std::vector<T> v(this->pos.size());
|
800 |
+
std::transform(
|
801 |
+
this->pos.begin(), this->pos.end(), v.begin(),
|
802 |
+
[](const char* arg) {
|
803 |
+
return convert::arg<T>(arg);
|
804 |
+
});
|
805 |
+
return v;
|
806 |
+
}
|
807 |
+
|
808 |
+
|
809 |
+
inline
|
810 |
+
bool definition::wants_no_arguments() const
|
811 |
+
{
|
812 |
+
return this->num_args == 0;
|
813 |
+
}
|
814 |
+
|
815 |
+
|
816 |
+
inline
|
817 |
+
bool definition::requires_arguments() const
|
818 |
+
{
|
819 |
+
return this->num_args > 0;
|
820 |
+
}
|
821 |
+
|
822 |
+
|
823 |
+
inline
|
824 |
+
bool cmd_line_arg_is_option_flag(
|
825 |
+
const char* s)
|
826 |
+
{
|
827 |
+
auto len = std::strlen(s);
|
828 |
+
|
829 |
+
// The shortest possible flag has two characters: a hyphen and an
|
830 |
+
// alpha-numeric character.
|
831 |
+
if (len < 2) {
|
832 |
+
return false;
|
833 |
+
}
|
834 |
+
|
835 |
+
// All flags must start with a hyphen.
|
836 |
+
if (s[0] != '-') {
|
837 |
+
return false;
|
838 |
+
}
|
839 |
+
|
840 |
+
// Shift the name forward by a character to account for the initial hyphen.
|
841 |
+
// This means if s was originally "-v" then name will be "v".
|
842 |
+
const char* name = s + 1;
|
843 |
+
|
844 |
+
// Check if we're dealing with a long flag.
|
845 |
+
bool is_long = false;
|
846 |
+
if (s[1] == '-') {
|
847 |
+
is_long = true;
|
848 |
+
|
849 |
+
// Just -- is not a valid flag.
|
850 |
+
if (len == 2) {
|
851 |
+
return false;
|
852 |
+
}
|
853 |
+
|
854 |
+
// Shift the name forward to account for the extra hyphen. This means if s
|
855 |
+
// was originally "--output" then name will be "output".
|
856 |
+
name = s + 2;
|
857 |
+
}
|
858 |
+
|
859 |
+
// The first character of the flag name must be alpha-numeric. This is to
|
860 |
+
// prevent things like "---a" from being valid flags.
|
861 |
+
len = std::strlen(name);
|
862 |
+
if (!std::isalnum(name[0])) {
|
863 |
+
return false;
|
864 |
+
}
|
865 |
+
|
866 |
+
// At this point in is_valid_flag_definition() we would check if the short
|
867 |
+
// flag has only one character. At command line specification you can group
|
868 |
+
// short flags together or even add an argument to a short flag without a
|
869 |
+
// space delimiter. Thus we don't check if this has only one character
|
870 |
+
// because it might not.
|
871 |
+
|
872 |
+
// If this is a long flag then we expect all characters *up to* an equal sign
|
873 |
+
// to be alpha-numeric or a hyphen. After the equal sign you are specify the
|
874 |
+
// argument to a long flag which can be basically anything.
|
875 |
+
if (is_long) {
|
876 |
+
bool encountered_equal = false;
|
877 |
+
return std::all_of(name, name + len, [&](const char& c) {
|
878 |
+
if (encountered_equal) {
|
879 |
+
return true;
|
880 |
+
} else {
|
881 |
+
if (c == '=') {
|
882 |
+
encountered_equal = true;
|
883 |
+
return true;
|
884 |
+
}
|
885 |
+
return std::isalnum(c) || c == '-';
|
886 |
+
}
|
887 |
+
});
|
888 |
+
}
|
889 |
+
|
890 |
+
// At this point we are not dealing with a long flag. We already checked that
|
891 |
+
// the first character is alpha-numeric so we've got the case of a single
|
892 |
+
// short flag covered. This might be a short flag group though and we might
|
893 |
+
// be tempted to check that each character of the short flag group is
|
894 |
+
// alpha-numeric. However, you can specify the argument for a short flag
|
895 |
+
// without a space delimiter (e.g. "-I/usr/local/include") so you can't tell
|
896 |
+
// if the rest of a short flag group is part of the argument or not unless
|
897 |
+
// you know what is a defined flag or not. We leave that kind of processing
|
898 |
+
// to the parser.
|
899 |
+
return true;
|
900 |
+
}
|
901 |
+
|
902 |
+
|
903 |
+
inline
|
904 |
+
bool is_valid_flag_definition(
|
905 |
+
const char* s)
|
906 |
+
{
|
907 |
+
auto len = std::strlen(s);
|
908 |
+
|
909 |
+
// The shortest possible flag has two characters: a hyphen and an
|
910 |
+
// alpha-numeric character.
|
911 |
+
if (len < 2) {
|
912 |
+
return false;
|
913 |
+
}
|
914 |
+
|
915 |
+
// All flags must start with a hyphen.
|
916 |
+
if (s[0] != '-') {
|
917 |
+
return false;
|
918 |
+
}
|
919 |
+
|
920 |
+
// Shift the name forward by a character to account for the initial hyphen.
|
921 |
+
// This means if s was originally "-v" then name will be "v".
|
922 |
+
const char* name = s + 1;
|
923 |
+
|
924 |
+
// Check if we're dealing with a long flag.
|
925 |
+
bool is_long = false;
|
926 |
+
if (s[1] == '-') {
|
927 |
+
is_long = true;
|
928 |
+
|
929 |
+
// Just -- is not a valid flag.
|
930 |
+
if (len == 2) {
|
931 |
+
return false;
|
932 |
+
}
|
933 |
+
|
934 |
+
// Shift the name forward to account for the extra hyphen. This means if s
|
935 |
+
// was originally "--output" then name will be "output".
|
936 |
+
name = s + 2;
|
937 |
+
}
|
938 |
+
|
939 |
+
// The first character of the flag name must be alpha-numeric. This is to
|
940 |
+
// prevent things like "---a" from being valid flags.
|
941 |
+
len = std::strlen(name);
|
942 |
+
if (!std::isalnum(name[0])) {
|
943 |
+
return false;
|
944 |
+
}
|
945 |
+
|
946 |
+
// If this is a short flag then it must only have one character.
|
947 |
+
if (!is_long && len > 1) {
|
948 |
+
return false;
|
949 |
+
}
|
950 |
+
|
951 |
+
// The rest of the characters must be alpha-numeric, but long flags are
|
952 |
+
// allowed to have hyphens too.
|
953 |
+
return std::all_of(name + 1, name + len, [&](const char& c) {
|
954 |
+
return std::isalnum(c) || (c == '-' && is_long);
|
955 |
+
});
|
956 |
+
}
|
957 |
+
|
958 |
+
|
959 |
+
inline
|
960 |
+
bool flag_is_short(
|
961 |
+
const char* s)
|
962 |
+
{
|
963 |
+
return s[0] == '-' && std::isalnum(s[1]);
|
964 |
+
}
|
965 |
+
|
966 |
+
|
967 |
+
inline
|
968 |
+
bool parser_map::known_short_flag(
|
969 |
+
const char flag) const
|
970 |
+
{
|
971 |
+
return this->short_map[flag] != nullptr;
|
972 |
+
}
|
973 |
+
|
974 |
+
|
975 |
+
inline
|
976 |
+
const definition* parser_map::get_definition_for_short_flag(
|
977 |
+
const char flag) const
|
978 |
+
{
|
979 |
+
return this->short_map[flag];
|
980 |
+
}
|
981 |
+
|
982 |
+
|
983 |
+
inline
|
984 |
+
bool parser_map::known_long_flag(
|
985 |
+
const std::string& flag) const
|
986 |
+
{
|
987 |
+
const auto existing_long_flag = this->long_map.find(flag);
|
988 |
+
return existing_long_flag != long_map.end();
|
989 |
+
}
|
990 |
+
|
991 |
+
|
992 |
+
inline
|
993 |
+
const definition* parser_map::get_definition_for_long_flag(
|
994 |
+
const std::string& flag) const
|
995 |
+
{
|
996 |
+
const auto existing_long_flag = this->long_map.find(flag);
|
997 |
+
if (existing_long_flag == long_map.end()) {
|
998 |
+
return nullptr;
|
999 |
+
}
|
1000 |
+
return existing_long_flag->second;
|
1001 |
+
}
|
1002 |
+
|
1003 |
+
|
1004 |
+
inline
|
1005 |
+
parser_map validate_definitions(
|
1006 |
+
const std::vector<definition>& definitions)
|
1007 |
+
{
|
1008 |
+
std::unordered_map<std::string, const definition*> long_map;
|
1009 |
+
parser_map map {{{nullptr}}, std::move(long_map)};
|
1010 |
+
|
1011 |
+
for (auto& defn : definitions) {
|
1012 |
+
|
1013 |
+
if (defn.flags.size() == 0) {
|
1014 |
+
std::ostringstream msg;
|
1015 |
+
msg << "option \"" << defn.name << "\" has no flag definitions";
|
1016 |
+
throw invalid_flag(msg.str());
|
1017 |
+
}
|
1018 |
+
|
1019 |
+
for (auto& flag : defn.flags) {
|
1020 |
+
|
1021 |
+
if (!is_valid_flag_definition(flag.data())) {
|
1022 |
+
std::ostringstream msg;
|
1023 |
+
msg << "flag \"" << flag << "\" specified for option \"" << defn.name
|
1024 |
+
<< "\" is invalid";
|
1025 |
+
throw invalid_flag(msg.str());
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
if (flag_is_short(flag.data())) {
|
1029 |
+
const int short_flag_letter = flag[1];
|
1030 |
+
const auto existing_short_flag = map.short_map[short_flag_letter];
|
1031 |
+
bool short_flag_already_exists = (existing_short_flag != nullptr);
|
1032 |
+
if (short_flag_already_exists) {
|
1033 |
+
std::ostringstream msg;
|
1034 |
+
msg << "duplicate short flag \"" << flag
|
1035 |
+
<< "\" found, specified by both option \"" << defn.name
|
1036 |
+
<< "\" and option \"" << existing_short_flag->name;
|
1037 |
+
throw invalid_flag(msg.str());
|
1038 |
+
}
|
1039 |
+
map.short_map[short_flag_letter] = &defn;
|
1040 |
+
continue;
|
1041 |
+
}
|
1042 |
+
|
1043 |
+
// If we're here then this is a valid, long-style flag.
|
1044 |
+
if (map.known_long_flag(flag)) {
|
1045 |
+
const auto existing_long_flag = map.get_definition_for_long_flag(flag);
|
1046 |
+
std::ostringstream msg;
|
1047 |
+
msg << "duplicate long flag \"" << flag
|
1048 |
+
<< "\" found, specified by both option \"" << defn.name
|
1049 |
+
<< "\" and option \"" << existing_long_flag->name;
|
1050 |
+
throw invalid_flag(msg.str());
|
1051 |
+
}
|
1052 |
+
map.long_map.insert(std::make_pair(flag, &defn));
|
1053 |
+
}
|
1054 |
+
}
|
1055 |
+
|
1056 |
+
return map;
|
1057 |
+
}
|
1058 |
+
|
1059 |
+
|
1060 |
+
inline
|
1061 |
+
parser_results parser::parse(int argc, const char** argv) const
|
1062 |
+
{
|
1063 |
+
// Inspect each definition to see if its valid. You may wonder "why don't
|
1064 |
+
// you do this validation on construction?" I had thought about it but
|
1065 |
+
// realized that since I've made the parser an aggregate type (granted it
|
1066 |
+
// just "aggregates" a single vector) I would need to track any changes to
|
1067 |
+
// the definitions vector and re-run the validity check in order to
|
1068 |
+
// maintain this expected "validity invariant" on the object. That would
|
1069 |
+
// then require hiding the definitions vector as a private entry and then
|
1070 |
+
// turning the parser into a thin interface (by re-exposing setters and
|
1071 |
+
// getters) to the vector methods just so that I can catch when the
|
1072 |
+
// definition has been modified. It seems much simpler to just enforce the
|
1073 |
+
// validity when you actually want to parser because it's at the moment of
|
1074 |
+
// parsing that you know the definitions are complete.
|
1075 |
+
parser_map map = validate_definitions(this->definitions);
|
1076 |
+
|
1077 |
+
// Initialize the parser results that we'll be returning. Store the program
|
1078 |
+
// name (assumed to be the first command line argument) and initialize
|
1079 |
+
// everything else as empty.
|
1080 |
+
std::unordered_map<std::string, option_results> options {};
|
1081 |
+
std::vector<const char*> pos;
|
1082 |
+
parser_results results {argv[0], std::move(options), std::move(pos)};
|
1083 |
+
|
1084 |
+
// Add an empty option result for each definition.
|
1085 |
+
for (const auto& defn : this->definitions) {
|
1086 |
+
option_results opt_results {{}};
|
1087 |
+
results.options.insert(
|
1088 |
+
std::make_pair(defn.name, opt_results));
|
1089 |
+
}
|
1090 |
+
|
1091 |
+
// Don't start off ignoring flags. We only ignore flags after a -- shows up
|
1092 |
+
// in the command line arguments.
|
1093 |
+
bool ignore_flags = false;
|
1094 |
+
|
1095 |
+
// Keep track of any options that are expecting arguments.
|
1096 |
+
const char* last_flag_expecting_args = nullptr;
|
1097 |
+
option_result* last_option_expecting_args = nullptr;
|
1098 |
+
unsigned int num_option_args_to_consume = 0;
|
1099 |
+
|
1100 |
+
// Get pointers to pointers so we can treat the raw pointer array as an
|
1101 |
+
// iterator for standard library algorithms. This isn't used yet but can be
|
1102 |
+
// used to template this function to work on iterators over strings or
|
1103 |
+
// C-strings.
|
1104 |
+
const char** arg_i = argv + 1;
|
1105 |
+
const char** arg_end = argv + argc;
|
1106 |
+
|
1107 |
+
while (arg_i != arg_end) {
|
1108 |
+
auto arg_i_cstr = *arg_i;
|
1109 |
+
auto arg_i_len = std::strlen(arg_i_cstr);
|
1110 |
+
|
1111 |
+
// Some behavior to note: if the previous option is expecting an argument
|
1112 |
+
// then the next entry will be treated as a positional argument even if
|
1113 |
+
// it looks like a flag.
|
1114 |
+
bool treat_as_positional_argument = (
|
1115 |
+
ignore_flags
|
1116 |
+
|| num_option_args_to_consume > 0
|
1117 |
+
|| !cmd_line_arg_is_option_flag(arg_i_cstr)
|
1118 |
+
);
|
1119 |
+
if (treat_as_positional_argument) {
|
1120 |
+
|
1121 |
+
// If last option is expecting some specific positive number of
|
1122 |
+
// arguments then give this argument to that option, *regardless of
|
1123 |
+
// whether or not the argument looks like a flag or is the special "--"
|
1124 |
+
// argument*.
|
1125 |
+
if (num_option_args_to_consume > 0) {
|
1126 |
+
last_option_expecting_args->arg = arg_i_cstr;
|
1127 |
+
--num_option_args_to_consume;
|
1128 |
+
++arg_i;
|
1129 |
+
continue;
|
1130 |
+
}
|
1131 |
+
|
1132 |
+
// Now we check if this is just "--" which is a special argument that
|
1133 |
+
// causes all following arguments to be treated as non-options and is
|
1134 |
+
// itselve discarded.
|
1135 |
+
if (std::strncmp(arg_i_cstr, "--", 2) == 0 && arg_i_len == 2) {
|
1136 |
+
ignore_flags = true;
|
1137 |
+
++arg_i;
|
1138 |
+
continue;
|
1139 |
+
}
|
1140 |
+
|
1141 |
+
// If there are no expectations for option arguments then simply use
|
1142 |
+
// this argument as a positional argument.
|
1143 |
+
results.pos.push_back(arg_i_cstr);
|
1144 |
+
++arg_i;
|
1145 |
+
continue;
|
1146 |
+
}
|
1147 |
+
|
1148 |
+
// Reset the "expecting argument" state.
|
1149 |
+
last_flag_expecting_args = nullptr;
|
1150 |
+
last_option_expecting_args = nullptr;
|
1151 |
+
num_option_args_to_consume = 0;
|
1152 |
+
|
1153 |
+
// If we're at this point then we're definitely dealing with something
|
1154 |
+
// that is flag-like and has hyphen as the first character and has a
|
1155 |
+
// length of at least two characters. How we handle this potential flag
|
1156 |
+
// depends on whether or not it is a long-option so we check that first.
|
1157 |
+
bool is_long_flag = (arg_i_cstr[1] == '-');
|
1158 |
+
|
1159 |
+
if (is_long_flag) {
|
1160 |
+
|
1161 |
+
// Long flags have a complication: their arguments can be specified
|
1162 |
+
// using an '=' character right inside the argument. That means an
|
1163 |
+
// argument like "--output=foobar.txt" is actually an option with flag
|
1164 |
+
// "--output" and argument "foobar.txt". So we look for the first
|
1165 |
+
// instance of the '=' character and keep it in long_flag_arg. If
|
1166 |
+
// long_flag_arg is nullptr then we didn't find '='. We need the
|
1167 |
+
// flag_len to construct long_flag_str below.
|
1168 |
+
auto long_flag_arg = std::strchr(arg_i_cstr, '=');
|
1169 |
+
std::size_t flag_len = arg_i_len;
|
1170 |
+
if (long_flag_arg != nullptr) {
|
1171 |
+
flag_len = long_flag_arg - arg_i_cstr;
|
1172 |
+
}
|
1173 |
+
std::string long_flag_str(arg_i_cstr, flag_len);
|
1174 |
+
|
1175 |
+
if (!map.known_long_flag(long_flag_str)) {
|
1176 |
+
std::ostringstream msg;
|
1177 |
+
msg << "found unexpected flag: " << long_flag_str;
|
1178 |
+
throw unexpected_option_error(msg.str());
|
1179 |
+
}
|
1180 |
+
|
1181 |
+
const auto defn = map.get_definition_for_long_flag(long_flag_str);
|
1182 |
+
|
1183 |
+
if (long_flag_arg != nullptr && defn->num_args == 0) {
|
1184 |
+
std::ostringstream msg;
|
1185 |
+
msg << "found argument for option not expecting an argument: "
|
1186 |
+
<< arg_i_cstr;
|
1187 |
+
throw unexpected_argument_error(msg.str());
|
1188 |
+
}
|
1189 |
+
|
1190 |
+
// We've got a legitimate, known long flag option so we add an option
|
1191 |
+
// result. This option result initially has an arg of nullptr, but that
|
1192 |
+
// might change in the following block.
|
1193 |
+
auto& opt_results = results.options[defn->name];
|
1194 |
+
option_result opt_result {nullptr};
|
1195 |
+
opt_results.all.push_back(std::move(opt_result));
|
1196 |
+
|
1197 |
+
if (defn->requires_arguments()) {
|
1198 |
+
bool there_is_an_equal_delimited_arg = (long_flag_arg != nullptr);
|
1199 |
+
if (there_is_an_equal_delimited_arg) {
|
1200 |
+
// long_flag_arg would be "=foo" in the "--output=foo" case so we
|
1201 |
+
// increment by 1 to get rid of the equal sign.
|
1202 |
+
opt_results.all.back().arg = long_flag_arg + 1;
|
1203 |
+
} else {
|
1204 |
+
last_flag_expecting_args = arg_i_cstr;
|
1205 |
+
last_option_expecting_args = &(opt_results.all.back());
|
1206 |
+
num_option_args_to_consume = defn->num_args;
|
1207 |
+
}
|
1208 |
+
}
|
1209 |
+
|
1210 |
+
++arg_i;
|
1211 |
+
continue;
|
1212 |
+
}
|
1213 |
+
|
1214 |
+
// If we've made it here then we're looking at either a short flag or a
|
1215 |
+
// group of short flags. Short flags can be grouped together so long as
|
1216 |
+
// they don't require any arguments unless the option that does is the
|
1217 |
+
// last in the group ("-o x -v" is okay, "-vo x" is okay, "-ov x" is
|
1218 |
+
// not). So starting after the dash we're going to process each character
|
1219 |
+
// as if it were a separate flag. Note "sf_idx" stands for "short flag
|
1220 |
+
// index".
|
1221 |
+
for (std::size_t sf_idx = 1; sf_idx < arg_i_len; ++sf_idx) {
|
1222 |
+
const auto short_flag = arg_i_cstr[sf_idx];
|
1223 |
+
|
1224 |
+
if (!std::isalnum(short_flag)) {
|
1225 |
+
std::ostringstream msg;
|
1226 |
+
msg << "found non-alphanumeric character '" << arg_i_cstr[sf_idx]
|
1227 |
+
<< "' in flag group '" << arg_i_cstr << "'";
|
1228 |
+
throw std::domain_error(msg.str());
|
1229 |
+
}
|
1230 |
+
|
1231 |
+
if (!map.known_short_flag(short_flag)) {
|
1232 |
+
std::ostringstream msg;
|
1233 |
+
msg << "found unexpected flag '" << arg_i_cstr[sf_idx]
|
1234 |
+
<< "' in flag group '" << arg_i_cstr << "'";
|
1235 |
+
throw unexpected_option_error(msg.str());
|
1236 |
+
}
|
1237 |
+
|
1238 |
+
auto defn = map.get_definition_for_short_flag(short_flag);
|
1239 |
+
auto& opt_results = results.options[defn->name];
|
1240 |
+
|
1241 |
+
// Create an option result with an empty argument (for now) and add it
|
1242 |
+
// to this option's results.
|
1243 |
+
option_result opt_result {nullptr};
|
1244 |
+
opt_results.all.push_back(std::move(opt_result));
|
1245 |
+
|
1246 |
+
if (defn->requires_arguments()) {
|
1247 |
+
|
1248 |
+
// If this short flag's option requires an argument and we're the
|
1249 |
+
// last flag in the short flag group then just put the parser into
|
1250 |
+
// "expecting argument for last option" state and move onto the next
|
1251 |
+
// command line argument.
|
1252 |
+
bool is_last_short_flag_in_group = (sf_idx == arg_i_len - 1);
|
1253 |
+
if (is_last_short_flag_in_group) {
|
1254 |
+
last_flag_expecting_args = arg_i_cstr;
|
1255 |
+
last_option_expecting_args = &(opt_results.all.back());
|
1256 |
+
num_option_args_to_consume = defn->num_args;
|
1257 |
+
break;
|
1258 |
+
}
|
1259 |
+
|
1260 |
+
// If this short flag's option requires an argument and we're NOT the
|
1261 |
+
// last flag in the short flag group then we automatically consume
|
1262 |
+
// the rest of the short flag group as the argument for this flag.
|
1263 |
+
// This is how we get the POSIX behavior of being able to specify a
|
1264 |
+
// flag's arguments without a white space delimiter (e.g.
|
1265 |
+
// "-I/usr/local/include").
|
1266 |
+
opt_results.all.back().arg = arg_i_cstr + sf_idx + 1;
|
1267 |
+
break;
|
1268 |
+
}
|
1269 |
+
}
|
1270 |
+
|
1271 |
+
++arg_i;
|
1272 |
+
continue;
|
1273 |
+
}
|
1274 |
+
|
1275 |
+
// If we're done with all of the arguments but are still expecting
|
1276 |
+
// arguments for a previous option then we haven't satisfied that option.
|
1277 |
+
// This is an error.
|
1278 |
+
if (num_option_args_to_consume > 0) {
|
1279 |
+
std::ostringstream msg;
|
1280 |
+
msg << "last option \"" << last_flag_expecting_args
|
1281 |
+
<< "\" expects an argument but the parser ran out of command line "
|
1282 |
+
<< "arguments to parse";
|
1283 |
+
throw option_lacks_argument_error(msg.str());
|
1284 |
+
}
|
1285 |
+
|
1286 |
+
return results;
|
1287 |
+
}
|
1288 |
+
|
1289 |
+
|
1290 |
+
inline
|
1291 |
+
parser_results parser::parse(int argc, char** argv) const
|
1292 |
+
{
|
1293 |
+
return parse(argc, const_cast<const char**>(argv));
|
1294 |
+
}
|
1295 |
+
|
1296 |
+
|
1297 |
+
namespace convert {
|
1298 |
+
|
1299 |
+
|
1300 |
+
/**
|
1301 |
+
* @brief
|
1302 |
+
* Templated function for conversion to T using the @ref std::strtol()
|
1303 |
+
* function. This is used for anything long length or shorter (long, int,
|
1304 |
+
* short, char).
|
1305 |
+
*/
|
1306 |
+
template <typename T> inline
|
1307 |
+
T long_(const char* arg)
|
1308 |
+
{
|
1309 |
+
char* endptr = nullptr;
|
1310 |
+
errno = 0;
|
1311 |
+
T ret = static_cast<T>(std::strtol(arg, &endptr, 0));
|
1312 |
+
if (endptr == arg) {
|
1313 |
+
std::ostringstream msg;
|
1314 |
+
msg << "unable to convert argument to integer: \"" << arg << "\"";
|
1315 |
+
throw std::invalid_argument(msg.str());
|
1316 |
+
}
|
1317 |
+
if (errno == ERANGE) {
|
1318 |
+
throw std::out_of_range("argument numeric value out of range");
|
1319 |
+
}
|
1320 |
+
return ret;
|
1321 |
+
}
|
1322 |
+
|
1323 |
+
|
1324 |
+
/**
|
1325 |
+
* @brief
|
1326 |
+
* Templated function for conversion to T using the @ref std::strtoll()
|
1327 |
+
* function. This is used for anything long long length or shorter (long
|
1328 |
+
* long).
|
1329 |
+
*/
|
1330 |
+
template <typename T> inline
|
1331 |
+
T long_long_(const char* arg)
|
1332 |
+
{
|
1333 |
+
char* endptr = nullptr;
|
1334 |
+
errno = 0;
|
1335 |
+
T ret = static_cast<T>(std::strtoll(arg, &endptr, 0));
|
1336 |
+
if (endptr == arg) {
|
1337 |
+
std::ostringstream msg;
|
1338 |
+
msg << "unable to convert argument to integer: \"" << arg << "\"";
|
1339 |
+
throw std::invalid_argument(msg.str());
|
1340 |
+
}
|
1341 |
+
if (errno == ERANGE) {
|
1342 |
+
throw std::out_of_range("argument numeric value out of range");
|
1343 |
+
}
|
1344 |
+
return ret;
|
1345 |
+
}
|
1346 |
+
|
1347 |
+
|
1348 |
+
#define DEFINE_CONVERSION_FROM_LONG_(TYPE) \
|
1349 |
+
template <> inline \
|
1350 |
+
TYPE arg(const char* arg) \
|
1351 |
+
{ \
|
1352 |
+
return long_<TYPE>(arg); \
|
1353 |
+
}
|
1354 |
+
|
1355 |
+
DEFINE_CONVERSION_FROM_LONG_(char)
|
1356 |
+
DEFINE_CONVERSION_FROM_LONG_(unsigned char)
|
1357 |
+
DEFINE_CONVERSION_FROM_LONG_(signed char)
|
1358 |
+
DEFINE_CONVERSION_FROM_LONG_(short)
|
1359 |
+
DEFINE_CONVERSION_FROM_LONG_(unsigned short)
|
1360 |
+
DEFINE_CONVERSION_FROM_LONG_(int)
|
1361 |
+
DEFINE_CONVERSION_FROM_LONG_(unsigned int)
|
1362 |
+
DEFINE_CONVERSION_FROM_LONG_(long)
|
1363 |
+
DEFINE_CONVERSION_FROM_LONG_(unsigned long)
|
1364 |
+
|
1365 |
+
#undef DEFINE_CONVERSION_FROM_LONG_
|
1366 |
+
|
1367 |
+
|
1368 |
+
#define DEFINE_CONVERSION_FROM_LONG_LONG_(TYPE) \
|
1369 |
+
template <> inline \
|
1370 |
+
TYPE arg(const char* arg) \
|
1371 |
+
{ \
|
1372 |
+
return long_long_<TYPE>(arg); \
|
1373 |
+
}
|
1374 |
+
|
1375 |
+
DEFINE_CONVERSION_FROM_LONG_LONG_(long long)
|
1376 |
+
DEFINE_CONVERSION_FROM_LONG_LONG_(unsigned long long)
|
1377 |
+
|
1378 |
+
#undef DEFINE_CONVERSION_FROM_LONG_LONG_
|
1379 |
+
|
1380 |
+
|
1381 |
+
template <> inline
|
1382 |
+
bool arg(const char* arg)
|
1383 |
+
{
|
1384 |
+
return argagg::convert::arg<int>(arg) != 0;
|
1385 |
+
}
|
1386 |
+
|
1387 |
+
|
1388 |
+
template <> inline
|
1389 |
+
float arg(const char* arg)
|
1390 |
+
{
|
1391 |
+
char* endptr = nullptr;
|
1392 |
+
errno = 0;
|
1393 |
+
float ret = std::strtof(arg, &endptr);
|
1394 |
+
if (endptr == arg) {
|
1395 |
+
std::ostringstream msg;
|
1396 |
+
msg << "unable to convert argument to integer: \"" << arg << "\"";
|
1397 |
+
throw std::invalid_argument(msg.str());
|
1398 |
+
}
|
1399 |
+
if (errno == ERANGE) {
|
1400 |
+
throw std::out_of_range("argument numeric value out of range");
|
1401 |
+
}
|
1402 |
+
return ret;
|
1403 |
+
}
|
1404 |
+
|
1405 |
+
|
1406 |
+
template <> inline
|
1407 |
+
double arg(const char* arg)
|
1408 |
+
{
|
1409 |
+
char* endptr = nullptr;
|
1410 |
+
errno = 0;
|
1411 |
+
double ret = std::strtod(arg, &endptr);
|
1412 |
+
if (endptr == arg) {
|
1413 |
+
std::ostringstream msg;
|
1414 |
+
msg << "unable to convert argument to integer: \"" << arg << "\"";
|
1415 |
+
throw std::invalid_argument(msg.str());
|
1416 |
+
}
|
1417 |
+
if (errno == ERANGE) {
|
1418 |
+
throw std::out_of_range("argument numeric value out of range");
|
1419 |
+
}
|
1420 |
+
return ret;
|
1421 |
+
}
|
1422 |
+
|
1423 |
+
|
1424 |
+
template <> inline
|
1425 |
+
const char* arg(const char* arg)
|
1426 |
+
{
|
1427 |
+
return arg;
|
1428 |
+
}
|
1429 |
+
|
1430 |
+
|
1431 |
+
template <> inline
|
1432 |
+
std::string arg(const char* arg)
|
1433 |
+
{
|
1434 |
+
return std::string(arg);
|
1435 |
+
}
|
1436 |
+
|
1437 |
+
}
|
1438 |
+
|
1439 |
+
|
1440 |
+
inline
|
1441 |
+
fmt_ostream::fmt_ostream(std::ostream& output)
|
1442 |
+
: std::ostringstream(), output(output)
|
1443 |
+
{
|
1444 |
+
}
|
1445 |
+
|
1446 |
+
|
1447 |
+
inline
|
1448 |
+
fmt_ostream::~fmt_ostream()
|
1449 |
+
{
|
1450 |
+
output << fmt_string(this->str());
|
1451 |
+
}
|
1452 |
+
|
1453 |
+
|
1454 |
+
#ifdef __unix__
|
1455 |
+
|
1456 |
+
|
1457 |
+
inline
|
1458 |
+
std::string fmt_string(const std::string& s)
|
1459 |
+
{
|
1460 |
+
constexpr int read_end = 0;
|
1461 |
+
constexpr int write_end = 1;
|
1462 |
+
|
1463 |
+
// TODO (vnguyen): This function overall needs to handle possible error
|
1464 |
+
// returns from the various syscalls.
|
1465 |
+
|
1466 |
+
int read_pipe[2];
|
1467 |
+
int write_pipe[2];
|
1468 |
+
if (pipe(read_pipe) == -1) {
|
1469 |
+
return s;
|
1470 |
+
}
|
1471 |
+
if (pipe(write_pipe) == -1) {
|
1472 |
+
return s;
|
1473 |
+
}
|
1474 |
+
|
1475 |
+
auto parent_pid = fork();
|
1476 |
+
bool is_fmt_proc = (parent_pid == 0);
|
1477 |
+
if (is_fmt_proc) {
|
1478 |
+
dup2(write_pipe[read_end], STDIN_FILENO);
|
1479 |
+
dup2(read_pipe[write_end], STDOUT_FILENO);
|
1480 |
+
close(write_pipe[read_end]);
|
1481 |
+
close(write_pipe[write_end]);
|
1482 |
+
close(read_pipe[read_end]);
|
1483 |
+
close(read_pipe[write_end]);
|
1484 |
+
const char* argv[] = {"fmt", NULL};
|
1485 |
+
execvp(const_cast<char*>(argv[0]), const_cast<char**>(argv));
|
1486 |
+
}
|
1487 |
+
|
1488 |
+
close(write_pipe[read_end]);
|
1489 |
+
close(read_pipe[write_end]);
|
1490 |
+
auto fmt_write_fd = write_pipe[write_end];
|
1491 |
+
auto write_result = write(fmt_write_fd, s.c_str(), s.length());
|
1492 |
+
if (write_result != static_cast<ssize_t>(s.length())) {
|
1493 |
+
return s;
|
1494 |
+
}
|
1495 |
+
close(fmt_write_fd);
|
1496 |
+
|
1497 |
+
auto fmt_read_fd = read_pipe[read_end];
|
1498 |
+
std::ostringstream os;
|
1499 |
+
char buf[64];
|
1500 |
+
while (true) {
|
1501 |
+
auto read_count = read(
|
1502 |
+
fmt_read_fd, reinterpret_cast<void*>(buf), sizeof(buf));
|
1503 |
+
if (read_count <= 0) {
|
1504 |
+
break;
|
1505 |
+
}
|
1506 |
+
os.write(buf, static_cast<std::streamsize>(read_count));
|
1507 |
+
}
|
1508 |
+
close(fmt_read_fd);
|
1509 |
+
|
1510 |
+
return os.str();
|
1511 |
+
}
|
1512 |
+
|
1513 |
+
|
1514 |
+
#else // #ifdef __unix__
|
1515 |
+
|
1516 |
+
|
1517 |
+
inline
|
1518 |
+
std::string fmt_string(const std::string& s)
|
1519 |
+
{
|
1520 |
+
return s;
|
1521 |
+
}
|
1522 |
+
|
1523 |
+
|
1524 |
+
#endif // #ifdef __unix__
|
1525 |
+
|
1526 |
+
|
1527 |
+
} // namespace argagg
|
1528 |
+
|
1529 |
+
|
1530 |
+
inline
|
1531 |
+
std::ostream& operator << (std::ostream& os, const argagg::parser& x)
|
1532 |
+
{
|
1533 |
+
for (auto& definition : x.definitions) {
|
1534 |
+
os << " ";
|
1535 |
+
for (auto& flag : definition.flags) {
|
1536 |
+
os << flag;
|
1537 |
+
if (flag != definition.flags.back()) {
|
1538 |
+
os << ", ";
|
1539 |
+
}
|
1540 |
+
}
|
1541 |
+
os << std::endl;
|
1542 |
+
os << " " << definition.help << std::endl;
|
1543 |
+
}
|
1544 |
+
return os;
|
1545 |
+
}
|
1546 |
+
|
1547 |
+
|
1548 |
+
#endif // ARGAGG_ARGAGG_ARGAGG_HPP
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/assert.h
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Hauke Strasdat, Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <pangolin/platform.h>
|
31 |
+
#include <pangolin/utils/format_string.h>
|
32 |
+
#include <iostream>
|
33 |
+
|
34 |
+
#ifdef __GNUC__
|
35 |
+
# define PANGO_FUNCTION __PRETTY_FUNCTION__
|
36 |
+
#elif (_MSC_VER >= 1310)
|
37 |
+
# define PANGO_FUNCTION __FUNCTION__
|
38 |
+
#else
|
39 |
+
# define PANGO_FUNCTION "unknown"
|
40 |
+
#endif
|
41 |
+
|
42 |
+
namespace pangolin {
|
43 |
+
|
44 |
+
template <typename... Args> PANGO_HOST_DEVICE
|
45 |
+
void abort(const char* function, const char* file, int line, Args&&... args)
|
46 |
+
{
|
47 |
+
std::fprintf(stderr, "pangolin::abort() in function '%s', file '%s', line %d.\n", function, file, line);
|
48 |
+
#ifndef __CUDACC__
|
49 |
+
std::cerr << FormatString(std::forward<Args>(args)...) << std::endl;
|
50 |
+
std::abort();
|
51 |
+
#endif
|
52 |
+
}
|
53 |
+
|
54 |
+
template <typename... Args> PANGO_HOST_DEVICE
|
55 |
+
void warning(const char* expr, const char* function, const char* file, int line, Args&&... args)
|
56 |
+
{
|
57 |
+
std::fprintf(stderr, "pangolin::warning() in function '%s', file '%s', line %d:\n\t%s\n", function, file, line, expr);
|
58 |
+
#ifndef __CUDACC__
|
59 |
+
std::cerr << FormatString(std::forward<Args>(args)...) << std::endl;
|
60 |
+
#endif
|
61 |
+
}
|
62 |
+
|
63 |
+
}
|
64 |
+
|
65 |
+
// Always check, even in debug
|
66 |
+
#define PANGO_ENSURE(expr, ...) ((expr) ? ((void)0) : pangolin::abort(PANGO_FUNCTION, __FILE__, __LINE__, ##__VA_ARGS__))
|
67 |
+
|
68 |
+
// May be disabled for optimisation
|
69 |
+
#define PANGO_ASSERT(expr, ...) ((expr) ? ((void)0) : pangolin::abort(PANGO_FUNCTION, __FILE__, __LINE__, ##__VA_ARGS__))
|
70 |
+
|
71 |
+
#define PANGO_WARNING(expr, ...) ((expr) ? ((void)0) : pangolin::warning(#expr, PANGO_FUNCTION, __FILE__, __LINE__, ##__VA_ARGS__))
|
72 |
+
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/avx_math.h
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2014 Hauke Strasdat, Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
#ifdef __AVX2__
|
30 |
+
#include <immintrin.h>
|
31 |
+
#endif
|
32 |
+
|
33 |
+
namespace pangolin
|
34 |
+
{
|
35 |
+
#ifdef __AVX2__
|
36 |
+
__m256 pow256_ps(__m256 x, __m256 y);
|
37 |
+
#endif
|
38 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/bitmask.h
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Modified version of https://gpfault.net/posts/typesafe-bitmasks.txt.html (public domain)
|
2 |
+
|
3 |
+
#include <type_traits>
|
4 |
+
|
5 |
+
namespace pangolin {
|
6 |
+
|
7 |
+
template <class option_type,
|
8 |
+
bool already_pow2,
|
9 |
+
// The line below ensures that bitmask can only be used with enums.
|
10 |
+
typename = typename std::enable_if<std::is_enum<option_type>::value>::type>
|
11 |
+
class bitmask {
|
12 |
+
// The type we'll use for storing the value of our bitmask should be the same
|
13 |
+
// as the enum's underlying type.
|
14 |
+
using underlying_type = typename std::underlying_type<option_type>::type;
|
15 |
+
|
16 |
+
// This method helps us avoid having to explicitly set enum values to powers
|
17 |
+
// of two.
|
18 |
+
static constexpr underlying_type mask_value(option_type o) {
|
19 |
+
|
20 |
+
return already_pow2 ? o : 1 << static_cast<underlying_type>(o);
|
21 |
+
}
|
22 |
+
|
23 |
+
// Private ctor to be used internally.
|
24 |
+
explicit constexpr bitmask(underlying_type o) : mask_(o) {}
|
25 |
+
|
26 |
+
public:
|
27 |
+
// Default ctor creates a bitmask with no options selected.
|
28 |
+
constexpr bitmask() : mask_(0) {}
|
29 |
+
|
30 |
+
// Creates a bitmask with just one bit set.
|
31 |
+
// This ctor is intentionally non-explicit, to allow for stuff like:
|
32 |
+
// FunctionExpectingBitmask(Options::Opt1)
|
33 |
+
constexpr bitmask(option_type o) : mask_(mask_value(o)) {}
|
34 |
+
|
35 |
+
// Set the bit corresponding to the given option.
|
36 |
+
constexpr bitmask operator|(option_type t) {
|
37 |
+
return bitmask(mask_ | (mask_value(t)));
|
38 |
+
}
|
39 |
+
|
40 |
+
// Set the bit corresponding to the given option.
|
41 |
+
void operator|=(option_type t) {
|
42 |
+
mask_ |= mask_value(t);
|
43 |
+
}
|
44 |
+
|
45 |
+
// Get the value of the bit corresponding to the given option.
|
46 |
+
constexpr bool operator&(option_type t) {
|
47 |
+
return mask_ & mask_value(t);
|
48 |
+
}
|
49 |
+
|
50 |
+
// Set the bit corresponding to the given option.
|
51 |
+
void operator&=(option_type t) {
|
52 |
+
mask_ &= mask_value(t);
|
53 |
+
}
|
54 |
+
|
55 |
+
underlying_type mask()
|
56 |
+
{
|
57 |
+
return mask_;
|
58 |
+
}
|
59 |
+
|
60 |
+
void set(option_type t, bool on)
|
61 |
+
{
|
62 |
+
if(on) {
|
63 |
+
mask_ |= mask_value(t);
|
64 |
+
}else{
|
65 |
+
mask_ &= ~mask_value(t);
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
private:
|
70 |
+
underlying_type mask_ = 0;
|
71 |
+
};
|
72 |
+
|
73 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/compontent_cast.h
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <pangolin/platform.h>
|
4 |
+
|
5 |
+
#ifdef HAVE_EIGEN
|
6 |
+
# include <Eigen/Core>
|
7 |
+
#endif
|
8 |
+
|
9 |
+
namespace pangolin
|
10 |
+
{
|
11 |
+
|
12 |
+
// Scalar / Vector agnostic static_cast-like thing
|
13 |
+
//
|
14 |
+
// e.g. Promote float to double:
|
15 |
+
// ComponentCast<double,float>::cast(0.14f);
|
16 |
+
//
|
17 |
+
// e.g. Promote Eigen::Vector2f to Eigen::Vector2d:
|
18 |
+
// ComponentCast<Eigen::Vector2d,Eigen::Vector2f>::cast(Eigen::Vector2f(0.1,0.2);
|
19 |
+
|
20 |
+
template <typename To, typename From>
|
21 |
+
struct ComponentCast
|
22 |
+
{
|
23 |
+
PANGO_HOST_DEVICE
|
24 |
+
static To cast(const From& val)
|
25 |
+
{
|
26 |
+
return static_cast<To>(val);
|
27 |
+
}
|
28 |
+
};
|
29 |
+
|
30 |
+
#ifdef HAVE_EIGEN
|
31 |
+
template <typename To, typename FromDerived>
|
32 |
+
struct ComponentCast<To, Eigen::MatrixBase<FromDerived> >
|
33 |
+
{
|
34 |
+
PANGO_HOST_DEVICE
|
35 |
+
static To cast(const Eigen::MatrixBase<FromDerived>& val)
|
36 |
+
{
|
37 |
+
return val.template cast<typename To::Scalar>();
|
38 |
+
}
|
39 |
+
};
|
40 |
+
#endif
|
41 |
+
|
42 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/file_extension.h
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <pangolin/platform.h>
|
31 |
+
#include <string>
|
32 |
+
|
33 |
+
namespace pangolin
|
34 |
+
{
|
35 |
+
|
36 |
+
enum ImageFileType
|
37 |
+
{
|
38 |
+
ImageFileTypePpm,
|
39 |
+
ImageFileTypeTga,
|
40 |
+
ImageFileTypePng,
|
41 |
+
ImageFileTypeJpg,
|
42 |
+
ImageFileTypeTiff,
|
43 |
+
ImageFileTypeGif,
|
44 |
+
ImageFileTypeExr,
|
45 |
+
ImageFileTypeBmp,
|
46 |
+
ImageFileTypePango,
|
47 |
+
ImageFileTypePvn,
|
48 |
+
ImageFileTypeVrs,
|
49 |
+
ImageFileTypeZstd,
|
50 |
+
ImageFileTypeLz4,
|
51 |
+
ImageFileTypeP12b,
|
52 |
+
ImageFileTypePly,
|
53 |
+
ImageFileTypeObj,
|
54 |
+
ImageFileTypeArw,
|
55 |
+
ImageFileTypeUnknown
|
56 |
+
};
|
57 |
+
|
58 |
+
|
59 |
+
PANGOLIN_EXPORT
|
60 |
+
std::string ImageFileTypeToName(ImageFileType);
|
61 |
+
|
62 |
+
PANGOLIN_EXPORT
|
63 |
+
ImageFileType NameToImageFileType(const std::string&);
|
64 |
+
|
65 |
+
PANGOLIN_EXPORT
|
66 |
+
std::string FileLowercaseExtention(const std::string& filename);
|
67 |
+
|
68 |
+
PANGOLIN_EXPORT
|
69 |
+
ImageFileType FileTypeMagic(const unsigned char data[], size_t bytes);
|
70 |
+
|
71 |
+
PANGOLIN_EXPORT
|
72 |
+
ImageFileType FileTypeExtension(const std::string& ext);
|
73 |
+
|
74 |
+
PANGOLIN_EXPORT
|
75 |
+
ImageFileType FileType(const std::string& filename);
|
76 |
+
|
77 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/file_utils.h
ADDED
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2013 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <pangolin/platform.h>
|
31 |
+
|
32 |
+
#include <string>
|
33 |
+
#include <vector>
|
34 |
+
#include <algorithm>
|
35 |
+
|
36 |
+
namespace pangolin
|
37 |
+
{
|
38 |
+
|
39 |
+
PANGOLIN_EXPORT
|
40 |
+
std::vector<std::string>& Split(const std::string& s, char delim, std::vector<std::string>& elements);
|
41 |
+
|
42 |
+
PANGOLIN_EXPORT
|
43 |
+
std::vector<std::string> Split(const std::string &s, char delim);
|
44 |
+
|
45 |
+
PANGOLIN_EXPORT
|
46 |
+
std::vector<std::string> Expand(const std::string &s, char open='[', char close=']', char delim=',');
|
47 |
+
|
48 |
+
PANGOLIN_EXPORT
|
49 |
+
std::string SanitizePath(const std::string& path);
|
50 |
+
|
51 |
+
PANGOLIN_EXPORT
|
52 |
+
std::string PathParent(const std::string& path, int levels = 1);
|
53 |
+
|
54 |
+
PANGOLIN_EXPORT
|
55 |
+
bool FileExists(const std::string& filename);
|
56 |
+
|
57 |
+
PANGOLIN_EXPORT
|
58 |
+
std::string FindPath(const std::string& child_path, const std::string& signature_path);
|
59 |
+
|
60 |
+
PANGOLIN_EXPORT
|
61 |
+
std::string PathExpand(const std::string& sPath);
|
62 |
+
|
63 |
+
PANGOLIN_EXPORT
|
64 |
+
bool MatchesWildcard(const std::string& str, const std::string& wildcard);
|
65 |
+
|
66 |
+
PANGOLIN_EXPORT
|
67 |
+
std::string GetFileContents(const std::string& filename);
|
68 |
+
|
69 |
+
|
70 |
+
enum class SortMethod {
|
71 |
+
STANDARD,
|
72 |
+
NATURAL
|
73 |
+
};
|
74 |
+
|
75 |
+
// Fill 'file_vec' with the files that match the glob-like 'wildcard_file_path'
|
76 |
+
// ? can be used to match any single charector
|
77 |
+
// * can be used to match any sequence of charectors in a directory
|
78 |
+
// ** can be used to match any directories across any number of levels
|
79 |
+
// e.g. FilesMatchingWildcard("~/*/code/*.h", vec);
|
80 |
+
// e.g. FilesMatchingWildcard("~/**/*.png", vec);
|
81 |
+
// sort the file_vec according to the specified sorting method.
|
82 |
+
PANGOLIN_EXPORT
|
83 |
+
bool FilesMatchingWildcard(const std::string& wildcard_file_path, std::vector<std::string>& file_vec, SortMethod sort_method = SortMethod::STANDARD);
|
84 |
+
|
85 |
+
PANGOLIN_EXPORT
|
86 |
+
std::string MakeUniqueFilename(const std::string& filename);
|
87 |
+
|
88 |
+
PANGOLIN_EXPORT
|
89 |
+
bool IsPipe(const std::string& file);
|
90 |
+
|
91 |
+
PANGOLIN_EXPORT
|
92 |
+
bool IsPipe(int fd);
|
93 |
+
|
94 |
+
PANGOLIN_EXPORT
|
95 |
+
int WritablePipeFileDescriptor(const std::string& file);
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Open the file for reading. Note that it is opened with O_NONBLOCK. The pipe
|
99 |
+
* open is done in two stages so that the producer knows a reader is waiting
|
100 |
+
* (but not blocked). The reader then checks PipeHasDataToRead() until it
|
101 |
+
* returns true. The file can then be opened. Note that the file descriptor
|
102 |
+
* should be closed after the read stream has been created so that the write
|
103 |
+
* side of the pipe does not get signaled.
|
104 |
+
*/
|
105 |
+
PANGOLIN_EXPORT
|
106 |
+
int ReadablePipeFileDescriptor(const std::string& file);
|
107 |
+
|
108 |
+
PANGOLIN_EXPORT
|
109 |
+
bool PipeHasDataToRead(int fd);
|
110 |
+
|
111 |
+
PANGOLIN_EXPORT
|
112 |
+
void FlushPipe(const std::string& file);
|
113 |
+
|
114 |
+
// TODO: Tidy these inlines up / move them
|
115 |
+
|
116 |
+
inline bool StartsWith(const std::string& str, const std::string& prefix)
|
117 |
+
{
|
118 |
+
return !str.compare(0, prefix.size(), prefix);
|
119 |
+
}
|
120 |
+
|
121 |
+
inline bool EndsWith(const std::string& str, const std::string& prefix)
|
122 |
+
{
|
123 |
+
return !str.compare(str.size() - prefix.size(), prefix.size(), prefix);
|
124 |
+
}
|
125 |
+
|
126 |
+
inline std::string Trim(const std::string& str, const std::string& delimiters = " \f\n\r\t\v" )
|
127 |
+
{
|
128 |
+
const size_t f = str.find_first_not_of( delimiters );
|
129 |
+
return f == std::string::npos ?
|
130 |
+
"" :
|
131 |
+
str.substr( f, str.find_last_not_of( delimiters ) + 1 );
|
132 |
+
}
|
133 |
+
|
134 |
+
inline void ToUpper( std::string& str )
|
135 |
+
{
|
136 |
+
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
|
137 |
+
}
|
138 |
+
|
139 |
+
inline void ToLower( std::string& str )
|
140 |
+
{
|
141 |
+
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
|
142 |
+
}
|
143 |
+
|
144 |
+
inline std::string ToUpperCopy( const std::string& str )
|
145 |
+
{
|
146 |
+
std::string out;
|
147 |
+
out.resize(str.size());
|
148 |
+
std::transform(str.begin(), str.end(), out.begin(), ::toupper);
|
149 |
+
return out;
|
150 |
+
}
|
151 |
+
|
152 |
+
inline std::string ToLowerCopy( const std::string& str )
|
153 |
+
{
|
154 |
+
std::string out;
|
155 |
+
out.resize(str.size());
|
156 |
+
std::transform(str.begin(), str.end(), out.begin(), ::tolower);
|
157 |
+
return out;
|
158 |
+
}
|
159 |
+
|
160 |
+
|
161 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/fix_size_buffer_queue.h
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <condition_variable>
|
31 |
+
#include <list>
|
32 |
+
#include <mutex>
|
33 |
+
#include <thread>
|
34 |
+
|
35 |
+
namespace pangolin
|
36 |
+
{
|
37 |
+
|
38 |
+
template<typename BufPType>
|
39 |
+
class FixSizeBuffersQueue
|
40 |
+
{
|
41 |
+
|
42 |
+
public:
|
43 |
+
FixSizeBuffersQueue() {}
|
44 |
+
|
45 |
+
~FixSizeBuffersQueue() {
|
46 |
+
}
|
47 |
+
|
48 |
+
BufPType getNewest() {
|
49 |
+
std::lock_guard<std::mutex> vlock(vMtx);
|
50 |
+
std::lock_guard<std::mutex> elock(eMtx);
|
51 |
+
if(validBuffers.size() == 0) {
|
52 |
+
// Empty queue.
|
53 |
+
return 0;
|
54 |
+
} else {
|
55 |
+
// Requeue all but newest buffers.
|
56 |
+
while(validBuffers.size() > 1) {
|
57 |
+
emptyBuffers.push_back(std::move(validBuffers.front()));
|
58 |
+
validBuffers.pop_front();
|
59 |
+
}
|
60 |
+
// Return newest buffer.
|
61 |
+
BufPType bp = std::move(validBuffers.front());
|
62 |
+
validBuffers.pop_front();
|
63 |
+
return bp;
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
BufPType getNext() {
|
68 |
+
std::lock_guard<std::mutex> vlock(vMtx);
|
69 |
+
if(validBuffers.size() == 0) {
|
70 |
+
// Empty queue.
|
71 |
+
return 0;
|
72 |
+
} else {
|
73 |
+
// Return oldest buffer.
|
74 |
+
BufPType bp = std::move(validBuffers.front());
|
75 |
+
validBuffers.pop_front();
|
76 |
+
return bp;
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
BufPType getFreeBuffer() {
|
81 |
+
std::lock_guard<std::mutex> vlock(vMtx);
|
82 |
+
std::lock_guard<std::mutex> elock(eMtx);
|
83 |
+
if(emptyBuffers.size() > 0) {
|
84 |
+
// Simply get a free buffer from the free buffers list.
|
85 |
+
BufPType bp = std::move(emptyBuffers.front());
|
86 |
+
emptyBuffers.pop_front();
|
87 |
+
return bp;
|
88 |
+
} else {
|
89 |
+
if(validBuffers.size() == 0) {
|
90 |
+
// Queue not yet initialized.
|
91 |
+
throw std::runtime_error("Queue not yet initialised.");
|
92 |
+
} else {
|
93 |
+
std::cerr << "Out of free buffers." << std::endl;
|
94 |
+
// No free buffers return oldest among the valid buffers.
|
95 |
+
BufPType bp = std::move(validBuffers.front());
|
96 |
+
validBuffers.pop_front();
|
97 |
+
return bp;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
void addValidBuffer(BufPType bp) {
|
103 |
+
// Add buffer to valid buffers queue.
|
104 |
+
std::lock_guard<std::mutex> vlock(vMtx);
|
105 |
+
validBuffers.push_back(std::move(bp));
|
106 |
+
}
|
107 |
+
|
108 |
+
void returnOrAddUsedBuffer(BufPType bp) {
|
109 |
+
// Add buffer back to empty buffers queue.
|
110 |
+
std::lock_guard<std::mutex> elock(eMtx);
|
111 |
+
emptyBuffers.push_back(std::move(bp));
|
112 |
+
}
|
113 |
+
|
114 |
+
size_t AvailableFrames() const {
|
115 |
+
std::lock_guard<std::mutex> vlock(vMtx);
|
116 |
+
return validBuffers.size();
|
117 |
+
}
|
118 |
+
|
119 |
+
size_t EmptyBuffers() const {
|
120 |
+
std::lock_guard<std::mutex> elock(eMtx);
|
121 |
+
return emptyBuffers.size();
|
122 |
+
}
|
123 |
+
|
124 |
+
bool DropNFrames(size_t n) {
|
125 |
+
std::lock_guard<std::mutex> vlock(vMtx);
|
126 |
+
if(validBuffers.size() < n) {
|
127 |
+
return false;
|
128 |
+
} else {
|
129 |
+
std::lock_guard<std::mutex> elock(eMtx);
|
130 |
+
// Requeue all but newest buffers.
|
131 |
+
for(unsigned int i=0; i<n; ++i) {
|
132 |
+
emptyBuffers.push_back(std::move(validBuffers.front()));
|
133 |
+
validBuffers.pop_front();
|
134 |
+
}
|
135 |
+
return true;
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
// unsigned int BufferSizeBytes(){
|
140 |
+
// return bufferSizeBytes;
|
141 |
+
// }
|
142 |
+
|
143 |
+
private:
|
144 |
+
std::list<BufPType> validBuffers;
|
145 |
+
std::list<BufPType> emptyBuffers;
|
146 |
+
mutable std::mutex vMtx;
|
147 |
+
mutable std::mutex eMtx;
|
148 |
+
// unsigned int maxNumBuffers;
|
149 |
+
// unsigned int bufferSizeBytes;
|
150 |
+
};
|
151 |
+
|
152 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/format_string.h
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2014 Hauke Strasdat, Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <sstream>
|
31 |
+
|
32 |
+
namespace pangolin {
|
33 |
+
namespace details {
|
34 |
+
|
35 |
+
// Following: http://stackoverflow.com/a/22759544
|
36 |
+
template <typename T>
|
37 |
+
class IsStreamable {
|
38 |
+
private:
|
39 |
+
template <typename TT>
|
40 |
+
static auto test(int) -> decltype( (std::declval<std::stringstream&>() << std::declval<TT>(), std::true_type()) );
|
41 |
+
|
42 |
+
template <typename>
|
43 |
+
static auto test(...) -> std::false_type;
|
44 |
+
|
45 |
+
public:
|
46 |
+
static const bool value = decltype(test<T>(0))::value;
|
47 |
+
};
|
48 |
+
|
49 |
+
inline void FormatStream(std::stringstream& stream, const char* text)
|
50 |
+
{
|
51 |
+
stream << text;
|
52 |
+
}
|
53 |
+
|
54 |
+
// Following: http://en.cppreference.com/w/cpp/language/parameter_pack
|
55 |
+
template <typename T, typename... Args>
|
56 |
+
void FormatStream(std::stringstream& stream, const char* text, T arg, Args... args)
|
57 |
+
{
|
58 |
+
static_assert(IsStreamable<T>::value,
|
59 |
+
"One of the args has not an ostream overload!");
|
60 |
+
for (; *text != '\0'; ++text) {
|
61 |
+
if (*text == '%') {
|
62 |
+
stream << arg;
|
63 |
+
FormatStream(stream, text + 1, args...);
|
64 |
+
return;
|
65 |
+
}
|
66 |
+
stream << *text;
|
67 |
+
}
|
68 |
+
stream << "\nFormat-Warning: There are " << sizeof...(Args) + 1
|
69 |
+
<< " args unused.";
|
70 |
+
}
|
71 |
+
|
72 |
+
} // namespace details
|
73 |
+
|
74 |
+
template <typename... Args>
|
75 |
+
std::string FormatString(const char* text, Args... args)
|
76 |
+
{
|
77 |
+
std::stringstream stream;
|
78 |
+
details::FormatStream(stream, text, args...);
|
79 |
+
return stream.str();
|
80 |
+
}
|
81 |
+
|
82 |
+
inline std::string FormatString()
|
83 |
+
{
|
84 |
+
return std::string();
|
85 |
+
}
|
86 |
+
|
87 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/is_streamable.h
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <type_traits>
|
4 |
+
#include <utility>
|
5 |
+
#include <iostream>
|
6 |
+
#include <sstream>
|
7 |
+
|
8 |
+
namespace pangolin {
|
9 |
+
|
10 |
+
// Provide SFINAE test for if type T is streamable into S
|
11 |
+
// Example usage:
|
12 |
+
// template <typename S>
|
13 |
+
// typename std::enable_if<is_streamable<S>::value, S>::type
|
14 |
+
// Example(const S& src) noexcept
|
15 |
+
// {
|
16 |
+
// std::cout << src;
|
17 |
+
// return src;
|
18 |
+
// }
|
19 |
+
template<typename T, typename S = std::ostream>
|
20 |
+
class is_streamable
|
21 |
+
{
|
22 |
+
template<typename SS, typename TT>
|
23 |
+
static auto test(int)
|
24 |
+
-> decltype( std::declval<SS&>() << std::declval<TT>(), std::true_type() );
|
25 |
+
|
26 |
+
template<typename, typename>
|
27 |
+
static auto test(...) -> std::false_type;
|
28 |
+
|
29 |
+
public:
|
30 |
+
static const bool value = decltype(test<S,T>(0))::value;
|
31 |
+
};
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/log.h
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
// TODO: Something a bit more useful here, probably using format_string.h
|
29 |
+
|
30 |
+
#pragma once
|
31 |
+
|
32 |
+
#ifndef _ANDROID_
|
33 |
+
# include <cstdio>
|
34 |
+
# define pango_print_debug(...) printf(__VA_ARGS__)
|
35 |
+
# define pango_print_info(...) printf(__VA_ARGS__)
|
36 |
+
# define pango_print_error(...) fprintf(stderr, __VA_ARGS__)
|
37 |
+
# define pango_print_warn(...) fprintf(stderr, __VA_ARGS__)
|
38 |
+
#else
|
39 |
+
# include <android/log.h>
|
40 |
+
# define pango_print_debug(...) __android_log_print(ANDROID_LOG_DEBUG, "pango", __VA_ARGS__ );
|
41 |
+
# define pango_print_info(...) __android_log_print(ANDROID_LOG_INFO, "pango", __VA_ARGS__ );
|
42 |
+
# define pango_print_error(...) __android_log_print(ANDROID_LOG_ERROR, "pango", __VA_ARGS__ );
|
43 |
+
# define pango_print_warn(...) __android_log_print(ANDROID_LOG_ERROR, "pango", __VA_ARGS__ );
|
44 |
+
#endif
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/memstreambuf.h
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <streambuf>
|
4 |
+
#include <vector>
|
5 |
+
|
6 |
+
namespace pangolin {
|
7 |
+
|
8 |
+
// A simple streambuf wrapper around std::vector for memory buffer use
|
9 |
+
struct memstreambuf : public std::streambuf
|
10 |
+
{
|
11 |
+
public:
|
12 |
+
memstreambuf(size_t initial_buffer_size)
|
13 |
+
{
|
14 |
+
buffer.reserve(initial_buffer_size);
|
15 |
+
}
|
16 |
+
|
17 |
+
// Avoiding use of std::streambuf's move constructor, since it is missing for old GCC
|
18 |
+
memstreambuf(memstreambuf&& o)
|
19 |
+
: buffer(std::move(o.buffer))
|
20 |
+
{
|
21 |
+
pubseekpos(o.pubseekoff(0, std::ios_base::cur));
|
22 |
+
}
|
23 |
+
|
24 |
+
size_t size() const
|
25 |
+
{
|
26 |
+
return buffer.size();
|
27 |
+
}
|
28 |
+
|
29 |
+
const unsigned char* data() const
|
30 |
+
{
|
31 |
+
return buffer.data();
|
32 |
+
}
|
33 |
+
|
34 |
+
void clear()
|
35 |
+
{
|
36 |
+
buffer.clear();
|
37 |
+
}
|
38 |
+
|
39 |
+
std::vector<unsigned char> buffer;
|
40 |
+
|
41 |
+
protected:
|
42 |
+
std::streamsize xsputn(const char_type* __s, std::streamsize __n) override
|
43 |
+
{
|
44 |
+
buffer.insert(buffer.end(), __s, __s + __n);
|
45 |
+
return __n;
|
46 |
+
}
|
47 |
+
|
48 |
+
int_type overflow(int_type __c) override
|
49 |
+
{
|
50 |
+
buffer.push_back( static_cast<unsigned char>(__c) );
|
51 |
+
return __c;
|
52 |
+
}
|
53 |
+
};
|
54 |
+
|
55 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/param_set.h
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <unordered_set>
|
4 |
+
#include <regex>
|
5 |
+
|
6 |
+
#include <pangolin/utils/uri.h>
|
7 |
+
|
8 |
+
namespace pangolin
|
9 |
+
{
|
10 |
+
|
11 |
+
struct PANGOLIN_EXPORT ParamSet {
|
12 |
+
struct PANGOLIN_EXPORT Param {
|
13 |
+
std::string name_regex;
|
14 |
+
std::string default_value;
|
15 |
+
std::string description;
|
16 |
+
};
|
17 |
+
|
18 |
+
std::vector<Param> params;
|
19 |
+
std::string str() const;
|
20 |
+
};
|
21 |
+
|
22 |
+
class PANGOLIN_EXPORT ParamReader {
|
23 |
+
public:
|
24 |
+
class ParamReaderException : public std::exception {
|
25 |
+
public:
|
26 |
+
ParamReaderException( const std::string ¶m_name )
|
27 |
+
{
|
28 |
+
error_message_ = param_name + " was not found in the parameter set";
|
29 |
+
}
|
30 |
+
virtual const char* what() const noexcept override {
|
31 |
+
return error_message_.c_str();
|
32 |
+
}
|
33 |
+
private:
|
34 |
+
std::string error_message_;
|
35 |
+
};
|
36 |
+
|
37 |
+
ParamReader( const ParamSet& param_set, const Uri& uri )
|
38 |
+
: param_set_(param_set), uri_(uri)
|
39 |
+
{}
|
40 |
+
|
41 |
+
template<typename T>
|
42 |
+
T Get( const std::string& param_name ) const
|
43 |
+
{
|
44 |
+
const ParamSet::Param* param = GetMatchingParamFromParamSet( param_name );
|
45 |
+
if( param ){
|
46 |
+
return GetHelper(param_name, Convert<T,std::string>::Do(param->default_value));
|
47 |
+
}
|
48 |
+
throw ParamReaderException( param_name );
|
49 |
+
}
|
50 |
+
|
51 |
+
template<typename T>
|
52 |
+
T Get( const std::string& param_name, const T& default_value ) const
|
53 |
+
{
|
54 |
+
const ParamSet::Param* param = GetMatchingParamFromParamSet( param_name );
|
55 |
+
if( param ){
|
56 |
+
return GetHelper(param_name, default_value);
|
57 |
+
}
|
58 |
+
throw ParamReaderException( param_name );
|
59 |
+
}
|
60 |
+
|
61 |
+
bool Contains( const std::string& param_name );
|
62 |
+
|
63 |
+
std::unordered_set<std::string> FindUnrecognizedUriParams();
|
64 |
+
|
65 |
+
private:
|
66 |
+
template<typename T>
|
67 |
+
T GetHelper( const std::string& param_name, const T& default_value ) const
|
68 |
+
{
|
69 |
+
return uri_.Get(param_name, default_value);
|
70 |
+
}
|
71 |
+
|
72 |
+
const ParamSet::Param* GetMatchingParamFromParamSet( const std::string& param_name ) const;
|
73 |
+
|
74 |
+
private:
|
75 |
+
const ParamSet param_set_;
|
76 |
+
const Uri uri_;
|
77 |
+
};
|
78 |
+
|
79 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/params.h
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <pangolin/platform.h>
|
31 |
+
#include <pangolin/utils/type_convert.h>
|
32 |
+
|
33 |
+
#include <string>
|
34 |
+
#include <vector>
|
35 |
+
#include <algorithm>
|
36 |
+
|
37 |
+
namespace pangolin
|
38 |
+
{
|
39 |
+
|
40 |
+
struct PANGOLIN_EXPORT Params
|
41 |
+
{
|
42 |
+
// Why not an actual map here?
|
43 |
+
// Well, in some drivers (notably USB3Vision based drivers) order
|
44 |
+
// matters, sometimes with duplicate keys.
|
45 |
+
typedef std::pair<std::string,std::string> KeyValue;
|
46 |
+
typedef std::vector<KeyValue> ParamMap;
|
47 |
+
|
48 |
+
Params()
|
49 |
+
{
|
50 |
+
}
|
51 |
+
|
52 |
+
Params(std::initializer_list<std::pair<std::string,std::string>> l)
|
53 |
+
: params(l)
|
54 |
+
{
|
55 |
+
}
|
56 |
+
|
57 |
+
// \returns true iff any entry has the key \param key
|
58 |
+
bool Contains(const std::string& key) const
|
59 |
+
{
|
60 |
+
for(ParamMap::const_iterator it = params.begin(); it!=params.end(); ++it) {
|
61 |
+
if(it->first == key) return true;
|
62 |
+
}
|
63 |
+
return false;
|
64 |
+
}
|
65 |
+
|
66 |
+
// \returns the value of the last entry with key \param key
|
67 |
+
// or \param default_val if no such entry exists
|
68 |
+
template<typename T>
|
69 |
+
T Get(const std::string& key, T default_val) const
|
70 |
+
{
|
71 |
+
// Return last value passed to the key.
|
72 |
+
for(ParamMap::const_reverse_iterator it = params.rbegin(); it!=params.rend(); ++it) {
|
73 |
+
if(it->first == key) return Convert<T, std::string>::Do(it->second);
|
74 |
+
}
|
75 |
+
return default_val;
|
76 |
+
}
|
77 |
+
|
78 |
+
// Adds a new entry with key \param key and value \param val to the end of the parameters list
|
79 |
+
// note: Any existing entry with key \param key will remain, but be overriden users with map-semantics.
|
80 |
+
template<typename T>
|
81 |
+
void Set(const std::string& key, const T& val)
|
82 |
+
{
|
83 |
+
params.push_back(std::pair<std::string,std::string>(key,Convert<std::string,T>::Do(val)));
|
84 |
+
}
|
85 |
+
|
86 |
+
// Remove all entries with key \param key
|
87 |
+
void Remove(const std::string& key)
|
88 |
+
{
|
89 |
+
params.erase(std::remove_if(params.begin(), params.end(), [&key](const KeyValue& kv){
|
90 |
+
return kv.first == key;
|
91 |
+
}), params.end());
|
92 |
+
}
|
93 |
+
|
94 |
+
ParamMap params;
|
95 |
+
};
|
96 |
+
|
97 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/parse.h
ADDED
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#ifndef PANGOLIN_PARSE_H
|
29 |
+
#define PANGOLIN_PARSE_H
|
30 |
+
|
31 |
+
#include <string>
|
32 |
+
#include <cctype>
|
33 |
+
|
34 |
+
namespace pangolin
|
35 |
+
{
|
36 |
+
|
37 |
+
const unsigned int parse_max_token_size = 1024;
|
38 |
+
|
39 |
+
inline void ConsumeWhitespace(std::istream& is)
|
40 |
+
{
|
41 |
+
while(is.good() && std::isspace(is.peek()) ) {
|
42 |
+
is.get();
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
inline bool ConsumeToNewline(std::istream& is)
|
47 |
+
{
|
48 |
+
while(is.good()) {
|
49 |
+
if(is.get() == '\n') {
|
50 |
+
return true;
|
51 |
+
}
|
52 |
+
}
|
53 |
+
return false;
|
54 |
+
}
|
55 |
+
|
56 |
+
template<size_t buffer_size> inline
|
57 |
+
size_t ReadToken(std::istream& is, char buffer[buffer_size])
|
58 |
+
{
|
59 |
+
size_t r = 0;
|
60 |
+
while(is.good() && r < buffer_size-1) {
|
61 |
+
int c = is.peek();
|
62 |
+
if( std::isgraph(c) ) {
|
63 |
+
buffer[r++] = (char)is.get();
|
64 |
+
}else{
|
65 |
+
break;
|
66 |
+
}
|
67 |
+
}
|
68 |
+
buffer[r] = '\0';
|
69 |
+
return r;
|
70 |
+
}
|
71 |
+
|
72 |
+
inline std::string ReadToken(std::istream &is)
|
73 |
+
{
|
74 |
+
char str_token[parse_max_token_size];
|
75 |
+
ReadToken<parse_max_token_size>(is, str_token);
|
76 |
+
return std::string(str_token);
|
77 |
+
}
|
78 |
+
|
79 |
+
template<size_t buffer_size> inline
|
80 |
+
size_t ConsumeWhitespaceReadToken(std::istream& is, char buffer[buffer_size])
|
81 |
+
{
|
82 |
+
ConsumeWhitespace(is);
|
83 |
+
return ReadToken<buffer_size>(is, buffer);
|
84 |
+
}
|
85 |
+
|
86 |
+
inline int ParseToken(const char* token, const char* token_list[], size_t token_list_size)
|
87 |
+
{
|
88 |
+
for(size_t i=0; i < token_list_size; ++i) {
|
89 |
+
if( strcmp(token, token_list[i]) == 0 ) {
|
90 |
+
return i;
|
91 |
+
}
|
92 |
+
}
|
93 |
+
return -1;
|
94 |
+
}
|
95 |
+
|
96 |
+
#define PANGOLIN_DEFINE_PARSE_TOKEN(x) \
|
97 |
+
inline x ParseToken##x(const char* token) { \
|
98 |
+
return (x)ParseToken(token, x##String, x##Size); \
|
99 |
+
} \
|
100 |
+
inline x ParseToken##x(std::istream& is) { \
|
101 |
+
char str_token[parse_max_token_size]; \
|
102 |
+
ReadToken<parse_max_token_size>(is, str_token); \
|
103 |
+
return ParseToken##x( str_token ); \
|
104 |
+
}
|
105 |
+
|
106 |
+
}
|
107 |
+
|
108 |
+
#endif // PANGOLIN_PARSE_H
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/picojson.h
ADDED
@@ -0,0 +1,1416 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This is a (butchered) derivative of picojson, incorporated into the
|
2 |
+
* Pangolin Project (http://github.com/stevenlovegrove/Pangolin)
|
3 |
+
*
|
4 |
+
* Modifications Copyright (c) 2014 Steven Lovegrove,
|
5 |
+
* Original licence applies (below), https://github.com/kazuho/picojson
|
6 |
+
*/
|
7 |
+
|
8 |
+
/*
|
9 |
+
* Copyright 2009-2010 Cybozu Labs, Inc.
|
10 |
+
* Copyright 2011-2014 Kazuho Oku
|
11 |
+
* All rights reserved.
|
12 |
+
*
|
13 |
+
* Redistribution and use in source and binary forms, with or without
|
14 |
+
* modification, are permitted provided that the following conditions are met:
|
15 |
+
*
|
16 |
+
* 1. Redistributions of source code must retain the above copyright notice,
|
17 |
+
* this list of conditions and the following disclaimer.
|
18 |
+
*
|
19 |
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
20 |
+
* this list of conditions and the following disclaimer in the documentation
|
21 |
+
* and/or other materials provided with the distribution.
|
22 |
+
*
|
23 |
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
24 |
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
25 |
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
26 |
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
27 |
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
28 |
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
29 |
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
30 |
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
31 |
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
32 |
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
33 |
+
* POSSIBILITY OF SUCH DAMAGE.
|
34 |
+
*/
|
35 |
+
#ifndef picojson_h
|
36 |
+
#define picojson_h
|
37 |
+
|
38 |
+
#include <algorithm>
|
39 |
+
#include <cstdio>
|
40 |
+
#include <cstdlib>
|
41 |
+
#include <cstring>
|
42 |
+
#include <iostream>
|
43 |
+
#include <iterator>
|
44 |
+
#include <limits>
|
45 |
+
#include <map>
|
46 |
+
#include <stdexcept>
|
47 |
+
#include <string>
|
48 |
+
#include <vector>
|
49 |
+
|
50 |
+
#include <pangolin/compat/type_traits.h>
|
51 |
+
|
52 |
+
// Enable INT64 support
|
53 |
+
#define PICOJSON_USE_INT64
|
54 |
+
|
55 |
+
// for isnan/isinf
|
56 |
+
#if __cplusplus>=201103L
|
57 |
+
# include <cmath>
|
58 |
+
#else
|
59 |
+
extern "C" {
|
60 |
+
# ifdef _MSC_VER
|
61 |
+
# include <float.h>
|
62 |
+
# elif defined(__INTEL_COMPILER)
|
63 |
+
# include <mathimf.h>
|
64 |
+
# else
|
65 |
+
# include <math.h>
|
66 |
+
# endif
|
67 |
+
}
|
68 |
+
#endif
|
69 |
+
|
70 |
+
// experimental support for int64_t (see README.mkdn for detail)
|
71 |
+
#ifdef PICOJSON_USE_INT64
|
72 |
+
# ifndef __STDC_FORMAT_MACROS
|
73 |
+
# define __STDC_FORMAT_MACROS
|
74 |
+
# endif
|
75 |
+
# include <errno.h>
|
76 |
+
# include <inttypes.h>
|
77 |
+
#endif // PICOJSON_USE_INT64
|
78 |
+
|
79 |
+
// to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0
|
80 |
+
#ifndef PICOJSON_USE_LOCALE
|
81 |
+
# define PICOJSON_USE_LOCALE 1
|
82 |
+
#endif // PICOJSON_USE_LOCALE
|
83 |
+
|
84 |
+
#if PICOJSON_USE_LOCALE
|
85 |
+
extern "C" {
|
86 |
+
# include <locale.h>
|
87 |
+
}
|
88 |
+
#endif // PICOJSON_USE_LOCALE
|
89 |
+
|
90 |
+
#ifndef PICOJSON_ASSERT
|
91 |
+
# define PICOJSON_ASSERT(e) do { if (! (e)) throw std::runtime_error(#e); } while (0)
|
92 |
+
#endif
|
93 |
+
|
94 |
+
#ifdef _MSC_VER
|
95 |
+
#define SNPRINTF _snprintf_s
|
96 |
+
#pragma warning(push)
|
97 |
+
#pragma warning(disable : 4244) // conversion from int to char
|
98 |
+
#else
|
99 |
+
#define SNPRINTF snprintf
|
100 |
+
#endif
|
101 |
+
|
102 |
+
#ifdef _MSC_VER
|
103 |
+
#define PICOJSON_FALSE_TEMPLATE_TYPE nullptr
|
104 |
+
#else
|
105 |
+
#define PICOJSON_FALSE_TEMPLATE_TYPE ((void*)0)
|
106 |
+
#endif
|
107 |
+
|
108 |
+
namespace picojson {
|
109 |
+
|
110 |
+
enum {
|
111 |
+
null_type,
|
112 |
+
boolean_type,
|
113 |
+
number_type,
|
114 |
+
string_type,
|
115 |
+
array_type,
|
116 |
+
object_type
|
117 |
+
#ifdef PICOJSON_USE_INT64
|
118 |
+
, int64_type
|
119 |
+
#endif
|
120 |
+
};
|
121 |
+
|
122 |
+
enum {
|
123 |
+
INDENT_WIDTH = 2
|
124 |
+
};
|
125 |
+
|
126 |
+
struct null {};
|
127 |
+
|
128 |
+
class value {
|
129 |
+
public:
|
130 |
+
typedef std::vector<value> array;
|
131 |
+
typedef std::map<std::string, value> object;
|
132 |
+
|
133 |
+
union _storage {
|
134 |
+
bool boolean_;
|
135 |
+
double number_;
|
136 |
+
#ifdef PICOJSON_USE_INT64
|
137 |
+
int64_t int64_;
|
138 |
+
#endif
|
139 |
+
std::string* string_;
|
140 |
+
array* array_;
|
141 |
+
object* object_;
|
142 |
+
};
|
143 |
+
protected:
|
144 |
+
int type_;
|
145 |
+
_storage u_;
|
146 |
+
public:
|
147 |
+
|
148 |
+
|
149 |
+
/////////////////////////////
|
150 |
+
// Constructors / Destructor
|
151 |
+
/////////////////////////////
|
152 |
+
|
153 |
+
~value();
|
154 |
+
value();
|
155 |
+
value(int type, bool);
|
156 |
+
|
157 |
+
/////////////////////////////
|
158 |
+
// Implicit type constructors
|
159 |
+
/////////////////////////////
|
160 |
+
|
161 |
+
value(bool b) : type_(boolean_type) {
|
162 |
+
u_.boolean_ = b;
|
163 |
+
}
|
164 |
+
|
165 |
+
#ifdef PICOJSON_USE_INT64
|
166 |
+
value(short v) : type_(int64_type) {
|
167 |
+
u_.int64_ = static_cast<int64_t>(v);
|
168 |
+
}
|
169 |
+
value(unsigned short v) : type_(int64_type) {
|
170 |
+
u_.int64_ = static_cast<int64_t>(v);
|
171 |
+
}
|
172 |
+
value(int v) : type_(int64_type) {
|
173 |
+
u_.int64_ = static_cast<int64_t>(v);
|
174 |
+
}
|
175 |
+
value(unsigned int v) : type_(int64_type) {
|
176 |
+
u_.int64_ = static_cast<int64_t>(v);
|
177 |
+
}
|
178 |
+
value(long v) : type_(int64_type) {
|
179 |
+
u_.int64_ = static_cast<int64_t>(v);
|
180 |
+
}
|
181 |
+
value(unsigned long v) : type_(int64_type) {
|
182 |
+
u_.int64_ = static_cast<int64_t>(v);
|
183 |
+
}
|
184 |
+
value(long long v) : type_(int64_type) {
|
185 |
+
u_.int64_ = static_cast<int64_t>(v);
|
186 |
+
}
|
187 |
+
value(unsigned long long v) : type_(int64_type) {
|
188 |
+
u_.int64_ = static_cast<int64_t>(v);
|
189 |
+
}
|
190 |
+
#endif
|
191 |
+
|
192 |
+
value(float n) : type_(number_type) {
|
193 |
+
if (
|
194 |
+
#ifdef _MSC_VER
|
195 |
+
! _finite(n)
|
196 |
+
#elif __cplusplus>=201103L || !(defined(isnan) && defined(isinf))
|
197 |
+
std::isnan(n) || std::isinf(n)
|
198 |
+
#else
|
199 |
+
isnan(n) || isinf(n)
|
200 |
+
#endif
|
201 |
+
) {
|
202 |
+
throw std::overflow_error("");
|
203 |
+
}
|
204 |
+
u_.number_ = static_cast<double>(n);
|
205 |
+
}
|
206 |
+
|
207 |
+
value(double n) : type_(number_type) {
|
208 |
+
if (
|
209 |
+
#ifdef _MSC_VER
|
210 |
+
! _finite(n)
|
211 |
+
#elif __cplusplus>=201103L || !(defined(isnan) && defined(isinf))
|
212 |
+
std::isnan(n) || std::isinf(n)
|
213 |
+
#else
|
214 |
+
isnan(n) || isinf(n)
|
215 |
+
#endif
|
216 |
+
) {
|
217 |
+
throw std::overflow_error("");
|
218 |
+
}
|
219 |
+
u_.number_ = n;
|
220 |
+
}
|
221 |
+
|
222 |
+
value(const array& a);
|
223 |
+
value(const object& o);
|
224 |
+
|
225 |
+
value(const std::string& s);
|
226 |
+
value(const char* s);
|
227 |
+
value(const char* s, size_t len);
|
228 |
+
|
229 |
+
value(const value& x);
|
230 |
+
value& operator=(const value& x);
|
231 |
+
|
232 |
+
/////////////////////////////
|
233 |
+
// Query / get type
|
234 |
+
/////////////////////////////
|
235 |
+
|
236 |
+
void swap(value& x);
|
237 |
+
template <typename T> bool is() const;
|
238 |
+
template <typename T> const T& get() const;
|
239 |
+
template <typename T> T& get();
|
240 |
+
bool evaluate_as_boolean() const;
|
241 |
+
size_t size() const;
|
242 |
+
|
243 |
+
/////////////////////////////
|
244 |
+
// Usage as array
|
245 |
+
/////////////////////////////
|
246 |
+
|
247 |
+
value& operator[](size_t idx);
|
248 |
+
const value& operator[](size_t idx) const;
|
249 |
+
bool contains(size_t idx) const;
|
250 |
+
value& push_back(const value& = value() );
|
251 |
+
|
252 |
+
/////////////////////////////
|
253 |
+
// Usage as object
|
254 |
+
/////////////////////////////
|
255 |
+
|
256 |
+
value& operator[](const std::string& key);
|
257 |
+
const value& operator[](const std::string& key) const;
|
258 |
+
bool contains(const std::string& key) const;
|
259 |
+
|
260 |
+
template <typename T>
|
261 |
+
T get_value(const std::string& key, T default_value) const;
|
262 |
+
|
263 |
+
/////////////////////////////
|
264 |
+
// Serialization
|
265 |
+
/////////////////////////////
|
266 |
+
|
267 |
+
std::string to_str() const;
|
268 |
+
template <typename Iter> void serialize(Iter os, bool prettify = false) const;
|
269 |
+
std::string serialize(bool prettify = false) const;
|
270 |
+
private:
|
271 |
+
template <typename T> value(const T*); // intentionally defined to block implicit conversion of pointer to bool
|
272 |
+
template <typename Iter> static void _indent(Iter os, int indent);
|
273 |
+
template <typename Iter> void serialize_(Iter os, int indent) const;
|
274 |
+
std::string serialize_(int indent) const;
|
275 |
+
};
|
276 |
+
|
277 |
+
typedef value::array array;
|
278 |
+
typedef value::object object;
|
279 |
+
|
280 |
+
inline value::value() : type_(null_type), u_({false}) {}
|
281 |
+
|
282 |
+
inline value::value(int type, bool) : type_(type) {
|
283 |
+
switch (type) {
|
284 |
+
#define INIT(p, v) case p##type: u_.p = v; break
|
285 |
+
INIT(boolean_, false);
|
286 |
+
INIT(number_, 0.0);
|
287 |
+
#ifdef PICOJSON_USE_INT64
|
288 |
+
INIT(int64_, 0);
|
289 |
+
#endif
|
290 |
+
INIT(string_, new std::string());
|
291 |
+
INIT(array_, new array());
|
292 |
+
INIT(object_, new object());
|
293 |
+
#undef INIT
|
294 |
+
default: break;
|
295 |
+
}
|
296 |
+
}
|
297 |
+
|
298 |
+
inline value::value(const std::string& s) : type_(string_type) {
|
299 |
+
u_.string_ = new std::string(s);
|
300 |
+
}
|
301 |
+
|
302 |
+
inline value::value(const array& a) : type_(array_type) {
|
303 |
+
u_.array_ = new array(a);
|
304 |
+
}
|
305 |
+
|
306 |
+
inline value::value(const object& o) : type_(object_type) {
|
307 |
+
u_.object_ = new object(o);
|
308 |
+
}
|
309 |
+
|
310 |
+
inline value::value(const char* s) : type_(string_type) {
|
311 |
+
u_.string_ = new std::string(s);
|
312 |
+
}
|
313 |
+
|
314 |
+
inline value::value(const char* s, size_t len) : type_(string_type) {
|
315 |
+
u_.string_ = new std::string(s, len);
|
316 |
+
}
|
317 |
+
|
318 |
+
inline value::~value() {
|
319 |
+
switch (type_) {
|
320 |
+
#define DEINIT(p) case p##type: delete u_.p; break
|
321 |
+
DEINIT(string_);
|
322 |
+
DEINIT(array_);
|
323 |
+
DEINIT(object_);
|
324 |
+
#undef DEINIT
|
325 |
+
default: break;
|
326 |
+
}
|
327 |
+
}
|
328 |
+
|
329 |
+
inline value::value(const value& x) : type_(x.type_) {
|
330 |
+
switch (type_) {
|
331 |
+
#define INIT(p, v) case p##type: u_.p = v; break
|
332 |
+
INIT(string_, new std::string(*x.u_.string_));
|
333 |
+
INIT(array_, new array(*x.u_.array_));
|
334 |
+
INIT(object_, new object(*x.u_.object_));
|
335 |
+
#undef INIT
|
336 |
+
default:
|
337 |
+
u_ = x.u_;
|
338 |
+
break;
|
339 |
+
}
|
340 |
+
}
|
341 |
+
|
342 |
+
inline value& value::operator=(const value& x) {
|
343 |
+
if (this != &x) {
|
344 |
+
this->~value();
|
345 |
+
new (this) value(x);
|
346 |
+
}
|
347 |
+
return *this;
|
348 |
+
}
|
349 |
+
|
350 |
+
inline void value::swap(value& x) {
|
351 |
+
std::swap(type_, x.type_);
|
352 |
+
std::swap(u_, x.u_);
|
353 |
+
}
|
354 |
+
|
355 |
+
#define IS(ctype, jtype) \
|
356 |
+
template <> inline bool value::is<ctype>() const { \
|
357 |
+
return type_ == jtype##_type; \
|
358 |
+
}
|
359 |
+
IS(null, null)
|
360 |
+
IS(bool, boolean)
|
361 |
+
#ifdef PICOJSON_USE_INT64
|
362 |
+
IS(int64_t, int64)
|
363 |
+
#endif
|
364 |
+
IS(std::string, string)
|
365 |
+
IS(array, array)
|
366 |
+
IS(object, object)
|
367 |
+
#undef IS
|
368 |
+
template <> inline bool value::is<double>() const {
|
369 |
+
return type_ == number_type
|
370 |
+
#ifdef PICOJSON_USE_INT64
|
371 |
+
|| type_ == int64_type
|
372 |
+
#endif
|
373 |
+
;
|
374 |
+
}
|
375 |
+
|
376 |
+
#define GET(ctype, var) \
|
377 |
+
template <> inline const ctype& value::get<ctype>() const { \
|
378 |
+
PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" \
|
379 |
+
&& is<ctype>()); \
|
380 |
+
return var; \
|
381 |
+
} \
|
382 |
+
template <> inline ctype& value::get<ctype>() { \
|
383 |
+
PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" \
|
384 |
+
&& is<ctype>()); \
|
385 |
+
return var; \
|
386 |
+
}
|
387 |
+
GET(bool, u_.boolean_)
|
388 |
+
GET(std::string, *u_.string_)
|
389 |
+
GET(array, *u_.array_)
|
390 |
+
GET(object, *u_.object_)
|
391 |
+
#ifdef PICOJSON_USE_INT64
|
392 |
+
GET(double, (type_ == int64_type && (const_cast<value*>(this)->type_ = number_type, const_cast<value*>(this)->u_.number_ = u_.int64_), u_.number_))
|
393 |
+
GET(int64_t, u_.int64_)
|
394 |
+
#else
|
395 |
+
GET(double, u_.number_)
|
396 |
+
#endif
|
397 |
+
#undef GET
|
398 |
+
|
399 |
+
inline bool value::evaluate_as_boolean() const {
|
400 |
+
switch (type_) {
|
401 |
+
case null_type:
|
402 |
+
return false;
|
403 |
+
case boolean_type:
|
404 |
+
return u_.boolean_;
|
405 |
+
case number_type:
|
406 |
+
return u_.number_ != 0;
|
407 |
+
case string_type:
|
408 |
+
return ! u_.string_->empty();
|
409 |
+
default:
|
410 |
+
return true;
|
411 |
+
}
|
412 |
+
}
|
413 |
+
|
414 |
+
inline size_t value::size() const
|
415 |
+
{
|
416 |
+
PICOJSON_ASSERT("Type mismatch! Not array." && is<array>());
|
417 |
+
return u_.array_->size();
|
418 |
+
}
|
419 |
+
|
420 |
+
inline const value& value::operator[](size_t idx) const {
|
421 |
+
PICOJSON_ASSERT("Type mismatch! Not array." && is<array>());
|
422 |
+
PICOJSON_ASSERT("Out of bounds." && idx < u_.array_->size() );
|
423 |
+
return (*u_.array_)[idx];
|
424 |
+
}
|
425 |
+
|
426 |
+
inline value& value::operator[](size_t idx) {
|
427 |
+
if( type_ == null_type ) {
|
428 |
+
// instantiate as array
|
429 |
+
type_ = array_type;
|
430 |
+
u_.array_ = new array();
|
431 |
+
}
|
432 |
+
|
433 |
+
PICOJSON_ASSERT("Type mismatch! Not array." && is<array>());
|
434 |
+
PICOJSON_ASSERT("Out of bounds." && idx < u_.array_->size() );
|
435 |
+
return (*u_.array_)[idx];
|
436 |
+
}
|
437 |
+
|
438 |
+
inline bool value::contains(size_t idx) const {
|
439 |
+
if( type_ == array_type) {
|
440 |
+
return idx < u_.array_->size();
|
441 |
+
}else{
|
442 |
+
return false;
|
443 |
+
}
|
444 |
+
}
|
445 |
+
|
446 |
+
inline value& value::push_back(const value& val)
|
447 |
+
{
|
448 |
+
if( type_ == null_type ) {
|
449 |
+
// instantiate as array
|
450 |
+
type_ = array_type;
|
451 |
+
u_.array_ = new array();
|
452 |
+
}
|
453 |
+
PICOJSON_ASSERT("Type mismatch! Not array." && is<array>());
|
454 |
+
u_.array_->push_back( val );
|
455 |
+
return u_.array_->back();
|
456 |
+
}
|
457 |
+
|
458 |
+
inline const value& value::operator[](const std::string& key) const {
|
459 |
+
PICOJSON_ASSERT("Type mismatch! Not object." && is<object>() );
|
460 |
+
object::const_iterator i = u_.object_->find(key);
|
461 |
+
PICOJSON_ASSERT("Key not found." && i != u_.object_->end() );
|
462 |
+
return i->second;
|
463 |
+
}
|
464 |
+
|
465 |
+
inline value& value::operator[](const std::string& key) {
|
466 |
+
if( type_ == null_type ) {
|
467 |
+
// instantiate as object
|
468 |
+
type_ = object_type;
|
469 |
+
u_.object_ = new object();
|
470 |
+
}
|
471 |
+
PICOJSON_ASSERT("Type mismatch! Not object." && is<object>());
|
472 |
+
return u_.object_->operator [](key);
|
473 |
+
}
|
474 |
+
|
475 |
+
inline bool value::contains(const std::string& key) const {
|
476 |
+
if( type_ == object_type) {
|
477 |
+
object::const_iterator i = u_.object_->find(key);
|
478 |
+
return i != u_.object_->end();
|
479 |
+
}else{
|
480 |
+
return false;
|
481 |
+
}
|
482 |
+
}
|
483 |
+
|
484 |
+
template <typename T>
|
485 |
+
inline T value::get_value(const std::string& key, T default_value) const {
|
486 |
+
if(contains(key)) {
|
487 |
+
return (*this)[key].get<T>();
|
488 |
+
}else{
|
489 |
+
return default_value;
|
490 |
+
}
|
491 |
+
}
|
492 |
+
|
493 |
+
inline std::string value::to_str() const {
|
494 |
+
switch (type_) {
|
495 |
+
case null_type: return "null";
|
496 |
+
case boolean_type: return u_.boolean_ ? "true" : "false";
|
497 |
+
#ifdef PICOJSON_USE_INT64
|
498 |
+
case int64_type: {
|
499 |
+
char buf[sizeof("-9223372036854775808")];
|
500 |
+
SNPRINTF(buf, sizeof(buf), "%" PRId64, u_.int64_);
|
501 |
+
return buf;
|
502 |
+
}
|
503 |
+
#endif
|
504 |
+
case number_type: {
|
505 |
+
char buf[256];
|
506 |
+
double tmp;
|
507 |
+
SNPRINTF(buf, sizeof(buf), fabs(u_.number_) < (1ULL << 53) && modf(u_.number_, &tmp) == 0 ? "%.f" : "%.17g", u_.number_);
|
508 |
+
#if PICOJSON_USE_LOCALE
|
509 |
+
char *decimal_point = localeconv()->decimal_point;
|
510 |
+
if (strcmp(decimal_point, ".") != 0) {
|
511 |
+
size_t decimal_point_len = strlen(decimal_point);
|
512 |
+
for (char *p = buf; *p != '\0'; ++p) {
|
513 |
+
if (strncmp(p, decimal_point, decimal_point_len) == 0) {
|
514 |
+
return std::string(buf, p) + "." + (p + decimal_point_len);
|
515 |
+
}
|
516 |
+
}
|
517 |
+
}
|
518 |
+
#endif
|
519 |
+
return buf;
|
520 |
+
}
|
521 |
+
case string_type: return *u_.string_;
|
522 |
+
case array_type: return "array";
|
523 |
+
case object_type: return "object";
|
524 |
+
default: PICOJSON_ASSERT("value::to_str() assert failed." && 0);
|
525 |
+
#ifdef _MSC_VER
|
526 |
+
__assume(0);
|
527 |
+
#endif
|
528 |
+
}
|
529 |
+
}
|
530 |
+
|
531 |
+
template <typename Iter> void copy(const std::string& s, Iter oi) {
|
532 |
+
std::copy(s.begin(), s.end(), oi);
|
533 |
+
}
|
534 |
+
|
535 |
+
template <typename Iter> void serialize_str(const std::string& s, Iter oi) {
|
536 |
+
*oi++ = '"';
|
537 |
+
for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
|
538 |
+
switch (*i) {
|
539 |
+
#define MAP(val, sym) case val: copy(sym, oi); break
|
540 |
+
MAP('"', "\\\"");
|
541 |
+
MAP('\\', "\\\\");
|
542 |
+
MAP('/', "\\/");
|
543 |
+
MAP('\b', "\\b");
|
544 |
+
MAP('\f', "\\f");
|
545 |
+
MAP('\n', "\\n");
|
546 |
+
MAP('\r', "\\r");
|
547 |
+
MAP('\t', "\\t");
|
548 |
+
#undef MAP
|
549 |
+
default:
|
550 |
+
if (static_cast<unsigned char>(*i) < 0x20 || *i == 0x7f) {
|
551 |
+
char buf[7];
|
552 |
+
SNPRINTF(buf, sizeof(buf), "\\u%04x", *i & 0xff);
|
553 |
+
copy(buf, buf + 6, oi);
|
554 |
+
} else {
|
555 |
+
*oi++ = *i;
|
556 |
+
}
|
557 |
+
break;
|
558 |
+
}
|
559 |
+
}
|
560 |
+
*oi++ = '"';
|
561 |
+
}
|
562 |
+
|
563 |
+
template <typename Iter> void value::serialize(Iter oi, bool prettify) const {
|
564 |
+
return serialize_(oi, prettify ? 0 : -1);
|
565 |
+
}
|
566 |
+
|
567 |
+
inline std::string value::serialize(bool prettify) const {
|
568 |
+
return serialize_(prettify ? 0 : -1);
|
569 |
+
}
|
570 |
+
|
571 |
+
template <typename Iter> void value::_indent(Iter oi, int indent) {
|
572 |
+
*oi++ = '\n';
|
573 |
+
for (int i = 0; i < indent * INDENT_WIDTH; ++i) {
|
574 |
+
*oi++ = ' ';
|
575 |
+
}
|
576 |
+
}
|
577 |
+
|
578 |
+
template <typename Iter> void value::serialize_(Iter oi, int indent) const {
|
579 |
+
switch (type_) {
|
580 |
+
case string_type:
|
581 |
+
serialize_str(*u_.string_, oi);
|
582 |
+
break;
|
583 |
+
case array_type: {
|
584 |
+
*oi++ = '[';
|
585 |
+
if (indent != -1) {
|
586 |
+
++indent;
|
587 |
+
}
|
588 |
+
for (array::const_iterator i = u_.array_->begin();
|
589 |
+
i != u_.array_->end();
|
590 |
+
++i) {
|
591 |
+
if (i != u_.array_->begin()) {
|
592 |
+
*oi++ = ',';
|
593 |
+
}
|
594 |
+
if (indent != -1) {
|
595 |
+
_indent(oi, indent);
|
596 |
+
}
|
597 |
+
i->serialize_(oi, indent);
|
598 |
+
}
|
599 |
+
if (indent != -1) {
|
600 |
+
--indent;
|
601 |
+
if (! u_.array_->empty()) {
|
602 |
+
_indent(oi, indent);
|
603 |
+
}
|
604 |
+
}
|
605 |
+
*oi++ = ']';
|
606 |
+
break;
|
607 |
+
}
|
608 |
+
case object_type: {
|
609 |
+
*oi++ = '{';
|
610 |
+
if (indent != -1) {
|
611 |
+
++indent;
|
612 |
+
}
|
613 |
+
for (object::const_iterator i = u_.object_->begin();
|
614 |
+
i != u_.object_->end();
|
615 |
+
++i) {
|
616 |
+
if (i != u_.object_->begin()) {
|
617 |
+
*oi++ = ',';
|
618 |
+
}
|
619 |
+
if (indent != -1) {
|
620 |
+
_indent(oi, indent);
|
621 |
+
}
|
622 |
+
serialize_str(i->first, oi);
|
623 |
+
*oi++ = ':';
|
624 |
+
if (indent != -1) {
|
625 |
+
*oi++ = ' ';
|
626 |
+
}
|
627 |
+
i->second.serialize_(oi, indent);
|
628 |
+
}
|
629 |
+
if (indent != -1) {
|
630 |
+
--indent;
|
631 |
+
if (! u_.object_->empty()) {
|
632 |
+
_indent(oi, indent);
|
633 |
+
}
|
634 |
+
}
|
635 |
+
*oi++ = '}';
|
636 |
+
break;
|
637 |
+
}
|
638 |
+
default:
|
639 |
+
copy(to_str(), oi);
|
640 |
+
break;
|
641 |
+
}
|
642 |
+
if (indent == 0) {
|
643 |
+
*oi++ = '\n';
|
644 |
+
}
|
645 |
+
}
|
646 |
+
|
647 |
+
inline std::string value::serialize_(int indent) const {
|
648 |
+
std::string s;
|
649 |
+
serialize_(std::back_inserter(s), indent);
|
650 |
+
return s;
|
651 |
+
}
|
652 |
+
|
653 |
+
template <typename Iter> class input {
|
654 |
+
protected:
|
655 |
+
Iter cur_, end_;
|
656 |
+
int last_ch_;
|
657 |
+
bool ungot_;
|
658 |
+
int line_;
|
659 |
+
public:
|
660 |
+
input(const Iter& first, const Iter& last) : cur_(first), end_(last), last_ch_(-1), ungot_(false), line_(1) {}
|
661 |
+
int getc() {
|
662 |
+
if (ungot_) {
|
663 |
+
ungot_ = false;
|
664 |
+
return last_ch_;
|
665 |
+
}
|
666 |
+
if (cur_ == end_) {
|
667 |
+
last_ch_ = -1;
|
668 |
+
return -1;
|
669 |
+
}
|
670 |
+
if (last_ch_ == '\n') {
|
671 |
+
line_++;
|
672 |
+
}
|
673 |
+
last_ch_ = *cur_ & 0xff;
|
674 |
+
++cur_;
|
675 |
+
return last_ch_;
|
676 |
+
}
|
677 |
+
void ungetc() {
|
678 |
+
if (last_ch_ != -1) {
|
679 |
+
PICOJSON_ASSERT(! ungot_);
|
680 |
+
ungot_ = true;
|
681 |
+
}
|
682 |
+
}
|
683 |
+
Iter cur() const { return cur_; }
|
684 |
+
int line() const { return line_; }
|
685 |
+
void skip_ws() {
|
686 |
+
while (1) {
|
687 |
+
int ch = getc();
|
688 |
+
if (! (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')) {
|
689 |
+
ungetc();
|
690 |
+
break;
|
691 |
+
}
|
692 |
+
}
|
693 |
+
}
|
694 |
+
bool expect(int expect) {
|
695 |
+
skip_ws();
|
696 |
+
if (getc() != expect) {
|
697 |
+
ungetc();
|
698 |
+
return false;
|
699 |
+
}
|
700 |
+
return true;
|
701 |
+
}
|
702 |
+
bool match(const std::string& pattern) {
|
703 |
+
for (std::string::const_iterator pi(pattern.begin());
|
704 |
+
pi != pattern.end();
|
705 |
+
++pi) {
|
706 |
+
if (getc() != *pi) {
|
707 |
+
ungetc();
|
708 |
+
return false;
|
709 |
+
}
|
710 |
+
}
|
711 |
+
return true;
|
712 |
+
}
|
713 |
+
};
|
714 |
+
|
715 |
+
template<typename Iter> inline int _parse_quadhex(input<Iter> &in) {
|
716 |
+
int uni_ch = 0, hex;
|
717 |
+
for (int i = 0; i < 4; i++) {
|
718 |
+
if ((hex = in.getc()) == -1) {
|
719 |
+
return -1;
|
720 |
+
}
|
721 |
+
if ('0' <= hex && hex <= '9') {
|
722 |
+
hex -= '0';
|
723 |
+
} else if ('A' <= hex && hex <= 'F') {
|
724 |
+
hex -= 'A' - 0xa;
|
725 |
+
} else if ('a' <= hex && hex <= 'f') {
|
726 |
+
hex -= 'a' - 0xa;
|
727 |
+
} else {
|
728 |
+
in.ungetc();
|
729 |
+
return -1;
|
730 |
+
}
|
731 |
+
uni_ch = uni_ch * 16 + hex;
|
732 |
+
}
|
733 |
+
return uni_ch;
|
734 |
+
}
|
735 |
+
|
736 |
+
template<typename String, typename Iter> inline bool _parse_codepoint(String& out, input<Iter>& in) {
|
737 |
+
int uni_ch;
|
738 |
+
if ((uni_ch = _parse_quadhex(in)) == -1) {
|
739 |
+
return false;
|
740 |
+
}
|
741 |
+
if (0xd800 <= uni_ch && uni_ch <= 0xdfff) {
|
742 |
+
if (0xdc00 <= uni_ch) {
|
743 |
+
// a second 16-bit of a surrogate pair appeared
|
744 |
+
return false;
|
745 |
+
}
|
746 |
+
// first 16-bit of surrogate pair, get the next one
|
747 |
+
if (in.getc() != '\\' || in.getc() != 'u') {
|
748 |
+
in.ungetc();
|
749 |
+
return false;
|
750 |
+
}
|
751 |
+
int second = _parse_quadhex(in);
|
752 |
+
if (! (0xdc00 <= second && second <= 0xdfff)) {
|
753 |
+
return false;
|
754 |
+
}
|
755 |
+
uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
|
756 |
+
uni_ch += 0x10000;
|
757 |
+
}
|
758 |
+
if (uni_ch < 0x80) {
|
759 |
+
out.push_back(uni_ch);
|
760 |
+
} else {
|
761 |
+
if (uni_ch < 0x800) {
|
762 |
+
out.push_back(0xc0 | (uni_ch >> 6));
|
763 |
+
} else {
|
764 |
+
if (uni_ch < 0x10000) {
|
765 |
+
out.push_back(0xe0 | (uni_ch >> 12));
|
766 |
+
} else {
|
767 |
+
out.push_back(0xf0 | (uni_ch >> 18));
|
768 |
+
out.push_back(0x80 | ((uni_ch >> 12) & 0x3f));
|
769 |
+
}
|
770 |
+
out.push_back(0x80 | ((uni_ch >> 6) & 0x3f));
|
771 |
+
}
|
772 |
+
out.push_back(0x80 | (uni_ch & 0x3f));
|
773 |
+
}
|
774 |
+
return true;
|
775 |
+
}
|
776 |
+
|
777 |
+
template<typename String, typename Iter> inline bool _parse_string(String& out, input<Iter>& in, int delim='"') {
|
778 |
+
while (1) {
|
779 |
+
int ch = in.getc();
|
780 |
+
if (ch < ' ') {
|
781 |
+
in.ungetc();
|
782 |
+
return false;
|
783 |
+
} else if (ch == delim) {
|
784 |
+
return true;
|
785 |
+
} else if (ch == '\\') {
|
786 |
+
if ((ch = in.getc()) == -1) {
|
787 |
+
return false;
|
788 |
+
}
|
789 |
+
switch (ch) {
|
790 |
+
#define MAP(sym, val) case sym: out.push_back(val); break
|
791 |
+
MAP('"', '\"');
|
792 |
+
MAP('\\', '\\');
|
793 |
+
MAP('/', '/');
|
794 |
+
MAP('b', '\b');
|
795 |
+
MAP('f', '\f');
|
796 |
+
MAP('n', '\n');
|
797 |
+
MAP('r', '\r');
|
798 |
+
MAP('t', '\t');
|
799 |
+
#undef MAP
|
800 |
+
case 'u':
|
801 |
+
if (! _parse_codepoint(out, in)) {
|
802 |
+
return false;
|
803 |
+
}
|
804 |
+
break;
|
805 |
+
default:
|
806 |
+
return false;
|
807 |
+
}
|
808 |
+
} else {
|
809 |
+
out.push_back(ch);
|
810 |
+
}
|
811 |
+
}
|
812 |
+
}
|
813 |
+
|
814 |
+
template <typename Context, typename Iter> inline bool _parse_array(Context& ctx, input<Iter>& in) {
|
815 |
+
if (! ctx.parse_array_start()) {
|
816 |
+
return false;
|
817 |
+
}
|
818 |
+
size_t idx = 0;
|
819 |
+
if (in.expect(']')) {
|
820 |
+
return ctx.parse_array_stop(idx);
|
821 |
+
}
|
822 |
+
do {
|
823 |
+
if (! ctx.parse_array_item(in, idx)) {
|
824 |
+
return false;
|
825 |
+
}
|
826 |
+
idx++;
|
827 |
+
} while (in.expect(','));
|
828 |
+
return in.expect(']') && ctx.parse_array_stop(idx);
|
829 |
+
}
|
830 |
+
|
831 |
+
template <typename Context, typename Iter> inline bool _parse_object(Context& ctx, input<Iter>& in) {
|
832 |
+
if (! ctx.parse_object_start()) {
|
833 |
+
return false;
|
834 |
+
}
|
835 |
+
if (in.expect('}')) {
|
836 |
+
return true;
|
837 |
+
}
|
838 |
+
do {
|
839 |
+
std::string key;
|
840 |
+
// Support " and ' delimited strings
|
841 |
+
if( in.expect('"') ) {
|
842 |
+
if( !_parse_string(key, in, '"') )
|
843 |
+
return false;
|
844 |
+
}else if (!in.expect('\'') || !_parse_string(key, in,'\'') ) {
|
845 |
+
return false;
|
846 |
+
}
|
847 |
+
if (!in.expect(':') || !ctx.parse_object_item(in, key)) {
|
848 |
+
return false;
|
849 |
+
}
|
850 |
+
} while (in.expect(','));
|
851 |
+
return in.expect('}');
|
852 |
+
}
|
853 |
+
|
854 |
+
template <typename Iter> inline std::string _parse_number(input<Iter>& in) {
|
855 |
+
std::string num_str;
|
856 |
+
while (1) {
|
857 |
+
int ch = in.getc();
|
858 |
+
if (('0' <= ch && ch <= '9') || ch == '+' || ch == '-'
|
859 |
+
|| ch == 'e' || ch == 'E') {
|
860 |
+
num_str.push_back(ch);
|
861 |
+
} else if (ch == '.') {
|
862 |
+
#if PICOJSON_USE_LOCALE
|
863 |
+
num_str += localeconv()->decimal_point;
|
864 |
+
#else
|
865 |
+
num_str.push_back('.');
|
866 |
+
#endif
|
867 |
+
} else {
|
868 |
+
in.ungetc();
|
869 |
+
break;
|
870 |
+
}
|
871 |
+
}
|
872 |
+
return num_str;
|
873 |
+
}
|
874 |
+
|
875 |
+
template <typename Context, typename Iter> inline bool _parse(Context& ctx, input<Iter>& in) {
|
876 |
+
in.skip_ws();
|
877 |
+
int ch = in.getc();
|
878 |
+
switch (ch) {
|
879 |
+
#define IS(ch, text, op) case ch: \
|
880 |
+
if (in.match(text) && op) { \
|
881 |
+
return true; \
|
882 |
+
} else { \
|
883 |
+
return false; \
|
884 |
+
}
|
885 |
+
IS('n', "ull", ctx.set_null());
|
886 |
+
IS('f', "alse", ctx.set_bool(false));
|
887 |
+
IS('t', "rue", ctx.set_bool(true));
|
888 |
+
#undef IS
|
889 |
+
case '"':
|
890 |
+
return ctx.parse_string(in);
|
891 |
+
case '[':
|
892 |
+
return _parse_array(ctx, in);
|
893 |
+
case '{':
|
894 |
+
return _parse_object(ctx, in);
|
895 |
+
default:
|
896 |
+
if (('0' <= ch && ch <= '9') || ch == '-') {
|
897 |
+
double f;
|
898 |
+
char *endp;
|
899 |
+
in.ungetc();
|
900 |
+
std::string num_str = _parse_number(in);
|
901 |
+
if (num_str.empty()) {
|
902 |
+
return false;
|
903 |
+
}
|
904 |
+
#ifdef PICOJSON_USE_INT64
|
905 |
+
{
|
906 |
+
errno = 0;
|
907 |
+
intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
|
908 |
+
if (errno == 0
|
909 |
+
&& std::numeric_limits<int64_t>::min() <= ival
|
910 |
+
&& ival <= std::numeric_limits<int64_t>::max()
|
911 |
+
&& endp == num_str.c_str() + num_str.size()) {
|
912 |
+
ctx.set_int64(ival);
|
913 |
+
return true;
|
914 |
+
}
|
915 |
+
}
|
916 |
+
#endif
|
917 |
+
f = strtod(num_str.c_str(), &endp);
|
918 |
+
if (endp == num_str.c_str() + num_str.size()) {
|
919 |
+
ctx.set_number(f);
|
920 |
+
return true;
|
921 |
+
}
|
922 |
+
return false;
|
923 |
+
}
|
924 |
+
break;
|
925 |
+
}
|
926 |
+
in.ungetc();
|
927 |
+
return false;
|
928 |
+
}
|
929 |
+
|
930 |
+
class deny_parse_context {
|
931 |
+
public:
|
932 |
+
bool set_null() { return false; }
|
933 |
+
bool set_bool(bool) { return false; }
|
934 |
+
#ifdef PICOJSON_USE_INT64
|
935 |
+
bool set_int64(int64_t) { return false; }
|
936 |
+
#endif
|
937 |
+
bool set_number(double) { return false; }
|
938 |
+
template <typename Iter> bool parse_string(input<Iter>&) { return false; }
|
939 |
+
bool parse_array_start() { return false; }
|
940 |
+
template <typename Iter> bool parse_array_item(input<Iter>&, size_t) {
|
941 |
+
return false;
|
942 |
+
}
|
943 |
+
bool parse_array_stop(size_t) { return false; }
|
944 |
+
bool parse_object_start() { return false; }
|
945 |
+
template <typename Iter> bool parse_object_item(input<Iter>&, const std::string&) {
|
946 |
+
return false;
|
947 |
+
}
|
948 |
+
};
|
949 |
+
|
950 |
+
class default_parse_context {
|
951 |
+
protected:
|
952 |
+
value* out_;
|
953 |
+
public:
|
954 |
+
default_parse_context(value* out) : out_(out) {}
|
955 |
+
bool set_null() {
|
956 |
+
*out_ = value();
|
957 |
+
return true;
|
958 |
+
}
|
959 |
+
bool set_bool(bool b) {
|
960 |
+
*out_ = value(b);
|
961 |
+
return true;
|
962 |
+
}
|
963 |
+
#ifdef PICOJSON_USE_INT64
|
964 |
+
bool set_int64(int64_t i) {
|
965 |
+
*out_ = value(i);
|
966 |
+
return true;
|
967 |
+
}
|
968 |
+
#endif
|
969 |
+
bool set_number(double f) {
|
970 |
+
*out_ = value(f);
|
971 |
+
return true;
|
972 |
+
}
|
973 |
+
template<typename Iter> bool parse_string(input<Iter>& in) {
|
974 |
+
*out_ = value(string_type, false);
|
975 |
+
return _parse_string(out_->get<std::string>(), in);
|
976 |
+
}
|
977 |
+
bool parse_array_start() {
|
978 |
+
*out_ = value(array_type, false);
|
979 |
+
return true;
|
980 |
+
}
|
981 |
+
template <typename Iter> bool parse_array_item(input<Iter>& in, size_t) {
|
982 |
+
array& a = out_->get<array>();
|
983 |
+
a.push_back(value());
|
984 |
+
default_parse_context ctx(&a.back());
|
985 |
+
return _parse(ctx, in);
|
986 |
+
}
|
987 |
+
bool parse_array_stop(size_t) { return true; }
|
988 |
+
bool parse_object_start() {
|
989 |
+
*out_ = value(object_type, false);
|
990 |
+
return true;
|
991 |
+
}
|
992 |
+
template <typename Iter> bool parse_object_item(input<Iter>& in, const std::string& key) {
|
993 |
+
object& o = out_->get<object>();
|
994 |
+
default_parse_context ctx(&o[key]);
|
995 |
+
return _parse(ctx, in);
|
996 |
+
}
|
997 |
+
private:
|
998 |
+
default_parse_context(const default_parse_context&);
|
999 |
+
default_parse_context& operator=(const default_parse_context&);
|
1000 |
+
};
|
1001 |
+
|
1002 |
+
class null_parse_context {
|
1003 |
+
public:
|
1004 |
+
struct dummy_str {
|
1005 |
+
void push_back(int) {}
|
1006 |
+
};
|
1007 |
+
public:
|
1008 |
+
null_parse_context() {}
|
1009 |
+
bool set_null() { return true; }
|
1010 |
+
bool set_bool(bool) { return true; }
|
1011 |
+
#ifdef PICOJSON_USE_INT64
|
1012 |
+
bool set_int64(int64_t) { return true; }
|
1013 |
+
#endif
|
1014 |
+
bool set_number(double) { return true; }
|
1015 |
+
template <typename Iter> bool parse_string(input<Iter>& in) {
|
1016 |
+
dummy_str s;
|
1017 |
+
return _parse_string(s, in);
|
1018 |
+
}
|
1019 |
+
bool parse_array_start() { return true; }
|
1020 |
+
template <typename Iter> bool parse_array_item(input<Iter>& in, size_t) {
|
1021 |
+
return _parse(*this, in);
|
1022 |
+
}
|
1023 |
+
bool parse_array_stop(size_t) { return true; }
|
1024 |
+
bool parse_object_start() { return true; }
|
1025 |
+
template <typename Iter> bool parse_object_item(input<Iter>& in, const std::string&) {
|
1026 |
+
return _parse(*this, in);
|
1027 |
+
}
|
1028 |
+
private:
|
1029 |
+
null_parse_context(const null_parse_context&);
|
1030 |
+
null_parse_context& operator=(const null_parse_context&);
|
1031 |
+
};
|
1032 |
+
|
1033 |
+
// obsolete, use the version below
|
1034 |
+
template <typename Iter> inline std::string parse(value& out, Iter& pos, const Iter& last) {
|
1035 |
+
std::string err;
|
1036 |
+
pos = parse(out, pos, last, &err);
|
1037 |
+
return err;
|
1038 |
+
}
|
1039 |
+
|
1040 |
+
template <typename Context, typename Iter> inline Iter _parse(Context& ctx, const Iter& first, const Iter& last, std::string* err) {
|
1041 |
+
input<Iter> in(first, last);
|
1042 |
+
if (! _parse(ctx, in) && err != NULL) {
|
1043 |
+
char buf[64];
|
1044 |
+
SNPRINTF(buf, sizeof(buf), "syntax error at line %d near: ", in.line());
|
1045 |
+
*err = buf;
|
1046 |
+
while (1) {
|
1047 |
+
int ch = in.getc();
|
1048 |
+
if (ch == -1 || ch == '\n') {
|
1049 |
+
break;
|
1050 |
+
} else if (ch >= ' ') {
|
1051 |
+
err->push_back(ch);
|
1052 |
+
}
|
1053 |
+
}
|
1054 |
+
}
|
1055 |
+
return in.cur();
|
1056 |
+
}
|
1057 |
+
|
1058 |
+
template <typename Iter> inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err) {
|
1059 |
+
default_parse_context ctx(&out);
|
1060 |
+
return _parse(ctx, first, last, err);
|
1061 |
+
}
|
1062 |
+
|
1063 |
+
inline std::string parse(value &out, const std::string &s) {
|
1064 |
+
std::string err;
|
1065 |
+
parse(out, s.begin(), s.end(), &err);
|
1066 |
+
return err;
|
1067 |
+
}
|
1068 |
+
|
1069 |
+
inline std::string parse(value& out, std::istream& is) {
|
1070 |
+
std::string err;
|
1071 |
+
parse(out, std::istreambuf_iterator<char>(is.rdbuf()),
|
1072 |
+
std::istreambuf_iterator<char>(), &err);
|
1073 |
+
return err;
|
1074 |
+
}
|
1075 |
+
|
1076 |
+
template <typename T> struct last_error_t {
|
1077 |
+
static std::string s;
|
1078 |
+
};
|
1079 |
+
template <typename T> std::string last_error_t<T>::s;
|
1080 |
+
|
1081 |
+
inline void set_last_error(const std::string& s) {
|
1082 |
+
last_error_t<bool>::s = s;
|
1083 |
+
}
|
1084 |
+
|
1085 |
+
inline const std::string& get_last_error() {
|
1086 |
+
return last_error_t<bool>::s;
|
1087 |
+
}
|
1088 |
+
|
1089 |
+
inline bool operator==(const value& x, const value& y) {
|
1090 |
+
if (x.is<null>())
|
1091 |
+
return y.is<null>();
|
1092 |
+
#define PICOJSON_CMP(type) \
|
1093 |
+
if (x.is<type>()) \
|
1094 |
+
return y.is<type>() && x.get<type>() == y.get<type>()
|
1095 |
+
PICOJSON_CMP(bool);
|
1096 |
+
PICOJSON_CMP(double);
|
1097 |
+
PICOJSON_CMP(std::string);
|
1098 |
+
PICOJSON_CMP(array);
|
1099 |
+
PICOJSON_CMP(object);
|
1100 |
+
#undef PICOJSON_CMP
|
1101 |
+
PICOJSON_ASSERT(0);
|
1102 |
+
#ifdef _MSC_VER
|
1103 |
+
__assume(0);
|
1104 |
+
#endif
|
1105 |
+
}
|
1106 |
+
|
1107 |
+
inline bool operator!=(const value& x, const value& y) {
|
1108 |
+
return ! (x == y);
|
1109 |
+
}
|
1110 |
+
|
1111 |
+
} // namespace json
|
1112 |
+
|
1113 |
+
inline std::istream& operator>>(std::istream& is, picojson::value& x)
|
1114 |
+
{
|
1115 |
+
picojson::set_last_error(std::string());
|
1116 |
+
std::string err = picojson::parse(x, is);
|
1117 |
+
if (! err.empty()) {
|
1118 |
+
picojson::set_last_error(err);
|
1119 |
+
is.setstate(std::ios::failbit);
|
1120 |
+
}
|
1121 |
+
return is;
|
1122 |
+
}
|
1123 |
+
|
1124 |
+
inline std::ostream& operator<<(std::ostream& os, const picojson::value& x)
|
1125 |
+
{
|
1126 |
+
x.serialize(std::ostream_iterator<char>(os));
|
1127 |
+
return os;
|
1128 |
+
}
|
1129 |
+
#ifdef _MSC_VER
|
1130 |
+
#pragma warning(pop)
|
1131 |
+
#endif // _MSC_VER
|
1132 |
+
|
1133 |
+
#endif // picojson_h
|
1134 |
+
|
1135 |
+
|
1136 |
+
|
1137 |
+
|
1138 |
+
#ifdef TEST_PICOJSON
|
1139 |
+
|
1140 |
+
#ifdef _MSC_VER
|
1141 |
+
#pragma warning(disable : 4127) // conditional expression is constant
|
1142 |
+
#endif // _MSC_VER
|
1143 |
+
|
1144 |
+
using namespace std;
|
1145 |
+
|
1146 |
+
static bool success = true;
|
1147 |
+
static int test_num = 0;
|
1148 |
+
|
1149 |
+
static void ok(bool b, const char* name = "")
|
1150 |
+
{
|
1151 |
+
if (! b)
|
1152 |
+
success = false;
|
1153 |
+
printf("%s %d - %s\n", b ? "ok" : "ng", ++test_num, name);
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
static void done_testing()
|
1157 |
+
{
|
1158 |
+
printf("1..%d\n", test_num);
|
1159 |
+
}
|
1160 |
+
|
1161 |
+
template <typename T> void is(const T& x, const T& y, const char* name = "")
|
1162 |
+
{
|
1163 |
+
if (x == y) {
|
1164 |
+
ok(true, name);
|
1165 |
+
} else {
|
1166 |
+
ok(false, name);
|
1167 |
+
}
|
1168 |
+
}
|
1169 |
+
|
1170 |
+
#include <algorithm>
|
1171 |
+
#include <sstream>
|
1172 |
+
#include <float.h>
|
1173 |
+
#include <limits.h>
|
1174 |
+
|
1175 |
+
int main(void)
|
1176 |
+
{
|
1177 |
+
#if PICOJSON_USE_LOCALE
|
1178 |
+
setlocale(LC_ALL, "");
|
1179 |
+
#endif // PICOJSON_USE_LOCALE
|
1180 |
+
|
1181 |
+
// constructors
|
1182 |
+
#define TEST(expr, expected) \
|
1183 |
+
is(picojson::value expr .serialize(), string(expected), "picojson::value" #expr)
|
1184 |
+
|
1185 |
+
TEST( (true), "true");
|
1186 |
+
TEST( (false), "false");
|
1187 |
+
TEST( (42.0), "42");
|
1188 |
+
TEST( (string("hello")), "\"hello\"");
|
1189 |
+
TEST( ("hello"), "\"hello\"");
|
1190 |
+
TEST( ("hello", 4), "\"hell\"");
|
1191 |
+
|
1192 |
+
{
|
1193 |
+
double a = 1;
|
1194 |
+
for (int i = 0; i < 1024; i++) {
|
1195 |
+
picojson::value vi(a);
|
1196 |
+
std::stringstream ss;
|
1197 |
+
ss << vi;
|
1198 |
+
picojson::value vo;
|
1199 |
+
ss >> vo;
|
1200 |
+
double b = vo.get<double>();
|
1201 |
+
if ((i < 53 && a != b) || fabs(a - b) / b > 1e-8) {
|
1202 |
+
printf("ng i=%d a=%.18e b=%.18e\n", i, a, b);
|
1203 |
+
}
|
1204 |
+
a *= 2;
|
1205 |
+
}
|
1206 |
+
}
|
1207 |
+
|
1208 |
+
#undef TEST
|
1209 |
+
|
1210 |
+
#define TEST(in, type, cmp, serialize_test) { \
|
1211 |
+
picojson::value v; \
|
1212 |
+
const char* s = in; \
|
1213 |
+
string err = picojson::parse(v, s, s + strlen(s)); \
|
1214 |
+
ok(err.empty(), in " no error"); \
|
1215 |
+
ok(v.is<type>(), in " check type"); \
|
1216 |
+
is<type>(v.get<type>(), cmp, in " correct output"); \
|
1217 |
+
is(*s, '\0', in " read to eof"); \
|
1218 |
+
if (serialize_test) { \
|
1219 |
+
is(v.serialize(), string(in), in " serialize"); \
|
1220 |
+
} \
|
1221 |
+
}
|
1222 |
+
TEST("false", bool, false, true);
|
1223 |
+
TEST("true", bool, true, true);
|
1224 |
+
TEST("90.5", double, 90.5, false);
|
1225 |
+
TEST("1.7976931348623157e+308", double, DBL_MAX, false);
|
1226 |
+
TEST("\"hello\"", string, string("hello"), true);
|
1227 |
+
TEST("\"\\\"\\\\\\/\\b\\f\\n\\r\\t\"", string, string("\"\\/\b\f\n\r\t"),
|
1228 |
+
true);
|
1229 |
+
TEST("\"\\u0061\\u30af\\u30ea\\u30b9\"", string,
|
1230 |
+
string("a\xe3\x82\xaf\xe3\x83\xaa\xe3\x82\xb9"), false);
|
1231 |
+
TEST("\"\\ud840\\udc0b\"", string, string("\xf0\xa0\x80\x8b"), false);
|
1232 |
+
#ifdef PICOJSON_USE_INT64
|
1233 |
+
TEST("0", int64_t, 0, true);
|
1234 |
+
TEST("-9223372036854775808", int64_t, std::numeric_limits<int64_t>::min(), true);
|
1235 |
+
TEST("9223372036854775807", int64_t, std::numeric_limits<int64_t>::max(), true);
|
1236 |
+
#endif // PICOJSON_USE_INT64
|
1237 |
+
|
1238 |
+
#undef TEST
|
1239 |
+
|
1240 |
+
#define TEST(type, expr) { \
|
1241 |
+
picojson::value v; \
|
1242 |
+
const char *s = expr; \
|
1243 |
+
string err = picojson::parse(v, s, s + strlen(s)); \
|
1244 |
+
ok(err.empty(), "empty " #type " no error"); \
|
1245 |
+
ok(v.is<picojson::type>(), "empty " #type " check type"); \
|
1246 |
+
ok(v.get<picojson::type>().empty(), "check " #type " array size"); \
|
1247 |
+
}
|
1248 |
+
TEST(array, "[]");
|
1249 |
+
TEST(object, "{}");
|
1250 |
+
#undef TEST
|
1251 |
+
|
1252 |
+
{
|
1253 |
+
picojson::value v;
|
1254 |
+
const char *s = "[1,true,\"hello\"]";
|
1255 |
+
string err = picojson::parse(v, s, s + strlen(s));
|
1256 |
+
ok(err.empty(), "array no error");
|
1257 |
+
ok(v.is<picojson::array>(), "array check type");
|
1258 |
+
is(v.get<picojson::array>().size(), size_t(3), "check array size");
|
1259 |
+
ok(v.contains(0), "check contains array[0]");
|
1260 |
+
ok(v.get(0).is<double>(), "check array[0] type");
|
1261 |
+
is(v.get(0).get<double>(), 1.0, "check array[0] value");
|
1262 |
+
ok(v.contains(1), "check contains array[1]");
|
1263 |
+
ok(v.get(1).is<bool>(), "check array[1] type");
|
1264 |
+
ok(v.get(1).get<bool>(), "check array[1] value");
|
1265 |
+
ok(v.contains(2), "check contains array[2]");
|
1266 |
+
ok(v.get(2).is<string>(), "check array[2] type");
|
1267 |
+
is(v.get(2).get<string>(), string("hello"), "check array[2] value");
|
1268 |
+
ok(!v.contains(3), "check not contains array[3]");
|
1269 |
+
}
|
1270 |
+
|
1271 |
+
{
|
1272 |
+
picojson::value v;
|
1273 |
+
const char *s = "{ \"a\": true }";
|
1274 |
+
string err = picojson::parse(v, s, s + strlen(s));
|
1275 |
+
ok(err.empty(), "object no error");
|
1276 |
+
ok(v.is<picojson::object>(), "object check type");
|
1277 |
+
is(v.get<picojson::object>().size(), size_t(1), "check object size");
|
1278 |
+
ok(v.contains("a"), "check contains property");
|
1279 |
+
ok(v.get("a").is<bool>(), "check bool property exists");
|
1280 |
+
is(v.get("a").get<bool>(), true, "check bool property value");
|
1281 |
+
is(v.serialize(), string("{\"a\":true}"), "serialize object");
|
1282 |
+
ok(!v.contains("z"), "check not contains property");
|
1283 |
+
}
|
1284 |
+
|
1285 |
+
#define TEST(json, msg) do { \
|
1286 |
+
picojson::value v; \
|
1287 |
+
const char *s = json; \
|
1288 |
+
string err = picojson::parse(v, s, s + strlen(s)); \
|
1289 |
+
is(err, string("syntax error at line " msg), msg); \
|
1290 |
+
} while (0)
|
1291 |
+
TEST("falsoa", "1 near: oa");
|
1292 |
+
TEST("{]", "1 near: ]");
|
1293 |
+
TEST("\n\bbell", "2 near: bell");
|
1294 |
+
TEST("\"abc\nd\"", "1 near: ");
|
1295 |
+
#undef TEST
|
1296 |
+
|
1297 |
+
{
|
1298 |
+
picojson::value v1, v2;
|
1299 |
+
const char *s;
|
1300 |
+
string err;
|
1301 |
+
s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
|
1302 |
+
err = picojson::parse(v1, s, s + strlen(s));
|
1303 |
+
s = "{ \"d\": 2.0, \"b\": true, \"a\": [1,2,\"three\"] }";
|
1304 |
+
err = picojson::parse(v2, s, s + strlen(s));
|
1305 |
+
ok((v1 == v2), "check == operator in deep comparison");
|
1306 |
+
}
|
1307 |
+
|
1308 |
+
{
|
1309 |
+
picojson::value v1, v2;
|
1310 |
+
const char *s;
|
1311 |
+
string err;
|
1312 |
+
s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
|
1313 |
+
err = picojson::parse(v1, s, s + strlen(s));
|
1314 |
+
s = "{ \"d\": 2.0, \"a\": [1,\"three\"], \"b\": true }";
|
1315 |
+
err = picojson::parse(v2, s, s + strlen(s));
|
1316 |
+
ok((v1 != v2), "check != operator for array in deep comparison");
|
1317 |
+
}
|
1318 |
+
|
1319 |
+
{
|
1320 |
+
picojson::value v1, v2;
|
1321 |
+
const char *s;
|
1322 |
+
string err;
|
1323 |
+
s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
|
1324 |
+
err = picojson::parse(v1, s, s + strlen(s));
|
1325 |
+
s = "{ \"d\": 2.0, \"a\": [1,2,\"three\"], \"b\": false }";
|
1326 |
+
err = picojson::parse(v2, s, s + strlen(s));
|
1327 |
+
ok((v1 != v2), "check != operator for object in deep comparison");
|
1328 |
+
}
|
1329 |
+
|
1330 |
+
{
|
1331 |
+
picojson::value v1, v2;
|
1332 |
+
const char *s;
|
1333 |
+
string err;
|
1334 |
+
s = "{ \"b\": true, \"a\": [1,2,\"three\"], \"d\": 2 }";
|
1335 |
+
err = picojson::parse(v1, s, s + strlen(s));
|
1336 |
+
picojson::object& o = v1.get<picojson::object>();
|
1337 |
+
o.erase("b");
|
1338 |
+
picojson::array& a = o["a"].get<picojson::array>();
|
1339 |
+
picojson::array::iterator i;
|
1340 |
+
i = std::remove(a.begin(), a.end(), picojson::value(std::string("three")));
|
1341 |
+
a.erase(i, a.end());
|
1342 |
+
s = "{ \"a\": [1,2], \"d\": 2 }";
|
1343 |
+
err = picojson::parse(v2, s, s + strlen(s));
|
1344 |
+
ok((v1 == v2), "check erase()");
|
1345 |
+
}
|
1346 |
+
|
1347 |
+
ok(picojson::value(3.0).serialize() == "3",
|
1348 |
+
"integral number should be serialized as a integer");
|
1349 |
+
|
1350 |
+
{
|
1351 |
+
const char* s = "{ \"a\": [1,2], \"d\": 2 }";
|
1352 |
+
picojson::null_parse_context ctx;
|
1353 |
+
string err;
|
1354 |
+
picojson::_parse(ctx, s, s + strlen(s), &err);
|
1355 |
+
ok(err.empty(), "null_parse_context");
|
1356 |
+
}
|
1357 |
+
|
1358 |
+
{
|
1359 |
+
picojson::value v;
|
1360 |
+
const char *s = "{ \"a\": 1, \"b\": [ 2, { \"b1\": \"abc\" } ], \"c\": {}, \"d\": [] }";
|
1361 |
+
string err;
|
1362 |
+
err = picojson::parse(v, s, s + strlen(s));
|
1363 |
+
ok(err.empty(), "parse test data for prettifying output");
|
1364 |
+
ok(v.serialize() == "{\"a\":1,\"b\":[2,{\"b1\":\"abc\"}],\"c\":{},\"d\":[]}", "non-prettifying output");
|
1365 |
+
ok(v.serialize(true) == "{\n \"a\": 1,\n \"b\": [\n 2,\n {\n \"b1\": \"abc\"\n }\n ],\n \"c\": {},\n \"d\": []\n}\n", "prettifying output");
|
1366 |
+
}
|
1367 |
+
|
1368 |
+
try {
|
1369 |
+
picojson::value v(std::numeric_limits<double>::quiet_NaN());
|
1370 |
+
ok(false, "should not accept NaN");
|
1371 |
+
} catch (std::overflow_error e) {
|
1372 |
+
ok(true, "should not accept NaN");
|
1373 |
+
}
|
1374 |
+
|
1375 |
+
try {
|
1376 |
+
picojson::value v(std::numeric_limits<double>::infinity());
|
1377 |
+
ok(false, "should not accept infinity");
|
1378 |
+
} catch (std::overflow_error e) {
|
1379 |
+
ok(true, "should not accept infinity");
|
1380 |
+
}
|
1381 |
+
|
1382 |
+
try {
|
1383 |
+
picojson::value v(123.);
|
1384 |
+
ok(! v.is<bool>(), "is<wrong_type>() should return false");
|
1385 |
+
v.get<bool>();
|
1386 |
+
ok(false, "get<wrong_type>() should raise an error");
|
1387 |
+
} catch (std::runtime_error e) {
|
1388 |
+
ok(true, "get<wrong_type>() should raise an error");
|
1389 |
+
}
|
1390 |
+
|
1391 |
+
#ifdef PICOJSON_USE_INT64
|
1392 |
+
{
|
1393 |
+
picojson::value v1((int64_t)123);
|
1394 |
+
ok(v1.is<int64_t>(), "is int64_t");
|
1395 |
+
ok(v1.is<double>(), "is double as well");
|
1396 |
+
ok(v1.serialize() == "123", "serialize the value");
|
1397 |
+
ok(v1.get<int64_t>() == 123, "value is correct as int64_t");
|
1398 |
+
ok(v1.get<double>(), "value is correct as double");
|
1399 |
+
|
1400 |
+
ok(! v1.is<int64_t>(), "is no more int64_type once get<double>() is called");
|
1401 |
+
ok(v1.is<double>(), "and is still a double");
|
1402 |
+
|
1403 |
+
const char *s = "-9223372036854775809";
|
1404 |
+
ok(picojson::parse(v1, s, s + strlen(s)).empty(), "parse underflowing int64_t");
|
1405 |
+
ok(! v1.is<int64_t>(), "underflowing int is not int64_t");
|
1406 |
+
ok(v1.is<double>(), "underflowing int is double");
|
1407 |
+
ok(v1.get<double>() + 9.22337203685478e+18 < 65536, "double value is somewhat correct");
|
1408 |
+
}
|
1409 |
+
#endif // PICOJSON_USE_INT64
|
1410 |
+
|
1411 |
+
done_testing();
|
1412 |
+
|
1413 |
+
return success ? 0 : 1;
|
1414 |
+
}
|
1415 |
+
|
1416 |
+
#endif // TEST_PICOJSON
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/posix/condition_variable.h
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <pangolin/utils/timer.h>
|
4 |
+
|
5 |
+
#include <memory>
|
6 |
+
|
7 |
+
namespace pangolin
|
8 |
+
{
|
9 |
+
|
10 |
+
class ConditionVariableInterface
|
11 |
+
{
|
12 |
+
public:
|
13 |
+
virtual ~ConditionVariableInterface()
|
14 |
+
{
|
15 |
+
}
|
16 |
+
|
17 |
+
virtual void wait() = 0;
|
18 |
+
virtual bool wait(timespec t) = 0;
|
19 |
+
virtual void signal() = 0;
|
20 |
+
virtual void broadcast() = 0;
|
21 |
+
};
|
22 |
+
|
23 |
+
std::shared_ptr<ConditionVariableInterface> create_named_condition_variable(const
|
24 |
+
std::string& name);
|
25 |
+
std::shared_ptr<ConditionVariableInterface> open_named_condition_variable(const
|
26 |
+
std::string& name);
|
27 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/posix/semaphore.h
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <memory>
|
4 |
+
|
5 |
+
#include <string>
|
6 |
+
|
7 |
+
namespace pangolin
|
8 |
+
{
|
9 |
+
|
10 |
+
class SemaphoreInterface
|
11 |
+
{
|
12 |
+
public:
|
13 |
+
|
14 |
+
virtual ~SemaphoreInterface() {
|
15 |
+
}
|
16 |
+
|
17 |
+
virtual bool tryAcquire() = 0;
|
18 |
+
virtual void acquire() = 0;
|
19 |
+
virtual void release() = 0;
|
20 |
+
};
|
21 |
+
|
22 |
+
std::shared_ptr<SemaphoreInterface> create_named_semaphore(const std::string& name,
|
23 |
+
unsigned int value);
|
24 |
+
std::shared_ptr<SemaphoreInterface> open_named_semaphore(const std::string& name);
|
25 |
+
|
26 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/posix/shared_memory_buffer.h
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <memory>
|
4 |
+
|
5 |
+
#include <string>
|
6 |
+
|
7 |
+
namespace pangolin
|
8 |
+
{
|
9 |
+
class SharedMemoryBufferInterface
|
10 |
+
{
|
11 |
+
public:
|
12 |
+
virtual ~SharedMemoryBufferInterface() {
|
13 |
+
}
|
14 |
+
virtual bool tryLock() = 0;
|
15 |
+
virtual void lock() = 0;
|
16 |
+
virtual void unlock() = 0;
|
17 |
+
virtual unsigned char *ptr() = 0;
|
18 |
+
virtual std::string name() = 0;
|
19 |
+
};
|
20 |
+
|
21 |
+
std::shared_ptr<SharedMemoryBufferInterface> create_named_shared_memory_buffer(const
|
22 |
+
std::string& name, size_t size);
|
23 |
+
std::shared_ptr<SharedMemoryBufferInterface> open_named_shared_memory_buffer(const
|
24 |
+
std::string& name, bool readwrite);
|
25 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/range.h
ADDED
@@ -0,0 +1,372 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <pangolin/platform.h>
|
31 |
+
|
32 |
+
#include <limits>
|
33 |
+
#include <algorithm>
|
34 |
+
#include <cmath>
|
35 |
+
|
36 |
+
//prevent including Eigen in cuda files
|
37 |
+
#if defined(HAVE_EIGEN) && !defined(__CUDACC__)
|
38 |
+
# define USE_EIGEN
|
39 |
+
#endif
|
40 |
+
|
41 |
+
#ifdef USE_EIGEN
|
42 |
+
# include <Eigen/Core>
|
43 |
+
# include <Eigen/Geometry>
|
44 |
+
#endif // USE_EIGEN
|
45 |
+
|
46 |
+
namespace pangolin
|
47 |
+
{
|
48 |
+
|
49 |
+
|
50 |
+
template<typename T>
|
51 |
+
struct Range
|
52 |
+
{
|
53 |
+
static Range<T> Open()
|
54 |
+
{
|
55 |
+
return Range<T>(std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
|
56 |
+
}
|
57 |
+
|
58 |
+
static Range<T> Empty()
|
59 |
+
{
|
60 |
+
return Range<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::lowest());
|
61 |
+
}
|
62 |
+
|
63 |
+
static Range<T> Containing(T val)
|
64 |
+
{
|
65 |
+
return Range<T>(val, val);
|
66 |
+
}
|
67 |
+
|
68 |
+
Range()
|
69 |
+
: min(+std::numeric_limits<T>::max()),
|
70 |
+
max(-std::numeric_limits<T>::max())
|
71 |
+
{
|
72 |
+
}
|
73 |
+
|
74 |
+
Range(T rmin, T rmax)
|
75 |
+
: min(rmin), max(rmax)
|
76 |
+
{
|
77 |
+
}
|
78 |
+
|
79 |
+
Range operator+(T v)
|
80 |
+
{
|
81 |
+
return Range(min+v, max+v);
|
82 |
+
}
|
83 |
+
|
84 |
+
Range operator-(T v)
|
85 |
+
{
|
86 |
+
return Range(min-v, max-v);
|
87 |
+
}
|
88 |
+
|
89 |
+
Range& operator+=(T v)
|
90 |
+
{
|
91 |
+
min += v;
|
92 |
+
max += v;
|
93 |
+
return *this;
|
94 |
+
}
|
95 |
+
|
96 |
+
Range& operator-=(T v)
|
97 |
+
{
|
98 |
+
min -= v;
|
99 |
+
max -= v;
|
100 |
+
return *this;
|
101 |
+
}
|
102 |
+
|
103 |
+
Range& operator*=(T v)
|
104 |
+
{
|
105 |
+
min *= v;
|
106 |
+
max *= v;
|
107 |
+
return *this;
|
108 |
+
}
|
109 |
+
|
110 |
+
Range& operator/=(T v)
|
111 |
+
{
|
112 |
+
min /= v;
|
113 |
+
max /= v;
|
114 |
+
return *this;
|
115 |
+
}
|
116 |
+
|
117 |
+
Range& operator+=(const Range& o)
|
118 |
+
{
|
119 |
+
min += o.min;
|
120 |
+
max += o.max;
|
121 |
+
return *this;
|
122 |
+
}
|
123 |
+
|
124 |
+
Range& operator-=(const Range& o)
|
125 |
+
{
|
126 |
+
min -= o.min;
|
127 |
+
max -= o.max;
|
128 |
+
return *this;
|
129 |
+
}
|
130 |
+
|
131 |
+
Range operator+(const Range& o) const
|
132 |
+
{
|
133 |
+
return Range(min + o.min, max + o.max);
|
134 |
+
}
|
135 |
+
|
136 |
+
Range operator-(const Range& o) const
|
137 |
+
{
|
138 |
+
return Range(min - o.min, max - o.max);
|
139 |
+
}
|
140 |
+
|
141 |
+
Range operator*(float s) const
|
142 |
+
{
|
143 |
+
return Range(T(s*min), T(s*max));
|
144 |
+
}
|
145 |
+
|
146 |
+
T Size() const
|
147 |
+
{
|
148 |
+
return max - min;
|
149 |
+
}
|
150 |
+
|
151 |
+
T AbsSize() const
|
152 |
+
{
|
153 |
+
return std::abs(Size());
|
154 |
+
}
|
155 |
+
|
156 |
+
T Mid() const
|
157 |
+
{
|
158 |
+
return (min + max) / (T)2.0f;
|
159 |
+
}
|
160 |
+
|
161 |
+
void Scale(float s, float center = 0.0f)
|
162 |
+
{
|
163 |
+
min = T(s*(min-center) + center);
|
164 |
+
max = T(s*(max-center) + center);
|
165 |
+
}
|
166 |
+
|
167 |
+
void Insert(T v)
|
168 |
+
{
|
169 |
+
min = std::min(min,v);
|
170 |
+
max = std::max(max,v);
|
171 |
+
}
|
172 |
+
|
173 |
+
void Insert(const Range<T>& r)
|
174 |
+
{
|
175 |
+
Insert(r.min);
|
176 |
+
Insert(r.max);
|
177 |
+
}
|
178 |
+
|
179 |
+
void Clamp(T vmin, T vmax)
|
180 |
+
{
|
181 |
+
min = std::min(std::max(vmin, min), vmax);
|
182 |
+
max = std::min(std::max(vmin, max), vmax);
|
183 |
+
}
|
184 |
+
|
185 |
+
void Clamp(const Range& o)
|
186 |
+
{
|
187 |
+
Clamp(o.min, o.max);
|
188 |
+
}
|
189 |
+
|
190 |
+
void Clear()
|
191 |
+
{
|
192 |
+
min = std::numeric_limits<T>::max();
|
193 |
+
max = std::numeric_limits<T>::lowest();
|
194 |
+
}
|
195 |
+
|
196 |
+
bool Contains(T v) const
|
197 |
+
{
|
198 |
+
return min <= v && v <= max;
|
199 |
+
}
|
200 |
+
|
201 |
+
bool ContainsWeak(T v) const
|
202 |
+
{
|
203 |
+
return (min <= v && v <= max)
|
204 |
+
|| (max <= v && v <= min);
|
205 |
+
}
|
206 |
+
|
207 |
+
template<typename To>
|
208 |
+
Range<To> Cast() const
|
209 |
+
{
|
210 |
+
return Range<To>(To(min), To(max));
|
211 |
+
}
|
212 |
+
|
213 |
+
T min;
|
214 |
+
T max;
|
215 |
+
};
|
216 |
+
|
217 |
+
template<typename T>
|
218 |
+
struct XYRange
|
219 |
+
{
|
220 |
+
static XYRange<T> Open()
|
221 |
+
{
|
222 |
+
return XYRange<T>(
|
223 |
+
Range<T>(std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max()),
|
224 |
+
Range<T>(std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max())
|
225 |
+
);
|
226 |
+
}
|
227 |
+
|
228 |
+
static XYRange<T> Empty()
|
229 |
+
{
|
230 |
+
return XYRange<T>(
|
231 |
+
Range<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::lowest()),
|
232 |
+
Range<T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::lowest())
|
233 |
+
);
|
234 |
+
}
|
235 |
+
|
236 |
+
static XYRange<T> Containing(T x, T y)
|
237 |
+
{
|
238 |
+
return XYRange<T>(
|
239 |
+
Range<T>(x, x),
|
240 |
+
Range<T>(y, y)
|
241 |
+
);
|
242 |
+
}
|
243 |
+
|
244 |
+
XYRange()
|
245 |
+
{
|
246 |
+
}
|
247 |
+
|
248 |
+
XYRange(const Range<T>& xrange, const Range<T>& yrange)
|
249 |
+
: x(xrange), y(yrange)
|
250 |
+
{
|
251 |
+
}
|
252 |
+
|
253 |
+
XYRange(T xmin, T xmax, T ymin, T ymax)
|
254 |
+
: x(xmin,xmax), y(ymin,ymax)
|
255 |
+
{
|
256 |
+
}
|
257 |
+
|
258 |
+
XYRange operator-(const XYRange& o) const
|
259 |
+
{
|
260 |
+
return XYRange(x - o.x, y - o.y);
|
261 |
+
}
|
262 |
+
|
263 |
+
XYRange operator*(float s) const
|
264 |
+
{
|
265 |
+
return XYRange(x*s, y*s);
|
266 |
+
}
|
267 |
+
|
268 |
+
XYRange& operator+=(const XYRange& o)
|
269 |
+
{
|
270 |
+
x += o.x;
|
271 |
+
y += o.y;
|
272 |
+
return *this;
|
273 |
+
}
|
274 |
+
|
275 |
+
void Scale(float sx, float sy, float centerx, float centery)
|
276 |
+
{
|
277 |
+
x.Scale(sx, centerx);
|
278 |
+
y.Scale(sy, centery);
|
279 |
+
}
|
280 |
+
|
281 |
+
void Clear()
|
282 |
+
{
|
283 |
+
x.Clear();
|
284 |
+
y.Clear();
|
285 |
+
}
|
286 |
+
|
287 |
+
void Clamp(T xmin, T xmax, T ymin, T ymax)
|
288 |
+
{
|
289 |
+
x.Clamp(xmin,xmax);
|
290 |
+
y.Clamp(ymin,ymax);
|
291 |
+
}
|
292 |
+
|
293 |
+
void Clamp(const XYRange& o)
|
294 |
+
{
|
295 |
+
x.Clamp(o.x);
|
296 |
+
y.Clamp(o.y);
|
297 |
+
}
|
298 |
+
|
299 |
+
void Insert(T xval, T yval)
|
300 |
+
{
|
301 |
+
x.Insert(xval);
|
302 |
+
y.Insert(yval);
|
303 |
+
}
|
304 |
+
|
305 |
+
void Insert(XYRange<T> r)
|
306 |
+
{
|
307 |
+
x.Insert(r.x);
|
308 |
+
y.Insert(r.y);
|
309 |
+
}
|
310 |
+
|
311 |
+
float Area() const
|
312 |
+
{
|
313 |
+
return x.Size() * y.Size();
|
314 |
+
}
|
315 |
+
|
316 |
+
bool Contains(float px, float py) const
|
317 |
+
{
|
318 |
+
return x.Contains(px) && y.Contains(py);
|
319 |
+
}
|
320 |
+
|
321 |
+
bool ContainsWeak(float px, float py) const
|
322 |
+
{
|
323 |
+
return x.ContainsWeak(px) && y.ContainsWeak(py);
|
324 |
+
}
|
325 |
+
|
326 |
+
template<typename To>
|
327 |
+
XYRange<To> Cast() const
|
328 |
+
{
|
329 |
+
return XYRange<To>(
|
330 |
+
x.template Cast<To>(),
|
331 |
+
y.template Cast<To>()
|
332 |
+
);
|
333 |
+
}
|
334 |
+
|
335 |
+
#ifdef USE_EIGEN
|
336 |
+
operator Eigen::AlignedBox<T,2>() const {
|
337 |
+
return Eigen::AlignedBox<T,2>(
|
338 |
+
Eigen::Matrix<T,2,1>(x.min, y.min),
|
339 |
+
Eigen::Matrix<T,2,1>(x.max, y.max)
|
340 |
+
);
|
341 |
+
}
|
342 |
+
|
343 |
+
Eigen::Matrix<T,2,1> Center() const {
|
344 |
+
return Eigen::Matrix<T,2,1>(x.Mid(), y.Mid());
|
345 |
+
}
|
346 |
+
#endif
|
347 |
+
|
348 |
+
Range<T> x;
|
349 |
+
Range<T> y;
|
350 |
+
};
|
351 |
+
|
352 |
+
typedef Range<int> Rangei;
|
353 |
+
typedef Range<float> Rangef;
|
354 |
+
typedef Range<double> Ranged;
|
355 |
+
|
356 |
+
typedef XYRange<int> XYRangei;
|
357 |
+
typedef XYRange<float> XYRangef;
|
358 |
+
typedef XYRange<double> XYRanged;
|
359 |
+
|
360 |
+
template<typename T> inline
|
361 |
+
Rangei Round(const Range<T>& r)
|
362 |
+
{
|
363 |
+
return Rangei( int(r.min+0.5), int(r.max+0.5) );
|
364 |
+
}
|
365 |
+
|
366 |
+
template<typename T> inline
|
367 |
+
XYRangei Round(const XYRange<T>& r)
|
368 |
+
{
|
369 |
+
return XYRangei( Round(r.x), Round(r.y) );
|
370 |
+
}
|
371 |
+
|
372 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/signal_slot.h
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <sigslot/signal.hpp>
|
4 |
+
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/sigstate.h
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <map>
|
31 |
+
#include <vector>
|
32 |
+
#include <pangolin/platform.h>
|
33 |
+
#include <pangolin/utils/file_utils.h>
|
34 |
+
#include <csignal>
|
35 |
+
|
36 |
+
#ifndef SIGPIPE
|
37 |
+
# define SIGPIPE 13
|
38 |
+
#endif // !SIGPIPE
|
39 |
+
|
40 |
+
namespace pangolin
|
41 |
+
{
|
42 |
+
|
43 |
+
typedef void (*SigCallbackFn)(int);
|
44 |
+
|
45 |
+
struct PANGOLIN_EXPORT SigCallback
|
46 |
+
{
|
47 |
+
SigCallback(const int & sig, SigCallbackFn fn, void* data)
|
48 |
+
: sig(sig), fn(fn), data(data), value(false)
|
49 |
+
{
|
50 |
+
std::signal(sig, fn);
|
51 |
+
}
|
52 |
+
|
53 |
+
int sig;
|
54 |
+
SigCallbackFn fn;
|
55 |
+
void * data;
|
56 |
+
volatile sig_atomic_t value;
|
57 |
+
};
|
58 |
+
|
59 |
+
class PANGOLIN_EXPORT SigState
|
60 |
+
{
|
61 |
+
public:
|
62 |
+
static SigState& I();
|
63 |
+
|
64 |
+
SigState();
|
65 |
+
~SigState();
|
66 |
+
|
67 |
+
void Clear();
|
68 |
+
|
69 |
+
std::map<int, SigCallback> sig_callbacks;
|
70 |
+
};
|
71 |
+
|
72 |
+
PANGOLIN_EXPORT
|
73 |
+
void RegisterNewSigCallback(SigCallbackFn callback, void* data, const int signal);
|
74 |
+
|
75 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/simple_math.h
ADDED
@@ -0,0 +1,446 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <iostream>
|
31 |
+
#include <string.h>
|
32 |
+
#include <algorithm>
|
33 |
+
#include <stdarg.h>
|
34 |
+
#include <cmath>
|
35 |
+
|
36 |
+
namespace pangolin
|
37 |
+
{
|
38 |
+
|
39 |
+
static const double Identity3d[] = {1,0,0, 0,1,0, 0,0,1};
|
40 |
+
static const double Zero3d[] = {0,0,0, 0,0,0, 0,0,0};
|
41 |
+
static const double Identity4d[] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
|
42 |
+
static const double Zero4d[] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
|
43 |
+
|
44 |
+
static const float Identity3f[] = {1,0,0, 0,1,0, 0,0,1};
|
45 |
+
static const float Zero3f[] = {0,0,0, 0,0,0, 0,0,0};
|
46 |
+
static const float Identity4f[] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};
|
47 |
+
static const float Zero4f[] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
|
48 |
+
|
49 |
+
template<int R, int C, typename P>
|
50 |
+
void MatPrint(const P m[R*C])
|
51 |
+
{
|
52 |
+
for( int r=0; r < R; ++r)
|
53 |
+
{
|
54 |
+
for( int c=0; c < C; ++c )
|
55 |
+
std::cout << m[R*c+r] << " ";
|
56 |
+
std::cout << std::endl;
|
57 |
+
}
|
58 |
+
std::cout << std::endl;
|
59 |
+
}
|
60 |
+
|
61 |
+
template<int R, int C, typename P>
|
62 |
+
void MatPrint(const P m[R*C], std::string name)
|
63 |
+
{
|
64 |
+
std::cout << name << " = [" << std::endl;
|
65 |
+
for( int r=0; r < R; ++r)
|
66 |
+
{
|
67 |
+
for( int c=0; c < C; ++c )
|
68 |
+
std::cout << m[R*c+r] << " ";
|
69 |
+
std::cout << std::endl;
|
70 |
+
}
|
71 |
+
std::cout << std::endl << "]" << std::endl;
|
72 |
+
}
|
73 |
+
|
74 |
+
// Set array using varadic arguments
|
75 |
+
template<int R, int C, typename P>
|
76 |
+
void MatSet(P m[R*C], ...)
|
77 |
+
{
|
78 |
+
va_list ap;
|
79 |
+
va_start(ap,m);
|
80 |
+
for( int i=0; i< R*C; ++i )
|
81 |
+
{
|
82 |
+
*m = (P)va_arg(ap,double);
|
83 |
+
++m;
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
// m = zeroes(N)
|
88 |
+
template<int R, int C, typename P>
|
89 |
+
void SetZero(P m[R*C] )
|
90 |
+
{
|
91 |
+
std::fill_n(m,R*C,0);
|
92 |
+
}
|
93 |
+
|
94 |
+
// m = identity(N)
|
95 |
+
template<int N, typename P>
|
96 |
+
void SetIdentity(P m[N*N] )
|
97 |
+
{
|
98 |
+
std::fill_n(m,N*N,0);
|
99 |
+
for( int i=0; i< N; ++i )
|
100 |
+
m[N*i+i] = 1;
|
101 |
+
}
|
102 |
+
|
103 |
+
// mo = m1 * m2
|
104 |
+
template<int R, int M, int C, typename P>
|
105 |
+
void MatMul(P mo[R*C], const P m1[R*M], const P m2[M*C] )
|
106 |
+
{
|
107 |
+
for( int r=0; r < R; ++r)
|
108 |
+
for( int c=0; c < C; ++c )
|
109 |
+
{
|
110 |
+
mo[R*c+r] = 0;
|
111 |
+
for( int m=0; m < M; ++ m) mo[R*c+r] += m1[R*m+r] * m2[M*c+m];
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
// mo = m1 * m2 * s
|
116 |
+
template<int R, int M, int C, typename P>
|
117 |
+
void MatMul(P mo[R*C], const P m1[R*M], const P m2[M*C], P s )
|
118 |
+
{
|
119 |
+
for( int r=0; r < R; ++r)
|
120 |
+
for( int c=0; c < C; ++c )
|
121 |
+
{
|
122 |
+
mo[R*c+r] = 0;
|
123 |
+
for( int m=0; m < M; ++ m) mo[R*c+r] += m1[R*m+r] * m2[M*c+m] * s;
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
// mo = m1 * transpose(m2)
|
128 |
+
template<int R, int M, int C, typename P>
|
129 |
+
void MatMulTranspose(P mo[R*C], const P m1[R*M], const P m2[C*M] )
|
130 |
+
{
|
131 |
+
for( int r=0; r < R; ++r)
|
132 |
+
for( int c=0; c < C; ++c )
|
133 |
+
{
|
134 |
+
mo[R*c+r] = 0;
|
135 |
+
for( int m=0; m < M; ++ m) mo[R*c+r] += m1[R*m+r] * m2[C*m+c];
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
// m = m1 + m2
|
140 |
+
template<int R, int C, typename P>
|
141 |
+
void MatAdd(P m[R*C], const P m1[R*C], const P m2[R*C])
|
142 |
+
{
|
143 |
+
for( int i=0; i< R*C; ++i )
|
144 |
+
m[i] = m1[i] + m2[i];
|
145 |
+
}
|
146 |
+
|
147 |
+
// m = m1 - m2
|
148 |
+
template<int R, int C, typename P>
|
149 |
+
void MatSub(P m[R*C], const P m1[R*C], const P m2[R*C])
|
150 |
+
{
|
151 |
+
for( int i=0; i< R*C; ++i )
|
152 |
+
m[i] = m1[i] - m2[i];
|
153 |
+
}
|
154 |
+
|
155 |
+
// m = m1 * scalar
|
156 |
+
template<int R, int C, typename P>
|
157 |
+
void MatMul(P m[R*C], const P m1[R*C], P scalar)
|
158 |
+
{
|
159 |
+
for( int i=0; i< R*C; ++i )
|
160 |
+
m[i] = m1[i] * scalar;
|
161 |
+
}
|
162 |
+
|
163 |
+
// m = m1 + m2
|
164 |
+
template<int R, int C, typename P>
|
165 |
+
void MatMul(P m[R*C], P scalar)
|
166 |
+
{
|
167 |
+
for( int i=0; i< R*C; ++i )
|
168 |
+
m[i] *= scalar;
|
169 |
+
}
|
170 |
+
|
171 |
+
template<int N, typename P>
|
172 |
+
void MatTranspose(P out[N*N], const P in[N*N] )
|
173 |
+
{
|
174 |
+
for( int c=0; c<N; ++c )
|
175 |
+
for( int r=0; r<N; ++r )
|
176 |
+
out[N*c+r] = in[N*r+c];
|
177 |
+
}
|
178 |
+
|
179 |
+
template<int N, typename P>
|
180 |
+
void MatTranspose(P m[N*N] )
|
181 |
+
{
|
182 |
+
for( int c=0; c<N; ++c )
|
183 |
+
for( int r=0; r<c; ++r )
|
184 |
+
std::swap<P>(m[N*c+r],m[N*r+c]);
|
185 |
+
}
|
186 |
+
|
187 |
+
// m = a x b
|
188 |
+
template<typename P>
|
189 |
+
void VecCross3(P m[3], const P a[3], const P b[3])
|
190 |
+
{
|
191 |
+
m[0] = a[1]*b[2] - a[2]*b[1];
|
192 |
+
m[1] = a[2]*b[0] - a[0]*b[2];
|
193 |
+
m[2] = a[0]*b[1] - a[1]*b[0];
|
194 |
+
}
|
195 |
+
|
196 |
+
// s = skewSymetrixMatrix(v)
|
197 |
+
template<typename P>
|
198 |
+
void MatSkew(P s[3*3], const P v[3] )
|
199 |
+
{
|
200 |
+
s[0] = 0;
|
201 |
+
s[1] = v[2];
|
202 |
+
s[2] = -v[1];
|
203 |
+
s[3] = -v[2];
|
204 |
+
s[4] = 0;
|
205 |
+
s[5] = v[0];
|
206 |
+
s[6] = v[1];
|
207 |
+
s[7] = -v[0];
|
208 |
+
s[8] = 0;
|
209 |
+
}
|
210 |
+
|
211 |
+
template<int N, typename P>
|
212 |
+
void MatOrtho( P m[N*N] )
|
213 |
+
{
|
214 |
+
// http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/index.htm
|
215 |
+
P Itimes3[N*N];
|
216 |
+
SetIdentity<N>(Itimes3);
|
217 |
+
MatMul<N,N>(Itimes3,(P)3.0);
|
218 |
+
|
219 |
+
P mmT[N*N];
|
220 |
+
MatMulTranspose<N,N,N>(mmT,m,m);
|
221 |
+
|
222 |
+
P _c[N*N];
|
223 |
+
MatSub<N,N>(_c,Itimes3,mmT);
|
224 |
+
P _m[N*N];
|
225 |
+
MatMul<N,N,N>(_m,m,_c,(P)0.5);
|
226 |
+
std::copy(_m,_m+(N*N),m);
|
227 |
+
}
|
228 |
+
|
229 |
+
template<typename P>
|
230 |
+
void Rotation(P R[3*3], P x, P y, P z)
|
231 |
+
{
|
232 |
+
P sx = sin(x);
|
233 |
+
P sy = sin(y);
|
234 |
+
P sz = sin(z);
|
235 |
+
P cx = cos(x);
|
236 |
+
P cy = cos(y);
|
237 |
+
P cz = cos(z);
|
238 |
+
// P cx = sqrt( (P)1.0 - sx * sx);
|
239 |
+
// P cy = sqrt( (P)1.0 - sy * sy);
|
240 |
+
// P cz = sqrt( (P)1.0 - sz * sz);
|
241 |
+
R[0] = cy * cz;
|
242 |
+
R[1] = sx * sy * cz + cx * sz;
|
243 |
+
R[2] = -cx * sy * cz + sx * sz;
|
244 |
+
R[3] = -cy * sz;
|
245 |
+
R[4] = -sx * sy * sz + cx * cz;
|
246 |
+
R[5] = cx * sy * sz + sx * cz;
|
247 |
+
R[6] = sy;
|
248 |
+
R[7] = -sx * cy;
|
249 |
+
R[8] = cx * cy;
|
250 |
+
}
|
251 |
+
|
252 |
+
template<typename P>
|
253 |
+
void LieSetIdentity(P T_ba[3*4] )
|
254 |
+
{
|
255 |
+
SetIdentity<3>(T_ba);
|
256 |
+
std::fill_n(T_ba+(3*3),3,0);
|
257 |
+
}
|
258 |
+
|
259 |
+
template<typename P>
|
260 |
+
void LieSetRotation(P T_ba[3*4], const P R_ba[3*3] )
|
261 |
+
{
|
262 |
+
std::copy(R_ba,R_ba+(3*3),T_ba);
|
263 |
+
}
|
264 |
+
|
265 |
+
template<typename P>
|
266 |
+
void LieSetTranslation(P T_ba[3*4], const P a_b[3] )
|
267 |
+
{
|
268 |
+
std::copy(a_b, a_b+3, T_ba+(3*3));
|
269 |
+
}
|
270 |
+
|
271 |
+
template<typename P>
|
272 |
+
void LieSetSE3(P T_ba[3*4], const P R_ba[3*3], const P a_b[3] )
|
273 |
+
{
|
274 |
+
LieSetRotation<P>(T_ba,R_ba);
|
275 |
+
LieSetTranslation<P>(T_ba,a_b);
|
276 |
+
}
|
277 |
+
|
278 |
+
template<typename P>
|
279 |
+
void LieGetRotation(P R_ba[3*3], const P T_ba[3*4] )
|
280 |
+
{
|
281 |
+
std::copy(T_ba,T_ba+(3*3),R_ba);
|
282 |
+
}
|
283 |
+
|
284 |
+
template<typename P>
|
285 |
+
void LieApplySO3( P out[3], const P R_ba[3*3], const P in[3] )
|
286 |
+
{
|
287 |
+
MatMul<3,3,1,P>(out,R_ba,in);
|
288 |
+
}
|
289 |
+
|
290 |
+
template<typename P>
|
291 |
+
void LieApplySE3vec( P x_b[3], const P T_ba[3*4], const P x_a[3] )
|
292 |
+
{
|
293 |
+
P rot[3];
|
294 |
+
MatMul<3,3,1,P>(rot,T_ba,x_a);
|
295 |
+
MatAdd<3,1,P>(x_b,rot,T_ba+(3*3));
|
296 |
+
}
|
297 |
+
|
298 |
+
template<typename P>
|
299 |
+
void LieApplySE34x4vec3( P x_b[3], const P T_ba[4*4], const P x_a[3] )
|
300 |
+
{
|
301 |
+
x_b[0] = T_ba[0]*x_a[0] + T_ba[4]*x_a[1] + T_ba[8]*x_a[2] + T_ba[12];
|
302 |
+
x_b[1] = T_ba[1]*x_a[0] + T_ba[5]*x_a[1] + T_ba[9]*x_a[2] + T_ba[13];
|
303 |
+
x_b[2] = T_ba[2]*x_a[0] + T_ba[6]*x_a[1] + T_ba[10]*x_a[2] + T_ba[14];
|
304 |
+
}
|
305 |
+
|
306 |
+
template<typename P>
|
307 |
+
void LieMulSO3( P R_ca[3*3], const P R_cb[3*3], const P R_ba[3*3] )
|
308 |
+
{
|
309 |
+
MatMul<3,3,3>(R_ca,R_cb,R_ba);
|
310 |
+
}
|
311 |
+
|
312 |
+
template<typename P>
|
313 |
+
void LieMulSE3( P T_ca[3*4], const P T_cb[3*4], const P T_ba[3*4] )
|
314 |
+
{
|
315 |
+
LieMulSO3<>(T_ca,T_cb,T_ba);
|
316 |
+
P R_cb_times_a_b[3];
|
317 |
+
LieApplySO3<>(R_cb_times_a_b,T_cb,T_ba+(3*3));
|
318 |
+
MatAdd<3,1>(T_ca+(3*3),R_cb_times_a_b,T_cb+(3*3));
|
319 |
+
}
|
320 |
+
|
321 |
+
template<typename P>
|
322 |
+
void LiePutSE3in4x4(P out[4*4], const P in[3*4] )
|
323 |
+
{
|
324 |
+
SetIdentity<4>(out);
|
325 |
+
std::copy(in,in+3, out);
|
326 |
+
std::copy(in+3,in+6, out+4);
|
327 |
+
std::copy(in+6,in+9, out+8);
|
328 |
+
std::copy(in+9,in+12, out+12);
|
329 |
+
}
|
330 |
+
|
331 |
+
template<typename P>
|
332 |
+
void LieSE3from4x4(P out[3*4], const P in[4*4] )
|
333 |
+
{
|
334 |
+
std::copy(in,in+3, out);
|
335 |
+
std::copy(in+4,in+7, out+3);
|
336 |
+
std::copy(in+8,in+11, out+6);
|
337 |
+
std::copy(in+12,in+15, out+9);
|
338 |
+
}
|
339 |
+
|
340 |
+
template<typename P>
|
341 |
+
void LieMul4x4bySE3( P T_ca[4*4], const P T_cb[3*4], const P T_ba[4*4] )
|
342 |
+
{
|
343 |
+
// TODO: fast
|
344 |
+
P T_cb4[4*4];
|
345 |
+
LiePutSE3in4x4<>(T_cb4,T_cb);
|
346 |
+
P res[4*4];
|
347 |
+
MatMul<4,4,4>(res,T_cb4,T_ba);
|
348 |
+
std::copy(res,res+(4*4),T_ca);
|
349 |
+
}
|
350 |
+
|
351 |
+
template<typename P>
|
352 |
+
void LieTransposeSO3( P R_ab[3*3], const P R_ba[3*3] )
|
353 |
+
{
|
354 |
+
MatTranspose<3,P>(R_ab,R_ba);
|
355 |
+
}
|
356 |
+
|
357 |
+
template<typename P>
|
358 |
+
void LieInverseSE3( P T_ab[3*4], const P T_ba[3*4] )
|
359 |
+
{
|
360 |
+
LieTransposeSO3<P>(T_ab,T_ba);
|
361 |
+
P minus_b_a[3];
|
362 |
+
LieApplySO3(minus_b_a, T_ab, T_ba+(3*3));
|
363 |
+
MatMul<3,1,P>(T_ab+(3*3),minus_b_a, -1);
|
364 |
+
}
|
365 |
+
|
366 |
+
// c = a x b
|
367 |
+
template<typename P>
|
368 |
+
void CrossProduct( P c[3], const P a[3], const P b[3] )
|
369 |
+
{
|
370 |
+
c[0] = a[1] * b[2] - a[2] * b[1];
|
371 |
+
c[1] = a[2] * b[0] - a[0] * b[2];
|
372 |
+
c[2] = a[0] * b[1] - a[1] * b[0];
|
373 |
+
}
|
374 |
+
|
375 |
+
template<int R, typename P>
|
376 |
+
P Length( P v[R] )
|
377 |
+
{
|
378 |
+
P sum_sq = 0;
|
379 |
+
|
380 |
+
for(size_t r = 0; r < R; ++r ) {
|
381 |
+
sum_sq += v[r] * v[r];
|
382 |
+
}
|
383 |
+
|
384 |
+
return sqrt(sum_sq);
|
385 |
+
}
|
386 |
+
|
387 |
+
|
388 |
+
template<int R, typename P>
|
389 |
+
void Normalise( P v[R] )
|
390 |
+
{
|
391 |
+
const P length = Length<R,P>(v);
|
392 |
+
|
393 |
+
for(size_t r = 0; r < R; ++r ) {
|
394 |
+
v[r] /= length;
|
395 |
+
}
|
396 |
+
}
|
397 |
+
|
398 |
+
template<typename P>
|
399 |
+
void EnforceUpT_wc(P T_wc[3*4], const P up_w[3])
|
400 |
+
{
|
401 |
+
// Copy R_wc
|
402 |
+
P R_wc[3*3];
|
403 |
+
std::copy(T_wc,T_wc+3*3,R_wc);
|
404 |
+
|
405 |
+
// New R_wc should go into T_wc
|
406 |
+
P* NR_wc = T_wc;
|
407 |
+
|
408 |
+
// // cx_w,cy_w,cz_w are camera axis in world coordinates
|
409 |
+
// // Calculate new camera coordinates (ncx_w,ncy_w,ncz_w)
|
410 |
+
|
411 |
+
// ncx_w = up_w x cz_w
|
412 |
+
CrossProduct(NR_wc + 0*3, up_w, R_wc + 2*3);
|
413 |
+
|
414 |
+
// ncy_w = cz_w x ncx_w
|
415 |
+
CrossProduct(NR_wc + 1*3, R_wc + 2*3, NR_wc + 0*3);
|
416 |
+
|
417 |
+
// ncz_w = cz_w
|
418 |
+
std::copy(R_wc + 2*3, R_wc + 3*3, NR_wc + 2*3);
|
419 |
+
|
420 |
+
Normalise<3,P>(NR_wc + 0*3);
|
421 |
+
Normalise<3,P>(NR_wc + 1*3);
|
422 |
+
Normalise<3,P>(NR_wc + 2*3);
|
423 |
+
}
|
424 |
+
|
425 |
+
template<typename P>
|
426 |
+
void EnforceUpT_cw(P T_cw_4x4[4*4], const P up_w[3])
|
427 |
+
{
|
428 |
+
// 3x4 from 4x4
|
429 |
+
P T_cw[3*4];
|
430 |
+
LieSE3from4x4<P>(T_cw,T_cw_4x4);
|
431 |
+
|
432 |
+
// Invert T_cw
|
433 |
+
P T_wc[3*4];
|
434 |
+
LieInverseSE3<P>(T_wc, T_cw);
|
435 |
+
|
436 |
+
// Enforce up for T_wc
|
437 |
+
EnforceUpT_wc<P>(T_wc, up_w);
|
438 |
+
|
439 |
+
// Invert
|
440 |
+
LieInverseSE3<P>(T_cw, T_wc);
|
441 |
+
|
442 |
+
// 4x4 from 3x4
|
443 |
+
LiePutSE3in4x4<P>(T_cw_4x4,T_cw);
|
444 |
+
}
|
445 |
+
|
446 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/threadedfilebuf.h
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <iostream>
|
31 |
+
#include <streambuf>
|
32 |
+
#include <fstream>
|
33 |
+
|
34 |
+
#include <pangolin/platform.h>
|
35 |
+
#include <thread>
|
36 |
+
#include <mutex>
|
37 |
+
#include <condition_variable>
|
38 |
+
|
39 |
+
#ifdef _LINUX_
|
40 |
+
// On linux, using posix file i/o to allow sync writes.
|
41 |
+
#define USE_POSIX_FILE_IO
|
42 |
+
#endif
|
43 |
+
|
44 |
+
namespace pangolin
|
45 |
+
{
|
46 |
+
|
47 |
+
class PANGOLIN_EXPORT threadedfilebuf : public std::streambuf
|
48 |
+
{
|
49 |
+
public:
|
50 |
+
~threadedfilebuf();
|
51 |
+
threadedfilebuf();
|
52 |
+
threadedfilebuf(const std::string& filename, size_t buffer_size_bytes);
|
53 |
+
|
54 |
+
void open(const std::string& filename, size_t buffer_size_bytes);
|
55 |
+
void close();
|
56 |
+
void force_close();
|
57 |
+
|
58 |
+
void operator()();
|
59 |
+
|
60 |
+
protected:
|
61 |
+
void soft_close();
|
62 |
+
|
63 |
+
//! Override streambuf::xsputn for asynchronous write
|
64 |
+
std::streamsize xsputn(const char * s, std::streamsize n) override;
|
65 |
+
|
66 |
+
//! Override streambuf::overflow for asynchronous write
|
67 |
+
int overflow(int c) override;
|
68 |
+
|
69 |
+
std::streampos seekoff(
|
70 |
+
std::streamoff off, std::ios_base::seekdir way,
|
71 |
+
std::ios_base::openmode which = std::ios_base::in | std::ios_base::out
|
72 |
+
) override;
|
73 |
+
|
74 |
+
#ifdef USE_POSIX_FILE_IO
|
75 |
+
int filenum = -1;
|
76 |
+
#else
|
77 |
+
std::filebuf file;
|
78 |
+
#endif
|
79 |
+
|
80 |
+
char* mem_buffer;
|
81 |
+
std::streamsize mem_size;
|
82 |
+
std::streamsize mem_max_size;
|
83 |
+
std::streamsize mem_start;
|
84 |
+
std::streamsize mem_end;
|
85 |
+
|
86 |
+
std::streampos input_pos;
|
87 |
+
|
88 |
+
std::mutex update_mutex;
|
89 |
+
std::condition_variable cond_queued;
|
90 |
+
std::condition_variable cond_dequeued;
|
91 |
+
std::thread write_thread;
|
92 |
+
|
93 |
+
bool should_run;
|
94 |
+
bool is_pipe;
|
95 |
+
};
|
96 |
+
|
97 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/timer.h
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <chrono>
|
31 |
+
#include <thread>
|
32 |
+
|
33 |
+
#include <pangolin/platform.h>
|
34 |
+
|
35 |
+
namespace pangolin
|
36 |
+
{
|
37 |
+
|
38 |
+
// These methods exist for backwards compatibility.
|
39 |
+
// They are deprecated in favour of direct use of std::chrono in C++11
|
40 |
+
|
41 |
+
using baseclock = std::chrono::steady_clock;
|
42 |
+
using basetime = baseclock::time_point;
|
43 |
+
static_assert(baseclock::is_steady, "baseclock must be steady to be robust against system time settings");
|
44 |
+
|
45 |
+
inline basetime TimeNow()
|
46 |
+
{
|
47 |
+
return baseclock::now();
|
48 |
+
}
|
49 |
+
|
50 |
+
inline double Time_s(basetime t)
|
51 |
+
{
|
52 |
+
using namespace std::chrono;
|
53 |
+
return (double)duration_cast<seconds>( t.time_since_epoch() ).count();
|
54 |
+
}
|
55 |
+
|
56 |
+
inline int64_t Time_us(basetime t)
|
57 |
+
{
|
58 |
+
using namespace std::chrono;
|
59 |
+
return duration_cast<microseconds>( t.time_since_epoch() ).count();
|
60 |
+
}
|
61 |
+
|
62 |
+
inline double TimeDiff_s(basetime start, basetime end)
|
63 |
+
{
|
64 |
+
const baseclock::duration d = end - start;
|
65 |
+
return Time_s( basetime() + d);
|
66 |
+
}
|
67 |
+
|
68 |
+
inline int64_t TimeDiff_us(basetime start, basetime end)
|
69 |
+
{
|
70 |
+
const baseclock::duration d = end - start;
|
71 |
+
return Time_us( basetime() + d);
|
72 |
+
}
|
73 |
+
|
74 |
+
inline basetime TimeAdd(basetime t1, basetime t2)
|
75 |
+
{
|
76 |
+
|
77 |
+
return t1 + t2.time_since_epoch();
|
78 |
+
}
|
79 |
+
|
80 |
+
inline double TimeNow_s()
|
81 |
+
{
|
82 |
+
return Time_s(TimeNow());
|
83 |
+
}
|
84 |
+
|
85 |
+
inline int64_t TimeNow_us()
|
86 |
+
{
|
87 |
+
return Time_us(TimeNow());
|
88 |
+
}
|
89 |
+
|
90 |
+
inline basetime WaitUntil(basetime t)
|
91 |
+
{
|
92 |
+
std::this_thread::sleep_until(t);
|
93 |
+
return TimeNow();
|
94 |
+
}
|
95 |
+
|
96 |
+
struct Timer
|
97 |
+
{
|
98 |
+
Timer() {
|
99 |
+
Reset();
|
100 |
+
}
|
101 |
+
|
102 |
+
void Reset()
|
103 |
+
{
|
104 |
+
start = TimeNow();
|
105 |
+
}
|
106 |
+
|
107 |
+
double Elapsed_s()
|
108 |
+
{
|
109 |
+
basetime currtime = TimeNow();
|
110 |
+
return TimeDiff_s(start,currtime);
|
111 |
+
}
|
112 |
+
|
113 |
+
double Elapsed_us()
|
114 |
+
{
|
115 |
+
basetime currtime = TimeNow();
|
116 |
+
return (double)TimeDiff_us(start,currtime);
|
117 |
+
}
|
118 |
+
|
119 |
+
basetime start;
|
120 |
+
};
|
121 |
+
|
122 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/transform.h
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2014 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <ostream>
|
31 |
+
#include <functional>
|
32 |
+
|
33 |
+
namespace pangolin
|
34 |
+
{
|
35 |
+
|
36 |
+
// Find the open brace preceeded by '$'
|
37 |
+
inline const char* FirstOpenBrace(const char* str, char token = '$', char open = '{')
|
38 |
+
{
|
39 |
+
bool symbol = false;
|
40 |
+
|
41 |
+
for(; *str != '\0'; ++str ) {
|
42 |
+
if( *str == token) {
|
43 |
+
symbol = true;
|
44 |
+
}else{
|
45 |
+
if( symbol ) {
|
46 |
+
if( *str == open ) {
|
47 |
+
return str;
|
48 |
+
} else {
|
49 |
+
symbol = false;
|
50 |
+
}
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
+
return 0;
|
55 |
+
}
|
56 |
+
|
57 |
+
// Find the first matching end brace. str includes open brace
|
58 |
+
inline const char* MatchingEndBrace(const char* str, char open = '{', char close = '}')
|
59 |
+
{
|
60 |
+
int b = 0;
|
61 |
+
for(; *str != '\0'; ++str ) {
|
62 |
+
if( *str == open ) {
|
63 |
+
++b;
|
64 |
+
}else if( *str == close ) {
|
65 |
+
--b;
|
66 |
+
if( b == 0 ) {
|
67 |
+
return str;
|
68 |
+
}
|
69 |
+
}
|
70 |
+
}
|
71 |
+
return 0;
|
72 |
+
}
|
73 |
+
|
74 |
+
inline std::string Transform(const std::string& val, std::function<std::string(const std::string&)> dictionary, char token = '$', char open = '{', char close = '}')
|
75 |
+
{
|
76 |
+
std::string expanded = val;
|
77 |
+
|
78 |
+
while(true)
|
79 |
+
{
|
80 |
+
const char* brace = FirstOpenBrace(expanded.c_str(), token, open);
|
81 |
+
if(brace)
|
82 |
+
{
|
83 |
+
const char* endbrace = MatchingEndBrace(brace);
|
84 |
+
if( endbrace )
|
85 |
+
{
|
86 |
+
std::ostringstream oss;
|
87 |
+
oss << std::string(expanded.c_str(), brace-1);
|
88 |
+
|
89 |
+
const std::string inexpand = Transform( std::string(brace+1,endbrace), dictionary, token, open, close );
|
90 |
+
oss << dictionary(inexpand);
|
91 |
+
oss << std::string(endbrace+1, expanded.c_str() + expanded.length() );
|
92 |
+
expanded = oss.str();
|
93 |
+
continue;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
break;
|
97 |
+
}
|
98 |
+
|
99 |
+
return expanded;
|
100 |
+
}
|
101 |
+
|
102 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/true_false_toggle.h
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
namespace pangolin {
|
4 |
+
|
5 |
+
enum class TrueFalseToggle
|
6 |
+
{
|
7 |
+
False=0,
|
8 |
+
True=1,
|
9 |
+
Toggle=2
|
10 |
+
};
|
11 |
+
|
12 |
+
inline bool to_bool(const TrueFalseToggle on_off_toggle, const bool current_value)
|
13 |
+
{
|
14 |
+
switch (on_off_toggle) {
|
15 |
+
case TrueFalseToggle::True: return true;
|
16 |
+
case TrueFalseToggle::False: return false;
|
17 |
+
case TrueFalseToggle::Toggle: return !current_value;
|
18 |
+
default: return false;
|
19 |
+
}
|
20 |
+
}
|
21 |
+
|
22 |
+
inline bool should_toggle(const TrueFalseToggle on_off_toggle, const bool current_value)
|
23 |
+
{
|
24 |
+
return ( (on_off_toggle == TrueFalseToggle::Toggle) ||
|
25 |
+
(current_value != (on_off_toggle==TrueFalseToggle::True))
|
26 |
+
);
|
27 |
+
}
|
28 |
+
|
29 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/type_convert.h
ADDED
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <iostream>
|
31 |
+
#include <sstream>
|
32 |
+
|
33 |
+
#include <functional>
|
34 |
+
#include <pangolin/compat/type_traits.h>
|
35 |
+
|
36 |
+
namespace pangolin
|
37 |
+
{
|
38 |
+
struct BadInputException : std::exception {
|
39 |
+
char const* what() const throw() { return "Failed to serialise type"; }
|
40 |
+
};
|
41 |
+
}
|
42 |
+
|
43 |
+
namespace pangolin
|
44 |
+
{
|
45 |
+
|
46 |
+
template<typename T, typename S, typename Enable=void>
|
47 |
+
struct Convert;
|
48 |
+
|
49 |
+
// Generic conversion through serialisation from / to string
|
50 |
+
template<typename T, typename S, typename Enable>
|
51 |
+
struct Convert {
|
52 |
+
static T Do(const S& src)
|
53 |
+
{
|
54 |
+
std::ostringstream oss;
|
55 |
+
oss << src;
|
56 |
+
std::istringstream iss(oss.str());
|
57 |
+
T target;
|
58 |
+
iss >> target;
|
59 |
+
|
60 |
+
if(iss.fail())
|
61 |
+
throw BadInputException();
|
62 |
+
|
63 |
+
return target;
|
64 |
+
}
|
65 |
+
};
|
66 |
+
|
67 |
+
// Between the same types is just a copy
|
68 |
+
template<typename T>
|
69 |
+
struct Convert<T, T > {
|
70 |
+
static T Do(const T& src)
|
71 |
+
{
|
72 |
+
return src;
|
73 |
+
}
|
74 |
+
};
|
75 |
+
|
76 |
+
// Apply bool alpha IO manipulator for bool types
|
77 |
+
template<>
|
78 |
+
struct Convert<bool,std::string> {
|
79 |
+
static bool Do(const std::string& src)
|
80 |
+
{
|
81 |
+
bool target;
|
82 |
+
std::istringstream iss(src);
|
83 |
+
iss >> target;
|
84 |
+
|
85 |
+
if(iss.fail())
|
86 |
+
{
|
87 |
+
std::istringstream iss2(src);
|
88 |
+
iss2 >> std::boolalpha >> target;
|
89 |
+
if( iss2.fail())
|
90 |
+
throw BadInputException();
|
91 |
+
}
|
92 |
+
|
93 |
+
return target;
|
94 |
+
}
|
95 |
+
};
|
96 |
+
|
97 |
+
// From strings
|
98 |
+
template<typename T>
|
99 |
+
struct Convert<T,std::string, typename pangolin::enable_if_c<
|
100 |
+
!std::is_same<T,std::string>::value
|
101 |
+
>::type > {
|
102 |
+
static T Do(const std::string& src)
|
103 |
+
{
|
104 |
+
T target;
|
105 |
+
std::istringstream iss(src);
|
106 |
+
iss >> target;
|
107 |
+
|
108 |
+
if(iss.fail())
|
109 |
+
throw BadInputException();
|
110 |
+
|
111 |
+
return target;
|
112 |
+
}
|
113 |
+
};
|
114 |
+
|
115 |
+
// To strings
|
116 |
+
template<typename S>
|
117 |
+
struct Convert<std::string, S, typename pangolin::enable_if_c<
|
118 |
+
!std::is_same<S,std::string>::value
|
119 |
+
>::type > {
|
120 |
+
static std::string Do(const S& src)
|
121 |
+
{
|
122 |
+
std::ostringstream oss;
|
123 |
+
oss << src;
|
124 |
+
return oss.str();
|
125 |
+
}
|
126 |
+
};
|
127 |
+
|
128 |
+
// Between scalars
|
129 |
+
template<typename T, typename S>
|
130 |
+
struct Convert<T, S, typename pangolin::enable_if_c<
|
131 |
+
std::is_scalar<T>::value && !std::is_same<T, bool>::value &&
|
132 |
+
std::is_scalar<S>::value && !std::is_same<S, bool>::value &&
|
133 |
+
!std::is_same<S,T>::value
|
134 |
+
>::type > {
|
135 |
+
static T Do(const S& src)
|
136 |
+
{
|
137 |
+
return static_cast<T>(src);
|
138 |
+
}
|
139 |
+
};
|
140 |
+
|
141 |
+
// From Scalars to bool (different than scalar definition to avoid MSVC Warnings)
|
142 |
+
template<typename T, typename S>
|
143 |
+
struct Convert<T, S, typename pangolin::enable_if_c<
|
144 |
+
std::is_same<T, bool>::value &&
|
145 |
+
std::is_scalar<S>::value &&
|
146 |
+
!std::is_same<S, T>::value
|
147 |
+
>::type > {
|
148 |
+
static T Do(const S& src)
|
149 |
+
{
|
150 |
+
return src != static_cast<S>(0);
|
151 |
+
}
|
152 |
+
};
|
153 |
+
|
154 |
+
// From bool to Scalars (different than scalar definition to avoid MSVC Warnings)
|
155 |
+
template<typename T, typename S>
|
156 |
+
struct Convert<T, S, typename pangolin::enable_if_c<
|
157 |
+
std::is_scalar<T>::value &&
|
158 |
+
std::is_same<S, bool>::value &&
|
159 |
+
!std::is_same<S, T>::value
|
160 |
+
>::type > {
|
161 |
+
static T Do(const S& src)
|
162 |
+
{
|
163 |
+
return src ? static_cast<T>(0) : static_cast<T>(1);
|
164 |
+
}
|
165 |
+
};
|
166 |
+
|
167 |
+
template<typename S>
|
168 |
+
std::string ToString(const S& src)
|
169 |
+
{
|
170 |
+
return Convert<std::string,S>::Do(src);
|
171 |
+
}
|
172 |
+
|
173 |
+
template<typename T>
|
174 |
+
T FromString(const std::string& src)
|
175 |
+
{
|
176 |
+
return Convert<T,std::string>::Do(src);
|
177 |
+
}
|
178 |
+
|
179 |
+
|
180 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/uri.h
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* This file is part of the Pangolin Project.
|
2 |
+
* http://github.com/stevenlovegrove/Pangolin
|
3 |
+
*
|
4 |
+
* Copyright (c) 2011 Steven Lovegrove
|
5 |
+
*
|
6 |
+
* Permission is hereby granted, free of charge, to any person
|
7 |
+
* obtaining a copy of this software and associated documentation
|
8 |
+
* files (the "Software"), to deal in the Software without
|
9 |
+
* restriction, including without limitation the rights to use,
|
10 |
+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11 |
+
* copies of the Software, and to permit persons to whom the
|
12 |
+
* Software is furnished to do so, subject to the following
|
13 |
+
* conditions:
|
14 |
+
*
|
15 |
+
* The above copyright notice and this permission notice shall be
|
16 |
+
* included in all copies or substantial portions of the Software.
|
17 |
+
*
|
18 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
19 |
+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
20 |
+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
21 |
+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
22 |
+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
23 |
+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
24 |
+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
+
* OTHER DEALINGS IN THE SOFTWARE.
|
26 |
+
*/
|
27 |
+
|
28 |
+
#pragma once
|
29 |
+
|
30 |
+
#include <string>
|
31 |
+
#include <pangolin/platform.h>
|
32 |
+
#include <pangolin/utils/params.h>
|
33 |
+
|
34 |
+
namespace pangolin
|
35 |
+
{
|
36 |
+
|
37 |
+
struct PANGOLIN_EXPORT Uri : public Params
|
38 |
+
{
|
39 |
+
std::string scheme;
|
40 |
+
std::string url;
|
41 |
+
std::string full_uri;
|
42 |
+
};
|
43 |
+
|
44 |
+
//! Parse string as Video URI
|
45 |
+
PANGOLIN_EXPORT
|
46 |
+
Uri ParseUri(const std::string& str_uri);
|
47 |
+
|
48 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/variadic_all.h
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#pragma once
|
2 |
+
|
3 |
+
#include <tuple>
|
4 |
+
|
5 |
+
namespace pangolin {
|
6 |
+
|
7 |
+
template<typename TPred, typename T>
|
8 |
+
bool all_of(TPred pred, const T& i)
|
9 |
+
{
|
10 |
+
return pred(i);
|
11 |
+
}
|
12 |
+
|
13 |
+
template<typename TPred, typename T, typename... Targs>
|
14 |
+
bool all_of(const TPred& pred, const T& i, const Targs& ... ins)
|
15 |
+
{
|
16 |
+
return pred(i) && all_of(pred, ins...);
|
17 |
+
}
|
18 |
+
|
19 |
+
template<typename TPred, typename T>
|
20 |
+
bool any_of(TPred pred, const T& i)
|
21 |
+
{
|
22 |
+
return pred(i);
|
23 |
+
}
|
24 |
+
|
25 |
+
template<typename TPred, typename T, typename... Targs>
|
26 |
+
bool any_of(const TPred& pred, const T& i, Targs& ... ins)
|
27 |
+
{
|
28 |
+
return pred(i) || any_of(pred, ins...);
|
29 |
+
}
|
30 |
+
|
31 |
+
template<typename TContainer, typename... Targs>
|
32 |
+
bool all_found(const TContainer& c, const Targs& ... its)
|
33 |
+
{
|
34 |
+
using T1 = typename std::tuple_element<0, std::tuple<Targs...>>::type;
|
35 |
+
return all_of([&c](const T1& it){return it != c.end();}, its...);
|
36 |
+
}
|
37 |
+
|
38 |
+
template<typename T, typename... Targs>
|
39 |
+
bool all_equal(const T& v1, const Targs& ... its)
|
40 |
+
{
|
41 |
+
return all_of([v1](const T& o){return v1 == o;}, its...);
|
42 |
+
}
|
43 |
+
|
44 |
+
}
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/xml/license.txt
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Use of this software is granted under one of the following two licenses,
|
2 |
+
to be chosen freely by the user.
|
3 |
+
|
4 |
+
1. Boost Software License - Version 1.0 - August 17th, 2003
|
5 |
+
===============================================================================
|
6 |
+
|
7 |
+
Copyright (c) 2006, 2007 Marcin Kalicinski
|
8 |
+
|
9 |
+
Permission is hereby granted, free of charge, to any person or organization
|
10 |
+
obtaining a copy of the software and accompanying documentation covered by
|
11 |
+
this license (the "Software") to use, reproduce, display, distribute,
|
12 |
+
execute, and transmit the Software, and to prepare derivative works of the
|
13 |
+
Software, and to permit third-parties to whom the Software is furnished to
|
14 |
+
do so, all subject to the following:
|
15 |
+
|
16 |
+
The copyright notices in the Software and this entire statement, including
|
17 |
+
the above license grant, this restriction and the following disclaimer,
|
18 |
+
must be included in all copies of the Software, in whole or in part, and
|
19 |
+
all derivative works of the Software, unless such copies or derivative
|
20 |
+
works are solely in the form of machine-executable object code generated by
|
21 |
+
a source language processor.
|
22 |
+
|
23 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
24 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
25 |
+
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
26 |
+
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
27 |
+
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
28 |
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
29 |
+
DEALINGS IN THE SOFTWARE.
|
30 |
+
|
31 |
+
2. The MIT License
|
32 |
+
===============================================================================
|
33 |
+
|
34 |
+
Copyright (c) 2006, 2007 Marcin Kalicinski
|
35 |
+
|
36 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
37 |
+
of this software and associated documentation files (the "Software"), to deal
|
38 |
+
in the Software without restriction, including without limitation the rights
|
39 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
40 |
+
of the Software, and to permit persons to whom the Software is furnished to do so,
|
41 |
+
subject to the following conditions:
|
42 |
+
|
43 |
+
The above copyright notice and this permission notice shall be included in all
|
44 |
+
copies or substantial portions of the Software.
|
45 |
+
|
46 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
47 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
48 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
49 |
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
50 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
51 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
52 |
+
IN THE SOFTWARE.
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/xml/rapidxml.hpp
ADDED
The diff for this file is too large to render.
See raw diff
|
|
third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/xml/rapidxml_iterators.hpp
ADDED
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#ifndef RAPIDXML_ITERATORS_HPP_INCLUDED
|
2 |
+
#define RAPIDXML_ITERATORS_HPP_INCLUDED
|
3 |
+
|
4 |
+
// Copyright (C) 2006, 2009 Marcin Kalicinski
|
5 |
+
// Version 1.13
|
6 |
+
// Revision $DateTime: 2009/05/13 01:46:17 $
|
7 |
+
//! \file rapidxml_iterators.hpp This file contains rapidxml iterators
|
8 |
+
|
9 |
+
#include "rapidxml.hpp"
|
10 |
+
|
11 |
+
namespace rapidxml
|
12 |
+
{
|
13 |
+
|
14 |
+
//! Iterator of child nodes of xml_node
|
15 |
+
template<class Ch>
|
16 |
+
class node_iterator
|
17 |
+
{
|
18 |
+
|
19 |
+
public:
|
20 |
+
|
21 |
+
typedef typename xml_node<Ch> value_type;
|
22 |
+
typedef typename xml_node<Ch> &reference;
|
23 |
+
typedef typename xml_node<Ch> *pointer;
|
24 |
+
typedef std::ptrdiff_t difference_type;
|
25 |
+
typedef std::bidirectional_iterator_tag iterator_category;
|
26 |
+
|
27 |
+
node_iterator()
|
28 |
+
: m_node(0)
|
29 |
+
{
|
30 |
+
}
|
31 |
+
|
32 |
+
node_iterator(xml_node<Ch> *node)
|
33 |
+
: m_node(node->first_node())
|
34 |
+
{
|
35 |
+
}
|
36 |
+
|
37 |
+
reference operator *() const
|
38 |
+
{
|
39 |
+
assert(m_node);
|
40 |
+
return *m_node;
|
41 |
+
}
|
42 |
+
|
43 |
+
pointer operator->() const
|
44 |
+
{
|
45 |
+
assert(m_node);
|
46 |
+
return m_node;
|
47 |
+
}
|
48 |
+
|
49 |
+
node_iterator& operator++()
|
50 |
+
{
|
51 |
+
assert(m_node);
|
52 |
+
m_node = m_node->next_sibling();
|
53 |
+
return *this;
|
54 |
+
}
|
55 |
+
|
56 |
+
node_iterator operator++(int)
|
57 |
+
{
|
58 |
+
node_iterator tmp = *this;
|
59 |
+
++this;
|
60 |
+
return tmp;
|
61 |
+
}
|
62 |
+
|
63 |
+
node_iterator& operator--()
|
64 |
+
{
|
65 |
+
assert(m_node && m_node->previous_sibling());
|
66 |
+
m_node = m_node->previous_sibling();
|
67 |
+
return *this;
|
68 |
+
}
|
69 |
+
|
70 |
+
node_iterator operator--(int)
|
71 |
+
{
|
72 |
+
node_iterator tmp = *this;
|
73 |
+
++this;
|
74 |
+
return tmp;
|
75 |
+
}
|
76 |
+
|
77 |
+
bool operator ==(const node_iterator<Ch> &rhs)
|
78 |
+
{
|
79 |
+
return m_node == rhs.m_node;
|
80 |
+
}
|
81 |
+
|
82 |
+
bool operator !=(const node_iterator<Ch> &rhs)
|
83 |
+
{
|
84 |
+
return m_node != rhs.m_node;
|
85 |
+
}
|
86 |
+
|
87 |
+
private:
|
88 |
+
|
89 |
+
xml_node<Ch> *m_node;
|
90 |
+
|
91 |
+
};
|
92 |
+
|
93 |
+
//! Iterator of child attributes of xml_node
|
94 |
+
template<class Ch>
|
95 |
+
class attribute_iterator
|
96 |
+
{
|
97 |
+
|
98 |
+
public:
|
99 |
+
|
100 |
+
typedef typename xml_attribute<Ch> value_type;
|
101 |
+
typedef typename xml_attribute<Ch> &reference;
|
102 |
+
typedef typename xml_attribute<Ch> *pointer;
|
103 |
+
typedef std::ptrdiff_t difference_type;
|
104 |
+
typedef std::bidirectional_iterator_tag iterator_category;
|
105 |
+
|
106 |
+
attribute_iterator()
|
107 |
+
: m_attribute(0)
|
108 |
+
{
|
109 |
+
}
|
110 |
+
|
111 |
+
attribute_iterator(xml_node<Ch> *node)
|
112 |
+
: m_attribute(node->first_attribute())
|
113 |
+
{
|
114 |
+
}
|
115 |
+
|
116 |
+
reference operator *() const
|
117 |
+
{
|
118 |
+
assert(m_attribute);
|
119 |
+
return *m_attribute;
|
120 |
+
}
|
121 |
+
|
122 |
+
pointer operator->() const
|
123 |
+
{
|
124 |
+
assert(m_attribute);
|
125 |
+
return m_attribute;
|
126 |
+
}
|
127 |
+
|
128 |
+
attribute_iterator& operator++()
|
129 |
+
{
|
130 |
+
assert(m_attribute);
|
131 |
+
m_attribute = m_attribute->next_attribute();
|
132 |
+
return *this;
|
133 |
+
}
|
134 |
+
|
135 |
+
attribute_iterator operator++(int)
|
136 |
+
{
|
137 |
+
attribute_iterator tmp = *this;
|
138 |
+
++this;
|
139 |
+
return tmp;
|
140 |
+
}
|
141 |
+
|
142 |
+
attribute_iterator& operator--()
|
143 |
+
{
|
144 |
+
assert(m_attribute && m_attribute->previous_attribute());
|
145 |
+
m_attribute = m_attribute->previous_attribute();
|
146 |
+
return *this;
|
147 |
+
}
|
148 |
+
|
149 |
+
attribute_iterator operator--(int)
|
150 |
+
{
|
151 |
+
attribute_iterator tmp = *this;
|
152 |
+
++this;
|
153 |
+
return tmp;
|
154 |
+
}
|
155 |
+
|
156 |
+
bool operator ==(const attribute_iterator<Ch> &rhs)
|
157 |
+
{
|
158 |
+
return m_attribute == rhs.m_attribute;
|
159 |
+
}
|
160 |
+
|
161 |
+
bool operator !=(const attribute_iterator<Ch> &rhs)
|
162 |
+
{
|
163 |
+
return m_attribute != rhs.m_attribute;
|
164 |
+
}
|
165 |
+
|
166 |
+
private:
|
167 |
+
|
168 |
+
xml_attribute<Ch> *m_attribute;
|
169 |
+
|
170 |
+
};
|
171 |
+
|
172 |
+
}
|
173 |
+
|
174 |
+
#endif
|