Vince's CSV Parser
Loading...
Searching...
No Matches
common.hpp
Go to the documentation of this file.
1
5#pragma once
6#include <algorithm>
7#include <array>
8#include <cmath>
9#include <cstdlib>
10#include <deque>
11
12#if defined(_WIN32)
13# ifndef WIN32_LEAN_AND_MEAN
14# define WIN32_LEAN_AND_MEAN
15# endif
16# include <windows.h>
17# undef max
18# undef min
19#elif defined(__linux__)
20# include <unistd.h>
21#endif
22
26#define CSV_INLINE
27
28#pragma once
29#include <type_traits>
30
31// Minimal portability macros (Hedley subset) with CSV_ prefix.
32#if defined(__clang__) || defined(__GNUC__)
33 #define CSV_CONST __attribute__((__const__))
34 #define CSV_PURE __attribute__((__pure__))
35 #define CSV_PRIVATE __attribute__((__visibility__("hidden")))
36 #define CSV_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
37#elif defined(_MSC_VER)
38 #define CSV_CONST
39 #define CSV_PURE
40 #define CSV_PRIVATE
41 #define CSV_NON_NULL(...)
42#else
43 #define CSV_CONST
44 #define CSV_PURE
45 #define CSV_PRIVATE
46 #define CSV_NON_NULL(...)
47#endif
48
49#if defined(__GNUC__) || defined(__clang__)
50 #define CSV_UNREACHABLE() __builtin_unreachable()
51#elif defined(_MSC_VER)
52 #define CSV_UNREACHABLE() __assume(0)
53#else
54 #define CSV_UNREACHABLE() abort()
55#endif
56
57namespace csv {
58#ifdef _MSC_VER
59#pragma region Compatibility Macros
60#endif
74#define STATIC_ASSERT(x) static_assert(x, "Assertion failed")
75
76#if (defined(CMAKE_CXX_STANDARD) && CMAKE_CXX_STANDARD == 20) || __cplusplus >= 202002L
77#define CSV_HAS_CXX20
78#endif
79
80#if (defined(CMAKE_CXX_STANDARD) && CMAKE_CXX_STANDARD == 17) || __cplusplus >= 201703L
81#define CSV_HAS_CXX17
82#endif
83
84#if (defined(CMAKE_CXX_STANDARD) && CMAKE_CXX_STANDARD >= 14) || __cplusplus >= 201402L
85#define CSV_HAS_CXX14
86#endif
87
88#ifdef CSV_HAS_CXX17
89#include <string_view>
93 using string_view = std::string_view;
94#else
95#include "../external/string_view.hpp"
99 using string_view = nonstd::string_view;
100#endif
101
102#ifdef CSV_HAS_CXX17
103 #define IF_CONSTEXPR if constexpr
104 #define CONSTEXPR_VALUE constexpr
105
106 #define CONSTEXPR_17 constexpr
107#else
108 #define IF_CONSTEXPR if
109 #define CONSTEXPR_VALUE const
110
111 #define CONSTEXPR_17 inline
112#endif
113
114#ifdef CSV_HAS_CXX14
115 template<bool B, class T = void>
116 using enable_if_t = std::enable_if_t<B, T>;
117
118 #define CONSTEXPR_14 constexpr
119 #define CONSTEXPR_VALUE_14 constexpr
120#else
121 template<bool B, class T = void>
122 using enable_if_t = typename std::enable_if<B, T>::type;
123
124 #define CONSTEXPR_14 inline
125 #define CONSTEXPR_VALUE_14 const
126#endif
127
128#ifdef CSV_HAS_CXX17
129 template<typename F, typename... Args>
130 using invoke_result_t = typename std::invoke_result<F, Args...>::type;
131#else
132 template<typename F, typename... Args>
133 using invoke_result_t = typename std::result_of<F(Args...)>::type;
134#endif
135
136 // Resolves g++ bug with regard to constexpr methods
137 // See: https://stackoverflow.com/questions/36489369/constexpr-non-static-member-function-with-non-constexpr-constructor-gcc-clang-d
138#if defined __GNUC__ && !defined __clang__
139 #if (__GNUC__ >= 7 &&__GNUC_MINOR__ >= 2) || (__GNUC__ >= 8)
140 #define CONSTEXPR constexpr
141 #endif
142 #else
143 #ifdef CSV_HAS_CXX17
144 #define CONSTEXPR constexpr
145 #endif
146#endif
147
148#ifndef CONSTEXPR
149#define CONSTEXPR inline
150#endif
151
152#ifdef _MSC_VER
153#pragma endregion
154#endif
155
156 namespace internals {
157 // PAGE_SIZE macro could be already defined by the host system.
158#if defined(PAGE_SIZE)
159#undef PAGE_SIZE
160#endif
161
162// Get operating system specific details
163#if defined(_WIN32)
164 inline int getpagesize() {
167 return std::max(sys_info.dwPageSize, sys_info.dwAllocationGranularity);
168 }
169
170 const int PAGE_SIZE = getpagesize();
171#elif defined(__linux__)
172 const int PAGE_SIZE = getpagesize();
173#else
177 const int PAGE_SIZE = 4096;
178#endif
179
190 constexpr size_t ITERATION_CHUNK_SIZE = 10000000; // 10MB
191
192 template<typename T>
193 inline bool is_equal(T a, T b, T epsilon = 0.001) {
195 static_assert(std::is_floating_point<T>::value, "T must be a floating point type.");
196 return std::abs(a - b) < epsilon;
197 }
198
205 enum class ParseFlags {
207 QUOTE = 2 | 1,
208 NOT_SPECIAL = 4,
209 DELIMITER = 4 | 2,
210 NEWLINE = 4 | 2 | 1
211 };
212
215 constexpr ParseFlags quote_escape_flag(ParseFlags flag, bool quote_escape) noexcept {
216 return (ParseFlags)((int)flag & ~((int)ParseFlags::QUOTE * quote_escape));
217 }
218
219 // Assumed to be true by parsing functions: allows for testing
220 // if an item is DELIMITER or NEWLINE with a >= statement
222
229 STATIC_ASSERT(quote_escape_flag(ParseFlags::QUOTE, false) == ParseFlags::QUOTE);
232
237
239 using ParseFlagMap = std::array<ParseFlags, 256>;
240
242 using WhitespaceMap = std::array<bool, 256>;
243 }
244
246 constexpr int CSV_NOT_FOUND = -1;
247
249 constexpr unsigned CHAR_OFFSET = std::numeric_limits<char>::is_signed ? 128 : 0;
250}
std::array< ParseFlags, 256 > ParseFlagMap
An array which maps ASCII chars to a parsing flag.
Definition common.hpp:239
std::array< bool, 256 > WhitespaceMap
An array which maps ASCII chars to a flag indicating if it is whitespace.
Definition common.hpp:242
constexpr size_t ITERATION_CHUNK_SIZE
Chunk size for lazy-loading large CSV files.
Definition common.hpp:190
bool is_equal(T a, T b, T epsilon=0.001)
Definition common.hpp:193
const int PAGE_SIZE
Size of a memory page in bytes.
Definition common.hpp:177
ParseFlags
An enum used for describing the significance of each character with respect to CSV parsing.
Definition common.hpp:205
@ QUOTE_ESCAPE_QUOTE
A quote inside or terminating a quote_escaped field.
@ NOT_SPECIAL
Characters with no special meaning or escaped delimiters and newlines.
@ NEWLINE
Characters which signify a new row.
@ QUOTE
Characters which may signify a quote escape.
@ DELIMITER
Characters which signify a new field.
constexpr ParseFlags quote_escape_flag(ParseFlags flag, bool quote_escape) noexcept
Transform the ParseFlags given the context of whether or not the current field is quote escaped.
Definition common.hpp:215
CSV_CONST CONSTEXPR_17 OutArray arrayToDefault(T &&value)
Helper constexpr function to initialize an array with all the elements set to value.
The all encompassing namespace.
constexpr int CSV_NOT_FOUND
Integer indicating a requested column wasn't found.
Definition common.hpp:246
constexpr unsigned CHAR_OFFSET
Offset to convert char into array index.
Definition common.hpp:249
nonstd::string_view string_view
The string_view class used by this library.
Definition common.hpp:99