Vince's CSV Parser
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 #include "../external/string_view.hpp"
32 
33  // If there is another version of Hedley, then the newer one
34  // takes precedence.
35  // See: https://github.com/nemequ/hedley
36 #include "../external/hedley.h"
37 
38 namespace csv {
39 #ifdef _MSC_VER
40 #pragma region Compatibility Macros
41 #endif
55 #define STATIC_ASSERT(x) static_assert(x, "Assertion failed")
56 
57 #if CMAKE_CXX_STANDARD == 17 || __cplusplus >= 201703L
58 #define CSV_HAS_CXX17
59 #endif
60 
61 #if CMAKE_CXX_STANDARD >= 14 || __cplusplus >= 201402L
62 #define CSV_HAS_CXX14
63 #endif
64 
65 #ifdef CSV_HAS_CXX17
66 #include <string_view>
71 #else
76 #endif
77 
78 #ifdef CSV_HAS_CXX17
79  #define IF_CONSTEXPR if constexpr
80  #define CONSTEXPR_VALUE constexpr
81 
82  #define CONSTEXPR_17 constexpr
83 #else
84  #define IF_CONSTEXPR if
85  #define CONSTEXPR_VALUE const
86 
87  #define CONSTEXPR_17 inline
88 #endif
89 
90 #ifdef CSV_HAS_CXX14
91  template<bool B, class T = void>
92  using enable_if_t = std::enable_if_t<B, T>;
93 
94  #define CONSTEXPR_14 constexpr
95  #define CONSTEXPR_VALUE_14 constexpr
96 #else
97  template<bool B, class T = void>
98  using enable_if_t = typename std::enable_if<B, T>::type;
99 
100  #define CONSTEXPR_14 inline
101  #define CONSTEXPR_VALUE_14 const
102 #endif
103 
104  // Resolves g++ bug with regard to constexpr methods
105  // See: https://stackoverflow.com/questions/36489369/constexpr-non-static-member-function-with-non-constexpr-constructor-gcc-clang-d
106 #if defined __GNUC__ && !defined __clang__
107  #if (__GNUC__ >= 7 &&__GNUC_MINOR__ >= 2) || (__GNUC__ >= 8)
108  #define CONSTEXPR constexpr
109  #endif
110  #else
111  #ifdef CSV_HAS_CXX17
112  #define CONSTEXPR constexpr
113  #endif
114 #endif
115 
116 #ifndef CONSTEXPR
117 #define CONSTEXPR inline
118 #endif
119 
120 #ifdef _MSC_VER
121 #pragma endregion
122 #endif
123 
124  namespace internals {
125  // PAGE_SIZE macro could be already defined by the host system.
126 #if defined(PAGE_SIZE)
127 #undef PAGE_SIZE
128 #endif
129 
130 // Get operating system specific details
131 #if defined(_WIN32)
132  inline int getpagesize() {
133  _SYSTEM_INFO sys_info = {};
134  GetSystemInfo(&sys_info);
135  return std::max(sys_info.dwPageSize, sys_info.dwAllocationGranularity);
136  }
137 
138  const int PAGE_SIZE = getpagesize();
139 #elif defined(__linux__)
140  const int PAGE_SIZE = getpagesize();
141 #else
145  const int PAGE_SIZE = 4096;
146 #endif
147 
151  constexpr size_t ITERATION_CHUNK_SIZE = 10000000; // 10MB
152 
153  template<typename T>
154  inline bool is_equal(T a, T b, T epsilon = 0.001) {
156  static_assert(std::is_floating_point<T>::value, "T must be a floating point type.");
157  return std::abs(a - b) < epsilon;
158  }
159 
166  enum class ParseFlags {
167  QUOTE_ESCAPE_QUOTE = 0,
168  QUOTE = 2 | 1,
169  NOT_SPECIAL = 4,
170  DELIMITER = 4 | 2,
171  NEWLINE = 4 | 2 | 1
172  };
173 
176  constexpr ParseFlags quote_escape_flag(ParseFlags flag, bool quote_escape) noexcept {
177  return (ParseFlags)((int)flag & ~((int)ParseFlags::QUOTE * quote_escape));
178  }
179 
180  // Assumed to be true by parsing functions: allows for testing
181  // if an item is DELIMITER or NEWLINE with a >= statement
183 
190  STATIC_ASSERT(quote_escape_flag(ParseFlags::QUOTE, false) == ParseFlags::QUOTE);
193 
198 
200  using ParseFlagMap = std::array<ParseFlags, 256>;
201 
203  using WhitespaceMap = std::array<bool, 256>;
204  }
205 
207  constexpr int CSV_NOT_FOUND = -1;
208 }
std::array< ParseFlags, 256 > ParseFlagMap
An array which maps ASCII chars to a parsing flag.
Definition: common.hpp:200
std::array< bool, 256 > WhitespaceMap
An array which maps ASCII chars to a flag indicating if it is whitespace.
Definition: common.hpp:203
constexpr size_t ITERATION_CHUNK_SIZE
For functions that lazy load a large CSV, this determines how many bytes are read at a time.
Definition: common.hpp:151
bool is_equal(T a, T b, T epsilon=0.001)
Definition: common.hpp:154
const int PAGE_SIZE
Size of a memory page in bytes.
Definition: common.hpp:145
ParseFlags
An enum used for describing the significance of each character with respect to CSV parsing.
Definition: common.hpp:166
@ 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:176
The all encompassing namespace.
constexpr int CSV_NOT_FOUND
Integer indicating a requested column wasn't found.
Definition: common.hpp:207
nonstd::string_view string_view
The string_view class used by this library.
Definition: common.hpp:75