Techt3o commited on
Commit
e25ab6a
·
verified ·
1 Parent(s): 739258a

1cc98d02ef4e1cd8a6d2d153318b198a877ea06642d3e1195aba2da22184a6fc

Browse files
Files changed (50) hide show
  1. third-party/DPVO/Pangolin/components/pango_core/CMakeLists.txt +74 -0
  2. third-party/DPVO/Pangolin/components/pango_core/include/NaturalSort/LICENSE.md +21 -0
  3. third-party/DPVO/Pangolin/components/pango_core/include/NaturalSort/README.md +61 -0
  4. third-party/DPVO/Pangolin/components/pango_core/include/NaturalSort/natural_sort.hpp +281 -0
  5. third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/config.hpp +16 -0
  6. third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/linux/dynalo.hpp +76 -0
  7. third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/macos/dynalo.hpp +76 -0
  8. third-party/DPVO/Pangolin/components/pango_core/include/dynalo/detail/windows/dynalo.hpp +107 -0
  9. third-party/DPVO/Pangolin/components/pango_core/include/dynalo/dynalo.hpp +184 -0
  10. third-party/DPVO/Pangolin/components/pango_core/include/dynalo/symbol_helper.hpp +72 -0
  11. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/compat/glutbitmap.h +92 -0
  12. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/compat/type_traits.h +49 -0
  13. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/factory/factory.h +31 -0
  14. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/factory/factory_help.h +31 -0
  15. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/factory/factory_registry.h +218 -0
  16. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/pangolin.h +59 -0
  17. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/platform.h +66 -0
  18. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/argagg.hpp +1548 -0
  19. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/assert.h +72 -0
  20. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/avx_math.h +38 -0
  21. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/bitmask.h +73 -0
  22. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/compontent_cast.h +42 -0
  23. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/file_extension.h +77 -0
  24. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/file_utils.h +161 -0
  25. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/fix_size_buffer_queue.h +152 -0
  26. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/format_string.h +87 -0
  27. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/is_streamable.h +35 -0
  28. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/log.h +44 -0
  29. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/memstreambuf.h +55 -0
  30. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/param_set.h +79 -0
  31. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/params.h +97 -0
  32. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/parse.h +108 -0
  33. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/picojson.h +1416 -0
  34. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/posix/condition_variable.h +27 -0
  35. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/posix/semaphore.h +26 -0
  36. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/posix/shared_memory_buffer.h +25 -0
  37. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/range.h +372 -0
  38. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/signal_slot.h +4 -0
  39. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/sigstate.h +75 -0
  40. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/simple_math.h +446 -0
  41. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/threadedfilebuf.h +97 -0
  42. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/timer.h +122 -0
  43. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/transform.h +102 -0
  44. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/true_false_toggle.h +29 -0
  45. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/type_convert.h +180 -0
  46. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/uri.h +48 -0
  47. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/variadic_all.h +44 -0
  48. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/xml/license.txt +52 -0
  49. third-party/DPVO/Pangolin/components/pango_core/include/pangolin/utils/xml/rapidxml.hpp +0 -0
  50. 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 &param_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