15#if !defined(CSV_ENABLE_THREADS) || CSV_ENABLE_THREADS
20# ifndef WIN32_LEAN_AND_MEAN
21# define WIN32_LEAN_AND_MEAN
26#elif defined(__linux__)
32#if defined(__EMSCRIPTEN__)
33#undef CSV_ENABLE_THREADS
34#define CSV_ENABLE_THREADS 0
35#elif !defined(CSV_ENABLE_THREADS)
36#define CSV_ENABLE_THREADS 1
40#if defined(CSV_CODE_COVERAGE)
43 #define CSV_FORCE_INLINE inline
45 #define CSV_NON_NULL(...)
46#elif defined(__clang__) || defined(__GNUC__)
47 #define CSV_CONST __attribute__((__const__))
48 #define CSV_PURE __attribute__((__pure__))
49 #define CSV_FORCE_INLINE inline __attribute__((__always_inline__))
53 #define CSV_PRIVATE __attribute__((__visibility__("hidden")))
55 #define CSV_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
56#elif defined(_MSC_VER)
59 #define CSV_FORCE_INLINE __forceinline
61 #define CSV_NON_NULL(...)
65 #define CSV_FORCE_INLINE inline
67 #define CSV_NON_NULL(...)
73# define CSV_MSVC_PUSH_DISABLE(w) __pragma(warning(push)) __pragma(warning(disable: w))
74# define CSV_MSVC_POP __pragma(warning(pop))
76# define CSV_MSVC_PUSH_DISABLE(w)
81#if defined(__cpp_exceptions) || defined(_CPPUNWIND) || defined(__EXCEPTIONS)
82#define CSV_EXCEPTIONS_ENABLED 1
84#define CSV_EXCEPTIONS_ENABLED 0
92#if CSV_EXCEPTIONS_ENABLED
94#define CSV_CATCH(exception_declaration, ...) catch exception_declaration __VA_ARGS__
97#define CSV_CATCH(exception_declaration, ...)
103#if defined(_MSVC_LANG) && _MSVC_LANG > __cplusplus
104# define CSV_CPLUSPLUS _MSVC_LANG
106# define CSV_CPLUSPLUS __cplusplus
109#if CSV_CPLUSPLUS >= 202302L
113#if CSV_CPLUSPLUS >= 202002L
117#if CSV_CPLUSPLUS >= 201703L
121#if CSV_CPLUSPLUS >= 201402L
127#if defined(CSV_HAS_CXX17)
128#define CSV_FALLTHROUGH [[fallthrough]]
129#elif defined(__clang__) && defined(__has_cpp_attribute)
130#if __has_cpp_attribute(clang::fallthrough)
131#define CSV_FALLTHROUGH [[clang::fallthrough]]
133#define CSV_FALLTHROUGH ((void)0)
135#elif defined(__GNUC__) && __GNUC__ >= 7
136#define CSV_FALLTHROUGH __attribute__((fallthrough))
138#define CSV_FALLTHROUGH ((void)0)
143#include <string_view>
145#include "../external/string_view.hpp"
154#pragma region Compatibility Macros
170#define STATIC_ASSERT(x) static_assert(x, "Assertion failed")
173 #define CSV_DEBUG_ASSERT(x) ((void)sizeof(x), (void)0)
175 #define CSV_DEBUG_ASSERT(x) assert(x)
191 #define IF_CONSTEXPR if constexpr
192 #define CONSTEXPR_VALUE constexpr
194 #define CONSTEXPR_17 constexpr
196 #define IF_CONSTEXPR if
197 #define CONSTEXPR_VALUE const
199 #define CONSTEXPR_17 inline
203 template<
bool B,
class T =
void>
204 using enable_if_t = std::enable_if_t<B, T>;
206 #define CONSTEXPR_14 constexpr
207 #define CONSTEXPR_VALUE_14 constexpr
209 template<
bool B,
class T =
void>
210 using enable_if_t =
typename std::enable_if<B, T>::type;
212 #define CONSTEXPR_14 inline
213 #define CONSTEXPR_VALUE_14 const
216 namespace internals {
217 template<
bool B,
class T =
void>
218 using enable_if_t = csv::enable_if_t<B, T>;
222 template<
typename F,
typename... Args>
223 using invoke_result_t =
typename std::invoke_result<F, Args...>::type;
225 template<
typename F,
typename... Args>
226 using invoke_result_t =
typename std::result_of<F(Args...)>::type;
229 template<
typename... Ts>
232 template<
typename F,
typename ReturnType,
typename Enable,
typename... Args>
235 template<
typename F,
typename ReturnType,
typename... Args>
239 void_t<invoke_result_t<F, Args...>>,
241 > : std::integral_constant<
243 std::is_convertible<invoke_result_t<F, Args...>, ReturnType>::value
246 template<
typename F,
typename ReturnType,
typename... Args>
253#if defined(__GNUC__) && !defined(__clang__)
254 #if defined(CSV_HAS_CXX17) && (((__GNUC__ == 7) && (__GNUC_MINOR__ >= 2)) || (__GNUC__ >= 8))
255 #define CONSTEXPR constexpr
259 #define CONSTEXPR constexpr
264#define CONSTEXPR inline
271 namespace internals {
276 static auto test(
int) ->
decltype(
277 std::hash<U>{}(std::declval<const U&>()),
282 static std::false_type test(...);
285 static constexpr bool value =
decltype(test<T>(0))::value;
292 static auto test(
int) ->
decltype(
293 std::declval<const U&>() == std::declval<const U&>(),
298 static std::false_type test(...);
301 static constexpr bool value =
decltype(test<T>(0))::value;
314 if (
this != &other) {
315 value_ = std::move(other.value_);
321 template<
typename Factory>
322 T& get_or_create(Factory&& factory)
const {
323#if CSV_ENABLE_THREADS
324 std::call_once(init_once_, [
this, &factory]() {
335 T* get()
const noexcept {
340 mutable std::shared_ptr<T> value_ =
nullptr;
341#if CSV_ENABLE_THREADS
342 mutable std::once_flag init_once_;
348 #pragma region CXX20 Concepts
353 std::ranges::input_range<std::remove_reference_t<T>>
354 && std::convertible_to<
355 std::ranges::range_reference_t<std::remove_reference_t<T>>,
361 { value.to_sv_range() } -> std::ranges::input_range;
362 requires std::convertible_to<
363 std::ranges::range_reference_t<
decltype(value.to_sv_range())>,
373 std::ranges::input_range<std::remove_reference_t<T>>
375 std::ranges::range_reference_t<std::remove_reference_t<T>>
384#if defined(PAGE_SIZE)
390 inline int getpagesize() {
391 _SYSTEM_INFO sys_info = {};
392 GetSystemInfo(&sys_info);
393 return std::max(sys_info.dwPageSize, sys_info.dwAllocationGranularity);
397#elif defined(__linux__)
421 CONSTEXPR_VALUE_14
CSVChunkIndex CSV_CHUNK_INDEX_MAX = (std::numeric_limits<CSVChunkIndex>::max)();
423 CONSTEXPR_VALUE_14
size_t CSV_CHUNK_SIZE_MAX = CSV_CHUNK_INDEX_MAX;
436 inline bool is_equal(T a, T b, T epsilon = 0.001) {
438 static_assert(std::is_floating_point<T>::value,
"T must be a floating point type.");
439 return std::abs(a - b) < epsilon;
460 return (
ParseFlags)((int)flag & ~((
int)ParseFlags::QUOTE * quote_escape));
465 STATIC_ASSERT(ParseFlags::DELIMITER < ParseFlags::CARRIAGE_RETURN);
466 STATIC_ASSERT(ParseFlags::DELIMITER < ParseFlags::NEWLINE);
467 STATIC_ASSERT(ParseFlags::CARRIAGE_RETURN < ParseFlags::NEWLINE);
476 STATIC_ASSERT(
quote_escape_flag(ParseFlags::DELIMITER,
false) == ParseFlags::DELIMITER);
477 STATIC_ASSERT(
quote_escape_flag(ParseFlags::CARRIAGE_RETURN,
false) == ParseFlags::CARRIAGE_RETURN);
478 STATIC_ASSERT(
quote_escape_flag(ParseFlags::NEWLINE,
false) == ParseFlags::NEWLINE);
480 STATIC_ASSERT(
quote_escape_flag(ParseFlags::NOT_SPECIAL,
true) == ParseFlags::NOT_SPECIAL);
481 STATIC_ASSERT(
quote_escape_flag(ParseFlags::QUOTE,
true) == ParseFlags::QUOTE_ESCAPE_QUOTE);
482 STATIC_ASSERT(
quote_escape_flag(ParseFlags::DELIMITER,
true) == ParseFlags::NOT_SPECIAL);
483 STATIC_ASSERT(
quote_escape_flag(ParseFlags::CARRIAGE_RETURN,
true) == ParseFlags::NOT_SPECIAL);
484 STATIC_ASSERT(
quote_escape_flag(ParseFlags::NEWLINE,
true) == ParseFlags::NOT_SPECIAL);
497 constexpr unsigned CHAR_OFFSET = std::numeric_limits<char>::is_signed ? 128 : 0;
std::array< ParseFlags, 256 > ParseFlagMap
An array which maps ASCII chars to a parsing flag.
std::array< bool, 256 > WhitespaceMap
An array which maps ASCII chars to a flag indicating if it is whitespace.
bool is_equal(T a, T b, T epsilon=0.001)
const int PAGE_SIZE
Size of a memory page in bytes.
ParseFlags
An enum used for describing the significance of each character with respect to CSV parsing.
@ 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.
@ CARRIAGE_RETURN
Characters which signify a carriage return.
@ QUOTE
Characters which may signify a quote escape.
@ DELIMITER
Characters which signify a new field.
constexpr size_t CSV_CHUNK_SIZE_FLOOR
Minimum supported custom chunk size for CSVFormat::chunk_size().
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.
std::uint32_t CSVChunkIndex
Type used to represent the location of a CSV byte within a larger chunk.
constexpr size_t CSV_SPECULATIVE_PARALLEL_MIN_BYTES
Default minimum source size before speculative parallel parsing is considered.
constexpr size_t CSV_CHUNK_SIZE_DEFAULT
Default chunk size for lazy-loading large CSV files.
The all encompassing namespace.
constexpr int CSV_NOT_FOUND
Integer indicating a requested column wasn't found.
constexpr unsigned CHAR_OFFSET
Offset to convert char into array index.
std::string_view string_view
The string_view class used by this library.