17#ifndef ADA_IDNA_UNICODE_TRANSCODING_H
18#define ADA_IDNA_UNICODE_TRANSCODING_H
25size_t utf8_to_utf32(
const char* buf,
size_t len,
char32_t* utf32_output);
31size_t utf32_to_utf8(
const char32_t* buf,
size_t len,
char* utf8_output);
38#ifndef ADA_IDNA_MAPPING_H
39#define ADA_IDNA_MAPPING_H
47void ascii_map(
char* input,
size_t length);
51std::u32string
map(std::u32string_view input);
58#ifndef ADA_IDNA_NORMALIZATION_H
59#define ADA_IDNA_NORMALIZATION_H
73#ifndef ADA_IDNA_PUNYCODE_H
74#define ADA_IDNA_PUNYCODE_H
90#ifndef ADA_IDNA_VALIDITY_H
91#define ADA_IDNA_VALIDITY_H
108#ifndef ADA_IDNA_TO_ASCII_H
109#define ADA_IDNA_TO_ASCII_H
112#include <string_view>
125std::string
to_ascii(std::string_view ut8_string);
132bool begins_with(std::u32string_view view, std::u32string_view prefix);
133bool begins_with(std::string_view view, std::string_view prefix);
135bool constexpr is_ascii(std::u32string_view view);
136bool constexpr is_ascii(std::string_view view);
144#ifndef ADA_IDNA_TO_UNICODE_H
145#define ADA_IDNA_TO_UNICODE_H
147#include <string_view>
151std::string
to_unicode(std::string_view input);
168#ifndef ADA_CHARACTER_SETS_INL_H
169#define ADA_CHARACTER_SETS_INL_H
178#ifndef ADA_CHARACTER_SETS_H
179#define ADA_CHARACTER_SETS_H
186#ifndef ADA_COMMON_DEFS_H
187#define ADA_COMMON_DEFS_H
190#define ADA_VISUAL_STUDIO 1
198#define ADA_CLANG_VISUAL_STUDIO 1
201#define ADA_REGULAR_VISUAL_STUDIO 1
207#define ADA_BEGIN_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-BEGIN " #name);
208#define ADA_END_DEBUG_BLOCK(name) __asm volatile("# LLVM-MCA-END " #name);
209#define ADA_DEBUG_BLOCK(name, block) \
210 BEGIN_DEBUG_BLOCK(name); \
212 END_DEBUG_BLOCK(name);
214#define ADA_BEGIN_DEBUG_BLOCK(name)
215#define ADA_END_DEBUG_BLOCK(name)
216#define ADA_DEBUG_BLOCK(name, block)
220#define ADA_ROUNDUP_N(a, n) (((a) + ((n)-1)) & ~((n)-1))
221#define ADA_ROUNDDOWN_N(a, n) ((a) & ~((n)-1))
223#define ADA_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
225#if defined(ADA_REGULAR_VISUAL_STUDIO)
227#define ada_really_inline __forceinline
228#define ada_never_inline __declspec(noinline)
231#define ada_warn_unused
234#define ada_likely(x) x
237#define ada_unlikely(x) x
240#define ADA_PUSH_DISABLE_WARNINGS __pragma(warning(push))
241#define ADA_PUSH_DISABLE_ALL_WARNINGS __pragma(warning(push, 0))
242#define ADA_DISABLE_VS_WARNING(WARNING_NUMBER) \
243 __pragma(warning(disable : WARNING_NUMBER))
248#if __has_include(<CppCoreCheck\Warnings.h>)
249#include <CppCoreCheck\Warnings.h>
250#define ADA_DISABLE_UNDESIRED_WARNINGS \
251 ADA_DISABLE_VS_WARNING(ALL_CPPCORECHECK_WARNINGS)
255#ifndef ADA_DISABLE_UNDESIRED_WARNINGS
256#define ADA_DISABLE_UNDESIRED_WARNINGS
259#define ADA_DISABLE_DEPRECATED_WARNING ADA_DISABLE_VS_WARNING(4996)
260#define ADA_DISABLE_STRICT_OVERFLOW_WARNING
261#define ADA_POP_DISABLE_WARNINGS __pragma(warning(pop))
265#define ada_really_inline inline __attribute__((always_inline))
266#define ada_never_inline inline __attribute__((noinline))
268#define ada_unused __attribute__((unused))
269#define ada_warn_unused __attribute__((warn_unused_result))
272#define ada_likely(x) __builtin_expect(!!(x), 1)
275#define ada_unlikely(x) __builtin_expect(!!(x), 0)
278#define ADA_PUSH_DISABLE_WARNINGS _Pragma("GCC diagnostic push")
281#define ADA_PUSH_DISABLE_ALL_WARNINGS \
282 ADA_PUSH_DISABLE_WARNINGS \
283 ADA_DISABLE_GCC_WARNING("-Weffc++") \
284 ADA_DISABLE_GCC_WARNING("-Wall") \
285 ADA_DISABLE_GCC_WARNING("-Wconversion") \
286 ADA_DISABLE_GCC_WARNING("-Wextra") \
287 ADA_DISABLE_GCC_WARNING("-Wattributes") \
288 ADA_DISABLE_GCC_WARNING("-Wimplicit-fallthrough") \
289 ADA_DISABLE_GCC_WARNING("-Wnon-virtual-dtor") \
290 ADA_DISABLE_GCC_WARNING("-Wreturn-type") \
291 ADA_DISABLE_GCC_WARNING("-Wshadow") \
292 ADA_DISABLE_GCC_WARNING("-Wunused-parameter") \
293 ADA_DISABLE_GCC_WARNING("-Wunused-variable")
294#define ADA_PRAGMA(P) _Pragma(#P)
295#define ADA_DISABLE_GCC_WARNING(WARNING) \
296 ADA_PRAGMA(GCC diagnostic ignored WARNING)
297#if defined(ADA_CLANG_VISUAL_STUDIO)
298#define ADA_DISABLE_UNDESIRED_WARNINGS \
299 ADA_DISABLE_GCC_WARNING("-Wmicrosoft-include")
301#define ADA_DISABLE_UNDESIRED_WARNINGS
303#define ADA_DISABLE_DEPRECATED_WARNING \
304 ADA_DISABLE_GCC_WARNING("-Wdeprecated-declarations")
305#define ADA_DISABLE_STRICT_OVERFLOW_WARNING \
306 ADA_DISABLE_GCC_WARNING("-Wstrict-overflow")
307#define ADA_POP_DISABLE_WARNINGS _Pragma("GCC diagnostic pop")
311#if defined(ADA_VISUAL_STUDIO)
318#define ADA_DLLIMPORTEXPORT __declspec(dllimport)
320#define ADA_DLLIMPORTEXPORT __declspec(dllexport)
323#define ADA_DLLIMPORTEXPORT
327#define ADA_TRY(EXPR) \
329 auto _err = (EXPR); \
336#if !defined(__has_cpp_attribute)
337#define __has_cpp_attribute(x) 0
340#if __has_cpp_attribute(gnu::noinline)
341#define ADA_ATTRIBUTE_NOINLINE [[gnu::noinline]]
343#define ADA_ATTRIBUTE_NOINLINE
349 __builtin_unreachable();
350#elif defined(_MSC_VER)
357#if defined(__GNUC__) && !defined(__clang__)
366#define ada_constexpr constexpr
369#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
370#define ADA_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
372#define ADA_IS_BIG_ENDIAN 0
374#if defined(__APPLE__) || \
377#include <machine/endian.h>
378#elif defined(sun) || \
380#include <sys/byteorder.h>
384#if __has_include(<endian.h>)
391#ifndef !defined(__BYTE_ORDER__) || !defined(__ORDER_LITTLE_ENDIAN__)
392#define ADA_IS_BIG_ENDIAN 0
395#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
396#define ADA_IS_BIG_ENDIAN 0
398#define ADA_IS_BIG_ENDIAN 1
413#if !defined(ADA_DEVELOPMENT_CHECKS) && !defined(NDEBUG)
417#define ADA_DEVELOPMENT_CHECKS 1
423#define ADA_DEVELOPMENT_CHECKS 1
430#if ADA_DEVELOPMENT_CHECKS
431#define ADA_REQUIRE(EXPR) \
433 if (!(EXPR) { abort(); }) }
435#define ADA_FAIL(MESSAGE) \
437 std::cerr << "FAIL: " << (MESSAGE) << std::endl; \
440#define ADA_ASSERT_EQUAL(LHS, RHS, MESSAGE) \
443 std::cerr << "Mismatch: '" << LHS << "' - '" << RHS << "'" << std::endl; \
447#define ADA_ASSERT_TRUE(COND) \
450 std::cerr << "Assert at line " << __LINE__ << " of file " << __FILE__ \
452 ADA_FAIL(ADA_STR(COND)); \
456#define ADA_FAIL(MESSAGE)
457#define ADA_ASSERT_EQUAL(LHS, RHS, MESSAGE)
458#define ADA_ASSERT_TRUE(COND)
461#ifdef ADA_VISUAL_STUDIO
462#define ADA_ASSUME(COND) __assume(COND)
464#define ADA_ASSUME(COND) \
467 __builtin_unreachable(); \
472#if defined(__SSE2__) || defined(__x86_64__) || defined(__x86_64) || \
473 (defined(_M_AMD64) || defined(_M_X64) || \
474 (defined(_M_IX86_FP) && _M_IX86_FP == 2))
478#if defined(__aarch64__) || defined(_M_ARM64)
507constexpr char hex[1024] =
508 "%00\0%01\0%02\0%03\0%04\0%05\0%06\0%07\0"
509 "%08\0%09\0%0A\0%0B\0%0C\0%0D\0%0E\0%0F\0"
510 "%10\0%11\0%12\0%13\0%14\0%15\0%16\0%17\0"
511 "%18\0%19\0%1A\0%1B\0%1C\0%1D\0%1E\0%1F\0"
512 "%20\0%21\0%22\0%23\0%24\0%25\0%26\0%27\0"
513 "%28\0%29\0%2A\0%2B\0%2C\0%2D\0%2E\0%2F\0"
514 "%30\0%31\0%32\0%33\0%34\0%35\0%36\0%37\0"
515 "%38\0%39\0%3A\0%3B\0%3C\0%3D\0%3E\0%3F\0"
516 "%40\0%41\0%42\0%43\0%44\0%45\0%46\0%47\0"
517 "%48\0%49\0%4A\0%4B\0%4C\0%4D\0%4E\0%4F\0"
518 "%50\0%51\0%52\0%53\0%54\0%55\0%56\0%57\0"
519 "%58\0%59\0%5A\0%5B\0%5C\0%5D\0%5E\0%5F\0"
520 "%60\0%61\0%62\0%63\0%64\0%65\0%66\0%67\0"
521 "%68\0%69\0%6A\0%6B\0%6C\0%6D\0%6E\0%6F\0"
522 "%70\0%71\0%72\0%73\0%74\0%75\0%76\0%77\0"
523 "%78\0%79\0%7A\0%7B\0%7C\0%7D\0%7E\0%7F\0"
524 "%80\0%81\0%82\0%83\0%84\0%85\0%86\0%87\0"
525 "%88\0%89\0%8A\0%8B\0%8C\0%8D\0%8E\0%8F\0"
526 "%90\0%91\0%92\0%93\0%94\0%95\0%96\0%97\0"
527 "%98\0%99\0%9A\0%9B\0%9C\0%9D\0%9E\0%9F\0"
528 "%A0\0%A1\0%A2\0%A3\0%A4\0%A5\0%A6\0%A7\0"
529 "%A8\0%A9\0%AA\0%AB\0%AC\0%AD\0%AE\0%AF\0"
530 "%B0\0%B1\0%B2\0%B3\0%B4\0%B5\0%B6\0%B7\0"
531 "%B8\0%B9\0%BA\0%BB\0%BC\0%BD\0%BE\0%BF\0"
532 "%C0\0%C1\0%C2\0%C3\0%C4\0%C5\0%C6\0%C7\0"
533 "%C8\0%C9\0%CA\0%CB\0%CC\0%CD\0%CE\0%CF\0"
534 "%D0\0%D1\0%D2\0%D3\0%D4\0%D5\0%D6\0%D7\0"
535 "%D8\0%D9\0%DA\0%DB\0%DC\0%DD\0%DE\0%DF\0"
536 "%E0\0%E1\0%E2\0%E3\0%E4\0%E5\0%E6\0%E7\0"
537 "%E8\0%E9\0%EA\0%EB\0%EC\0%ED\0%EE\0%EF\0"
538 "%F0\0%F1\0%F2\0%F3\0%F4\0%F5\0%F6\0%F7\0"
539 "%F8\0%F9\0%FA\0%FB\0%FC\0%FD\0%FE\0%FF";
543 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
545 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
547 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
549 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
551 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
553 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
555 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
557 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
559 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
561 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
563 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
565 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
567 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
569 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
571 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
573 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x80,
575 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
577 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
579 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
581 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
583 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
585 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
587 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
589 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
591 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
593 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
595 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
597 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
599 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
601 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
603 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
605 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
609 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
611 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
613 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
615 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
617 0x01 | 0x00 | 0x04 | 0x08 | 0x00 | 0x00 | 0x00 | 0x80,
619 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
621 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
623 0x00 | 0x00 | 0x00 | 0x00 | 0x10 | 0x00 | 0x40 | 0x00,
625 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
627 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
629 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
631 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
633 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
635 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
637 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
639 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x80,
641 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
643 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
645 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
647 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
649 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
651 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
653 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
655 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
657 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
659 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
661 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
663 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
665 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
667 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
669 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
671 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
675 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
677 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
679 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
681 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
683 0x01 | 0x00 | 0x04 | 0x08 | 0x00 | 0x00 | 0x00 | 0x00,
685 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
687 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
689 0x00 | 0x00 | 0x00 | 0x00 | 0x10 | 0x00 | 0x40 | 0x00,
691 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
693 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
695 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
697 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
699 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
701 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
703 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
705 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x80,
707 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
709 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
711 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
713 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
715 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
717 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
719 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
721 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
723 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
725 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
727 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
729 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
731 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
733 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
735 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
737 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
741 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
743 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
745 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
747 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
749 0x01 | 0x00 | 0x04 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
751 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
753 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
755 0x00 | 0x00 | 0x00 | 0x00 | 0x10 | 0x00 | 0x40 | 0x00,
757 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
759 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
761 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
763 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
765 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
767 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
769 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
771 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x80,
773 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
775 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
777 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
779 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
781 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
783 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
785 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
787 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
789 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
791 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
793 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
795 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
797 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
799 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
801 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
803 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
807 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
809 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
811 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
813 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
815 0x01 | 0x00 | 0x04 | 0x08 | 0x00 | 0x00 | 0x00 | 0x00,
817 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x80,
819 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
821 0x00 | 0x00 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
823 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
825 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
827 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
829 0x00 | 0x00 | 0x00 | 0x08 | 0x10 | 0x20 | 0x40 | 0x00,
831 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
833 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
835 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
837 0x00 | 0x00 | 0x00 | 0x08 | 0x10 | 0x20 | 0x00 | 0x80,
839 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
841 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
843 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
845 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
847 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
849 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
851 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
853 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
855 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
857 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
859 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
861 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
863 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
865 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
867 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
869 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
873 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
875 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
877 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
879 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
881 0x01 | 0x00 | 0x04 | 0x08 | 0x00 | 0x00 | 0x00 | 0x00,
883 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
885 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
887 0x00 | 0x00 | 0x00 | 0x00 | 0x10 | 0x00 | 0x40 | 0x80,
889 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
891 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
893 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
895 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
897 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
899 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
901 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
903 0x00 | 0x00 | 0x00 | 0x08 | 0x00 | 0x20 | 0x00 | 0x80,
905 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
907 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
909 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
911 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
913 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
915 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
917 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
919 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
921 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
923 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
925 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
927 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
929 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
931 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
933 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
935 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
939 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
941 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
943 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
945 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
947 0x00 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
949 0x01 | 0x02 | 0x00 | 0x08 | 0x10 | 0x00 | 0x00 | 0x80,
951 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
953 0x00 | 0x00 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
955 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
957 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
959 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
961 0x00 | 0x00 | 0x00 | 0x08 | 0x00 | 0x20 | 0x40 | 0x00,
963 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
965 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
967 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
969 0x00 | 0x00 | 0x00 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
971 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
973 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
975 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
977 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
979 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
981 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
983 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
985 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
987 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
989 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
991 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
993 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
995 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
997 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
999 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
1001 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
1004 return !!(a[i >> 3] & (1 << (i & 7)));
1016#ifndef ADA_CHECKERS_INL_H
1017#define ADA_CHECKERS_INL_H
1021#include <string_view>
1028 uint32_t value_one = 1;
1029 bool is_little_endian = (
reinterpret_cast<char*
>(&value_one)[0] == 1);
1031 std::memcpy(&word0x,
"0x", 2);
1033 uint16_t two_first_bytes{};
1034 std::memcpy(&two_first_bytes, input.data(), 2);
1035 if (is_little_endian) {
1036 two_first_bytes |= 0x2000;
1038 two_first_bytes |= 0x020;
1040 return two_first_bytes == word0x;
1047constexpr bool is_digit(
char x)
noexcept {
return (x >=
'0') & (x <=
'9'); }
1049constexpr char to_lower(
char x)
noexcept {
return (x | 0x20); }
1051constexpr bool is_alpha(
char x)
noexcept {
1056 return input.size() >= 2 &&
1057 (
is_alpha(input[0]) && ((input[1] ==
':') || (input[1] ==
'|'))) &&
1058 ((input.size() == 2) || (input[2] ==
'/' || input[2] ==
'\\' ||
1059 input[2] ==
'?' || input[2] ==
'#'));
1063 std::string_view input)
noexcept {
1064 return input.size() >= 2 && (
is_alpha(input[0]) && (input[1] ==
':'));
1068 std::string_view prefix) {
1071 return view.size() >= prefix.size() &&
1072 std::equal(prefix.begin(), prefix.end(), view.begin());
1091#define ADA_LOGGING 0
1100template <
typename T>
1103 std::cout << t << std::endl;
1111template <
typename T,
typename... Args>
1113 [[maybe_unused]] Args... args) {
1124template <
typename T,
typename... Args>
1126 [[maybe_unused]] Args... args) {
1128 std::cout <<
"ADA_LOG: " << t;
1137template <
typename T>
1140 std::cout <<
"ADA_LOG: " << t << std::endl;
1148#define ada_log(...) \
1150 ada::log(__VA_ARGS__); \
1164#ifndef ADA_ENCODING_TYPE_H
1165#define ADA_ENCODING_TYPE_H
1197#ifndef ADA_HELPERS_H
1198#define ADA_HELPERS_H
1332#ifndef ADA_URL_BASE_H
1333#define ADA_URL_BASE_H
1340#ifndef ADA_URL_COMPONENTS_H
1341#define ADA_URL_COMPONENTS_H
1345#include <string_view>
1358 constexpr static uint32_t
omitted = uint32_t(-1);
1477constexpr uint16_t get_special_port(std::string_view scheme)
noexcept;
1495#include <string_view>
1562 [[nodiscard]] virtual std::
string get_origin() const noexcept = 0;
1577 [[nodiscard]] inline uint16_t get_special_port() const noexcept;
1597 virtual
size_t parse_port(std::string_view view,
1598 bool check_trailing_content) noexcept = 0;
1601 return this->parse_port(view,
false);
1610 virtual inline void clear_pathname() = 0;
1613 virtual inline void clear_search() = 0;
1616 [[nodiscard]]
virtual inline bool has_hash() const noexcept = 0;
1619 [[nodiscard]] virtual inline
bool has_search() const noexcept = 0;
1628#include <string_view>
1644template <
typename out_iter>
1645void encode_json(std::string_view view, out_iter out);
1661 std::string_view& input)
noexcept;
1708 size_t pos)
noexcept;
1714bool overlaps(std::string_view input1,
const std::string& input2)
noexcept;
1723 size_t pos2)
noexcept {
1724#if ADA_DEVELOPMENT_CHECKS
1726 std::cerr <<
"Negative-length substring: [" << pos1 <<
" to " << pos2 <<
")"
1731 return std::string_view(input.data() + pos1, pos2 - pos1);
1747 const bool is_special, std::string_view& view)
noexcept;
1761template <
class url_type>
1763 url_type&
url)
noexcept;
1770find_authority_delimiter_special(std::string_view view)
noexcept;
1777find_authority_delimiter(std::string_view view)
noexcept;
1782template <
typename T,
typename... Args>
1783inline void inner_concat(std::string& buffer, T t) {
1790template <
typename T,
typename... Args>
1791inline void inner_concat(std::string& buffer, T t, Args... args) {
1793 return inner_concat(buffer, args...);
1801template <
typename... Args>
1802std::string concat(Args... args) {
1804 inner_concat(answer, args...);
1812inline int leading_zeroes(uint32_t input_num)
noexcept {
1813#if ADA_REGULAR_VISUAL_STUDIO
1814 unsigned long leading_zero(0);
1815 unsigned long in(input_num);
1816 return _BitScanReverse(&leading_zero, in) ? int(31 - leading_zero) : 32;
1818 return __builtin_clz(input_num);
1828inline int fast_digit_count(uint32_t x)
noexcept {
1829 auto int_log2 = [](uint32_t z) ->
int {
1830 return 31 - ada::helpers::leading_zeroes(z | 1);
1836 const static uint64_t table[] = {
1837 4294967296, 8589934582, 8589934582, 8589934582, 12884901788,
1838 12884901788, 12884901788, 17179868184, 17179868184, 17179868184,
1839 21474826480, 21474826480, 21474826480, 21474826480, 25769703776,
1840 25769703776, 25769703776, 30063771072, 30063771072, 30063771072,
1841 34349738368, 34349738368, 34349738368, 34349738368, 38554705664,
1842 38554705664, 38554705664, 41949672960, 41949672960, 41949672960,
1843 42949672960, 42949672960};
1844 return int((x + table[int_log2(x)]) >> 32);
1859#include <string_view>
1882#ifndef TL_EXPECTED_HPP
1883#define TL_EXPECTED_HPP
1885#define TL_EXPECTED_VERSION_MAJOR 1
1886#define TL_EXPECTED_VERSION_MINOR 1
1887#define TL_EXPECTED_VERSION_PATCH 0
1890#include <functional>
1891#include <type_traits>
1894#if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
1895#define TL_EXPECTED_EXCEPTIONS_ENABLED
1898#if (defined(_MSC_VER) && _MSC_VER == 1900)
1899#define TL_EXPECTED_MSVC2015
1900#define TL_EXPECTED_MSVC2015_CONSTEXPR
1902#define TL_EXPECTED_MSVC2015_CONSTEXPR constexpr
1905#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
1906 !defined(__clang__))
1907#define TL_EXPECTED_GCC49
1910#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \
1911 !defined(__clang__))
1912#define TL_EXPECTED_GCC54
1915#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \
1916 !defined(__clang__))
1917#define TL_EXPECTED_GCC55
1920#if !defined(TL_ASSERT)
1922#if (__cplusplus > 201103L) && !defined(TL_EXPECTED_GCC49)
1924#define TL_ASSERT(x) assert(x)
1930#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
1931 !defined(__clang__))
1934#define TL_EXPECTED_NO_CONSTRR
1936#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
1937 std::has_trivial_copy_constructor<T>
1938#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
1939 std::has_trivial_copy_assign<T>
1942#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \
1943 std::is_trivially_destructible<T>
1947#elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__))
1948#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
1949#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
1953struct is_trivially_copy_constructible
1954 : std::is_trivially_copy_constructible<T> {};
1955#ifdef _GLIBCXX_VECTOR
1956template <
class T,
class A>
1957struct is_trivially_copy_constructible<std::vector<T, A>> : std::false_type {};
1963#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
1964 tl::detail::is_trivially_copy_constructible<T>
1965#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
1966 std::is_trivially_copy_assignable<T>
1967#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \
1968 std::is_trivially_destructible<T>
1970#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
1971 std::is_trivially_copy_constructible<T>
1972#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
1973 std::is_trivially_copy_assignable<T>
1974#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \
1975 std::is_trivially_destructible<T>
1978#if __cplusplus > 201103L
1979#define TL_EXPECTED_CXX14
1982#ifdef TL_EXPECTED_GCC49
1983#define TL_EXPECTED_GCC49_CONSTEXPR
1985#define TL_EXPECTED_GCC49_CONSTEXPR constexpr
1988#if (__cplusplus == 201103L || defined(TL_EXPECTED_MSVC2015) || \
1989 defined(TL_EXPECTED_GCC49))
1990#define TL_EXPECTED_11_CONSTEXPR
1992#define TL_EXPECTED_11_CONSTEXPR constexpr
1996template <
class T,
class E>
1999#ifndef TL_MONOSTATE_INPLACE_MUTEX
2000#define TL_MONOSTATE_INPLACE_MUTEX
2012 static_assert(!std::is_same<E, void>::value,
"E must not be void");
2019 template <
class... Args,
typename std::enable_if<std::is_constructible<
2020 E, Args &&...>::value>::type * =
nullptr>
2022 : m_val(std::forward<Args>(args)...) {}
2024 class U,
class... Args,
2025 typename std::enable_if<std::is_constructible<
2026 E, std::initializer_list<U> &, Args &&...>::value>::type * =
nullptr>
2027 constexpr explicit unexpected(std::initializer_list<U> l, Args &&...args)
2028 : m_val(l, std::forward<Args>(args)...) {}
2030 constexpr const E &
value() const & {
return m_val; }
2033 constexpr const E &&
value() const && {
return std::move(m_val); }
2039#ifdef __cpp_deduction_guides
2041unexpected(E) -> unexpected<E>;
2080template <
typename E>
2082#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
2083 throw std::forward<E>(e);
2089 __builtin_unreachable();
2094#ifndef TL_TRAITS_MUTEX
2095#define TL_TRAITS_MUTEX
2103template <
bool E,
class T =
void>
2105template <
bool B,
class T,
class F>
2113template <
class B,
class... Bs>
2115 : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
2117#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
2118#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
2124#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
2126struct is_pointer_to_non_const_member_func : std::false_type {};
2127template <
class T,
class Ret,
class... Args>
2128struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)>
2129 : std::true_type {};
2130template <
class T,
class Ret,
class... Args>
2131struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &>
2132 : std::true_type {};
2133template <
class T,
class Ret,
class... Args>
2134struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &&>
2135 : std::true_type {};
2136template <
class T,
class Ret,
class... Args>
2137struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile>
2138 : std::true_type {};
2139template <
class T,
class Ret,
class... Args>
2140struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile &>
2141 : std::true_type {};
2142template <
class T,
class Ret,
class... Args>
2143struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile &&>
2144 : std::true_type {};
2147struct is_const_or_const_ref : std::false_type {};
2149struct is_const_or_const_ref<T const &> : std::true_type {};
2151struct is_const_or_const_ref<T const> : std::true_type {};
2157 typename Fn,
typename... Args,
2158#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
2159 typename =
enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value &&
2160 is_const_or_const_ref<Args...>::value)>,
2162 typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
int = 0>
2163constexpr auto invoke(Fn &&f, Args &&...args)
noexcept(
2164 noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
2165 ->
decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
2166 return std::mem_fn(f)(std::forward<Args>(args)...);
2169template <
typename Fn,
typename... Args,
2170 typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
2171constexpr auto invoke(Fn &&f, Args &&...args)
noexcept(
2172 noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
2173 ->
decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
2174 return std::forward<Fn>(f)(std::forward<Args>(args)...);
2178template <
class F,
class,
class... Us>
2181template <
class F,
class... Us>
2184 decltype(detail::
invoke(std::declval<F>(), std::declval<Us>()...), void()),
2187 decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
2190template <
class F,
class... Us>
2193template <
class F,
class... Us>
2196#if defined(_MSC_VER) && _MSC_VER <= 1900
2198template <
class T,
class U = T>
2201template <
class T,
class U = T>
2202struct is_nothrow_swappable : std::true_type {};
2205namespace swap_adl_tests {
2212template <
class T, std::
size_t N>
2217template <
class,
class>
2219template <class T, class U,
2220 class = decltype(swap(std::declval<T &>(), std::declval<U &>()))>
2221std::true_type can_swap(
int) noexcept(noexcept(swap(std::declval<T &>(),
2222 std::declval<U &>())));
2224template <class, class>
2225std::false_type uses_std(...);
2226template <class T, class U>
2227std::is_same<decltype(swap(std::declval<T &>(), std::declval<U &>())),
tag>
2232 : std::integral_constant<
bool,
2233 std::is_nothrow_move_constructible<T>::value &&
2234 std::is_nothrow_move_assignable<T>::value> {};
2236template <
class T, std::
size_t N>
2239template <
class T,
class U>
2241 : std::integral_constant<bool, noexcept(can_swap<T, U>(0))> {};
2244template <
class T,
class U = T>
2246 : std::integral_constant<
2248 decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
2249 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
2250 (std::is_move_assignable<T>::value &&
2251 std::is_move_constructible<T>::value))> {};
2253template <
class T, std::
size_t N>
2255 : std::integral_constant<
2257 decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
2258 (!decltype(detail::swap_adl_tests::uses_std<T[N], T[N]>(
2260 is_swappable<T, T>::value)> {};
2262template <
class T,
class U = T>
2264 : std::integral_constant<
2266 is_swappable<T, U>::value &&
2267 ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
2268 detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
2269 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
2270 detail::swap_adl_tests::is_adl_swap_noexcept<T, U>::value))> {};
2277template <
class T,
class E>
2282template <
class T,
class E,
class U>
2284 std::is_constructible<T, U &&>::value &&
2285 !std::is_same<detail::decay_t<U>,
in_place_t>::value &&
2289template <
class T,
class E,
class U,
class G,
class UR,
class GR>
2291 std::is_constructible<T, UR>::value &&
2292 std::is_constructible<E, GR>::value &&
2293 !std::is_constructible<T, expected<U, G> &>::value &&
2294 !std::is_constructible<T, expected<U, G> &&>::value &&
2295 !std::is_constructible<T, const expected<U, G> &>::value &&
2296 !std::is_constructible<T, const expected<U, G> &&>::value &&
2297 !std::is_convertible<expected<U, G> &, T>::value &&
2298 !std::is_convertible<expected<U, G> &&, T>::value &&
2299 !std::is_convertible<const expected<U, G> &, T>::value &&
2300 !std::is_convertible<const expected<U, G> &&, T>::value>;
2302template <
class T,
class U>
2331template <class T, class E, bool = std::is_trivially_destructible<T>::value,
2332 bool = std::is_trivially_destructible<E>::value>
2337 template <
class... Args,
2341 : m_val(std::forward<Args>(args)...), m_has_val(true) {}
2343 template <
class U,
class... Args,
2345 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2348 : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
2349 template <
class... Args,
2353 : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
2355 template <
class U,
class... Args,
2357 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2359 std::initializer_list<U> il,
2361 : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
2367 m_unexpect.~unexpected<E>();
2380template <
class T,
class E>
2385 template <
class... Args,
2389 : m_val(std::forward<Args>(args)...), m_has_val(true) {}
2391 template <
class U,
class... Args,
2393 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2396 : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
2397 template <
class... Args,
2401 : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
2403 template <
class U,
class... Args,
2405 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2407 std::initializer_list<U> il,
2409 : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
2421template <
class T,
class E>
2425 : m_no_init(), m_has_val(false) {}
2427 template <
class... Args,
2431 : m_val(std::forward<Args>(args)...), m_has_val(true) {}
2433 template <
class U,
class... Args,
2435 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2438 : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
2439 template <
class... Args,
2443 : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
2445 template <
class U,
class... Args,
2447 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2449 std::initializer_list<U> il,
2451 : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
2455 m_unexpect.~unexpected<E>();
2468template <
class T,
class E>
2473 template <
class... Args,
2477 : m_val(std::forward<Args>(args)...), m_has_val(true) {}
2479 template <
class U,
class... Args,
2481 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2484 : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
2485 template <
class... Args,
2489 : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
2491 template <
class U,
class... Args,
2493 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2495 std::initializer_list<U> il,
2497 : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
2526 template <
class... Args,
2530 : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
2532 template <
class U,
class... Args,
2534 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2536 std::initializer_list<U> il,
2538 : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
2557 template <
class... Args,
2561 : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
2563 template <
class U,
class... Args,
2565 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2567 std::initializer_list<U> il,
2569 : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
2573 m_unexpect.~unexpected<E>();
2586template <
class T,
class E>
2590 template <
class... Args>
2592 new (std::addressof(this->m_val)) T(std::forward<Args>(args)...);
2593 this->m_has_val =
true;
2596 template <
class Rhs>
2598 new (std::addressof(this->m_val)) T(std::forward<Rhs>(rhs).get());
2599 this->m_has_val =
true;
2602 template <
class... Args>
2604 new (std::addressof(this->m_unexpect))
2606 this->m_has_val =
false;
2609#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
2617 template <
class U = T,
2621 if (!this->m_has_val && rhs.m_has_val) {
2622 geterr().~unexpected<E>();
2623 construct(rhs.get());
2631 template <
class U = T,
2632 detail::enable_if_t<!std::is_nothrow_copy_constructible<U>::value &&
2633 std::is_nothrow_move_constructible<U>::value>
2635 void assign(
const expected_operations_base &rhs)
noexcept {
2636 if (!this->m_has_val && rhs.m_has_val) {
2638 geterr().~unexpected<E>();
2639 construct(std::move(tmp));
2650 template <
class U = T,
2651 detail::enable_if_t<!std::is_nothrow_copy_constructible<U>::value &&
2652 !std::is_nothrow_move_constructible<U>::value>
2654 void assign(
const expected_operations_base &rhs) {
2655 if (!this->m_has_val && rhs.m_has_val) {
2656 auto tmp = std::move(geterr());
2657 geterr().~unexpected<E>();
2659#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
2661 construct(rhs.get());
2663 geterr() = std::move(tmp);
2667 construct(rhs.get());
2675 template <
class U = T,
2676 detail::enable_if_t<std::is_nothrow_move_constructible<U>::value>
2678 void assign(expected_operations_base &&rhs)
noexcept {
2679 if (!this->m_has_val && rhs.m_has_val) {
2680 geterr().~unexpected<E>();
2681 construct(std::move(rhs).get());
2683 assign_common(std::move(rhs));
2687 template <
class U = T,
2688 detail::enable_if_t<!std::is_nothrow_move_constructible<U>::value>
2690 void assign(expected_operations_base &&rhs) {
2691 if (!this->m_has_val && rhs.m_has_val) {
2692 auto tmp = std::move(geterr());
2693 geterr().~unexpected<E>();
2694#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
2696 construct(std::move(rhs).get());
2698 geterr() = std::move(tmp);
2702 construct(std::move(rhs).get());
2705 assign_common(std::move(rhs));
2713 if (!this->m_has_val && rhs.m_has_val) {
2714 geterr().~unexpected<E>();
2715 construct(rhs.get());
2722 if (!this->m_has_val && rhs.m_has_val) {
2723 geterr().~unexpected<E>();
2724 construct(std::move(rhs).get());
2726 assign_common(std::move(rhs));
2733 template <
class Rhs>
2735 if (this->m_has_val) {
2736 if (rhs.m_has_val) {
2737 get() = std::forward<Rhs>(rhs).get();
2740 construct_error(std::forward<Rhs>(rhs).geterr());
2743 if (!rhs.m_has_val) {
2744 geterr() = std::forward<Rhs>(rhs).geterr();
2752 constexpr const T &
get() const & {
return this->m_val; }
2754#ifndef TL_EXPECTED_NO_CONSTRR
2755 constexpr const T &&
get() const && {
return std::move(this->m_val); }
2759 return this->m_unexpect;
2763 return std::move(this->m_unexpect);
2765#ifndef TL_EXPECTED_NO_CONSTRR
2767 return std::move(this->m_unexpect);
2780 template <
class... Args>
2782 this->m_has_val =
true;
2787 template <
class Rhs>
2789 this->m_has_val =
true;
2792 template <
class... Args>
2794 new (std::addressof(this->m_unexpect))
2796 this->m_has_val =
false;
2799 template <
class Rhs>
2801 if (!this->m_has_val) {
2802 if (rhs.m_has_val) {
2803 geterr().~unexpected<E>();
2806 geterr() = std::forward<Rhs>(rhs).geterr();
2809 if (!rhs.m_has_val) {
2810 construct_error(std::forward<Rhs>(rhs).geterr());
2818 return this->m_unexpect;
2822 return std::move(this->m_unexpect);
2824#ifndef TL_EXPECTED_NO_CONSTRR
2826 return std::move(this->m_unexpect);
2837template <
class T,
class E,
2846template <
class T,
class E>
2854 this->construct_with(rhs);
2856 this->construct_error(rhs.
geterr());
2870#ifndef TL_EXPECTED_GCC49
2871template <
class T,
class E,
2874 std::is_trivially_move_constructible<E>::value>
2879template <
class T,
class E,
bool = false>
2882template <
class T,
class E>
2890 std::is_nothrow_move_constructible<T>::value)
2892 if (rhs.has_value()) {
2893 this->construct_with(std::move(rhs));
2895 this->construct_error(std::move(rhs.geterr()));
2917template <
class T,
class E>
2938#ifndef TL_EXPECTED_GCC49
2943 std::is_trivially_move_constructible<T>,
2944 std::is_trivially_move_assignable<T>>>::value &&
2945 std::is_trivially_destructible<E>::value &&
2946 std::is_trivially_move_constructible<E>::value &&
2947 std::is_trivially_move_assignable<E>::value>
2952template <
class T,
class E,
bool = false>
2956template <
class T,
class E>
2971 &&rhs)
noexcept(std::is_nothrow_move_constructible<T>::value &&
2972 std::is_nothrow_move_assignable<T>::value) {
2973 this->assign(std::move(rhs));
2980template <
class T,
class E,
2981 bool EnableCopy = (is_copy_constructible_or_void<T>::value &&
2982 std::is_copy_constructible<E>::value),
2983 bool EnableMove = (is_move_constructible_or_void<T>::value &&
2984 std::is_move_constructible<E>::value)>
2995template <class T, class E>
3006template <class T, class E>
3017template <class T, class E>
3031template <class T, class E,
3033 std::is_copy_constructible<E>::value &&
3035 std::is_copy_assignable<E>::value),
3037 std::is_move_constructible<E>::value &&
3039 std::is_move_assignable<E>::value)>
3051template <class T, class E>
3063template <class T, class E>
3075template <class T, class E>
3096template <
class T,
class E,
3098 std::is_default_constructible<T>::value || std::is_void<T>::value>
3114template <
class T,
class E>
3135 virtual const char *
what() const noexcept
override {
3136 return "Bad expected access";
3139 const E &
error() const & {
return m_val; }
3141 const E &&
error() const && {
return std::move(m_val); }
3142 E &&
error() && {
return std::move(m_val); }
3155template <
class T,
class E>
3160 static_assert(!std::is_reference<T>::value,
"T must not be a reference");
3161 static_assert(!std::is_same<T, std::remove_cv<in_place_t>::type>::value,
3162 "T must not be in_place_t");
3163 static_assert(!std::is_same<T, std::remove_cv<unexpect_t>::type>::value,
3164 "T must not be unexpect_t");
3166 !std::is_same<T, typename std::remove_cv<unexpected<E>>::type>::value,
3167 "T must not be unexpected<E>");
3168 static_assert(!std::is_reference<E>::value,
"E must not be a reference");
3170 T *valptr() {
return std::addressof(this->m_val); }
3171 const T *valptr()
const {
return std::addressof(this->m_val); }
3172 unexpected<E> *errptr() {
return std::addressof(this->m_unexpect); }
3174 return std::addressof(this->m_unexpect);
3177 template <
class U = T,
3184 template <
class U = T,
3186 constexpr const U &val()
const {
3189 constexpr const unexpected<E> &err()
const {
return this->m_unexpect; }
3199#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
3200 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
3203 return and_then_impl(*
this, std::forward<F>(f));
3207 return and_then_impl(std::move(*
this), std::forward<F>(f));
3210 constexpr auto and_then(F &&f)
const & {
3211 return and_then_impl(*
this, std::forward<F>(f));
3214#ifndef TL_EXPECTED_NO_CONSTRR
3216 constexpr auto and_then(F &&f)
const && {
3224 std::declval<expected &>(), std::forward<F>(f))) {
3225 return and_then_impl(*
this, std::forward<F>(f));
3229 std::declval<expected &&>(), std::forward<F>(f))) {
3230 return and_then_impl(std::move(*
this), std::forward<F>(f));
3233 constexpr auto and_then(F &&f)
const & ->
decltype(and_then_impl(
3234 std::declval<expected const &>(), std::forward<F>(f))) {
3235 return and_then_impl(*
this, std::forward<F>(f));
3238#ifndef TL_EXPECTED_NO_CONSTRR
3240 constexpr auto and_then(F &&f)
const && ->
decltype(and_then_impl(
3241 std::declval<expected const &&>(), std::forward<F>(f))) {
3242 return and_then_impl(std::move(*
this), std::forward<F>(f));
3247#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
3248 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
3251 return expected_map_impl(*
this, std::forward<F>(f));
3255 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3258 constexpr auto map(F &&f)
const & {
3262 constexpr auto map(F &&f)
const && {
3268 std::declval<expected &>(), std::declval<F &&>()))
3270 return expected_map_impl(*
this, std::forward<F>(f));
3274 std::declval<F &&>()))
3276 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3279 constexpr decltype(expected_map_impl(std::declval<const expected &>(),
3280 std::declval<F &&>()))
3282 return expected_map_impl(*
this, std::forward<F>(f));
3285#ifndef TL_EXPECTED_NO_CONSTRR
3287 constexpr decltype(expected_map_impl(std::declval<const expected &&>(),
3288 std::declval<F &&>()))
3290 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3295#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
3296 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
3299 return expected_map_impl(*
this, std::forward<F>(f));
3303 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3306 constexpr auto transform(F &&f)
const & {
3310 constexpr auto transform(F &&f)
const && {
3316 std::declval<expected &>(), std::declval<F &&>()))
3318 return expected_map_impl(*
this, std::forward<F>(f));
3322 std::declval<F &&>()))
3324 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3327 constexpr decltype(expected_map_impl(std::declval<const expected &>(),
3328 std::declval<F &&>()))
3330 return expected_map_impl(*
this, std::forward<F>(f));
3333#ifndef TL_EXPECTED_NO_CONSTRR
3335 constexpr decltype(expected_map_impl(std::declval<const expected &&>(),
3336 std::declval<F &&>()))
3338 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3343#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
3344 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
3347 return map_error_impl(*
this, std::forward<F>(f));
3351 return map_error_impl(std::move(*
this), std::forward<F>(f));
3354 constexpr auto map_error(F &&f)
const & {
3358 constexpr auto map_error(F &&f)
const && {
3364 std::declval<F &&>()))
3366 return map_error_impl(*
this, std::forward<F>(f));
3370 std::declval<F &&>()))
3372 return map_error_impl(std::move(*
this), std::forward<F>(f));
3375 constexpr decltype(map_error_impl(std::declval<const expected &>(),
3376 std::declval<F &&>()))
3378 return map_error_impl(*
this, std::forward<F>(f));
3381#ifndef TL_EXPECTED_NO_CONSTRR
3383 constexpr decltype(map_error_impl(std::declval<const expected &&>(),
3384 std::declval<F &&>()))
3386 return map_error_impl(std::move(*
this), std::forward<F>(f));
3390#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
3391 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
3394 return map_error_impl(*
this, std::forward<F>(f));
3398 return map_error_impl(std::move(*
this), std::forward<F>(f));
3401 constexpr auto transform_error(F &&f)
const & {
3405 constexpr auto transform_error(F &&f)
const && {
3411 std::declval<F &&>()))
3413 return map_error_impl(*
this, std::forward<F>(f));
3417 std::declval<F &&>()))
3419 return map_error_impl(std::move(*
this), std::forward<F>(f));
3422 constexpr decltype(map_error_impl(std::declval<const expected &>(),
3423 std::declval<F &&>()))
3425 return map_error_impl(*
this, std::forward<F>(f));
3428#ifndef TL_EXPECTED_NO_CONSTRR
3430 constexpr decltype(map_error_impl(std::declval<const expected &&>(),
3431 std::declval<F &&>()))
3433 return map_error_impl(std::move(*
this), std::forward<F>(f));
3439 return or_else_impl(*
this, std::forward<F>(f));
3444 return or_else_impl(std::move(*
this), std::forward<F>(f));
3449 return or_else_impl(*
this, std::forward<F>(f));
3452#ifndef TL_EXPECTED_NO_CONSTRR
3455 return or_else_impl(std::move(*
this), std::forward<F>(f));
3464 template <
class... Args,
3469 ctor_base(detail::default_constructor_tag{}) {}
3471 template <
class U,
class... Args,
3473 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
3476 ctor_base(detail::default_constructor_tag{}) {}
3478 template <
class G = E,
3485 ctor_base(detail::default_constructor_tag{}) {}
3494 ctor_base(detail::default_constructor_tag{}) {}
3501 std::is_nothrow_constructible<E, G &&>::value)
3503 ctor_base(detail::default_constructor_tag{}) {}
3510 std::is_nothrow_constructible<E, G &&>::value)
3512 ctor_base(detail::default_constructor_tag{}) {}
3514 template <
class... Args,
3519 ctor_base(detail::default_constructor_tag{}) {}
3521 template <
class U,
class... Args,
3523 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
3527 ctor_base(detail::default_constructor_tag{}) {}
3529 template <
class U,
class G,
3531 std::is_convertible<G const &, E>::value)> * =
3538 this->construct(*rhs);
3540 this->construct_error(rhs.
error());
3544 template <
class U,
class G,
3545 detail::enable_if_t<(std::is_convertible<U const &, T>::value &&
3546 std::is_convertible<G const &, E>::value)> * =
3548 detail::expected_enable_from_other<T, E, U, G, const U &, const G &>
3553 this->construct(*rhs);
3555 this->construct_error(rhs.
error());
3561 detail::enable_if_t<!(std::is_convertible<U &&, T>::value &&
3562 std::is_convertible<G &&, E>::value)> * =
nullptr,
3563 detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * =
nullptr>
3567 this->construct(std::move(*rhs));
3569 this->construct_error(std::move(rhs.
error()));
3575 detail::enable_if_t<(std::is_convertible<U &&, T>::value &&
3576 std::is_convertible<G &&, E>::value)> * =
nullptr,
3577 detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * =
nullptr>
3581 this->construct(std::move(*rhs));
3583 this->construct_error(std::move(rhs.
error()));
3589 detail::enable_if_t<!std::is_convertible<U &&, T>::value> * =
nullptr,
3590 detail::expected_enable_forward_value<T, E, U> * =
nullptr>
3602 class U = T,
class G = T,
3609 std::is_same<T, detail::decay_t<U>>>::value &&
3610 std::is_constructible<T, U>::value &&
3611 std::is_assignable<G &, U>::value &&
3612 std::is_nothrow_move_constructible<E>::value)> * =
nullptr>
3615 val() = std::forward<U>(v);
3617 err().~unexpected<E>();
3618 ::new (valptr()) T(std::forward<U>(v));
3619 this->m_has_val =
true;
3626 class U = T,
class G = T,
3633 std::is_same<T, detail::decay_t<U>>>::value &&
3634 std::is_constructible<T, U>::value &&
3635 std::is_assignable<G &, U>::value &&
3636 std::is_nothrow_move_constructible<E>::value)> * =
nullptr>
3639 val() = std::forward<U>(v);
3641 auto tmp = std::move(err());
3642 err().~unexpected<E>();
3644#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
3646 ::new (valptr()) T(std::forward<U>(v));
3647 this->m_has_val =
true;
3649 err() = std::move(tmp);
3653 ::new (valptr()) T(std::forward<U>(v));
3654 this->m_has_val =
true;
3661 template <
class G = E,
3663 std::is_assignable<G &, G>::value> * =
nullptr>
3668 this->destroy_val();
3670 this->m_has_val =
false;
3676 template <
class G = E,
3678 std::is_move_assignable<G>::value> * =
nullptr>
3681 err() = std::move(rhs);
3683 this->destroy_val();
3685 this->m_has_val =
false;
3692 T, Args &&...>::value> * =
nullptr>
3697 err().~unexpected<E>();
3698 this->m_has_val =
true;
3700 ::new (valptr()) T(std::forward<Args>(args)...);
3704 T, Args &&...>::value> * =
nullptr>
3708 ::new (valptr()) T(std::forward<Args>(args)...);
3710 auto tmp = std::move(err());
3711 err().~unexpected<E>();
3713#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
3715 ::new (valptr()) T(std::forward<Args>(args)...);
3716 this->m_has_val =
true;
3718 err() = std::move(tmp);
3722 ::new (valptr()) T(std::forward<Args>(args)...);
3723 this->m_has_val =
true;
3728 template <
class U,
class... Args,
3730 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
3731 void emplace(std::initializer_list<U> il, Args &&...args) {
3733 T t(il, std::forward<Args>(args)...);
3734 val() = std::move(t);
3736 err().~unexpected<E>();
3737 ::new (valptr()) T(il, std::forward<Args>(args)...);
3738 this->m_has_val =
true;
3742 template <
class U,
class... Args,
3744 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
3745 void emplace(std::initializer_list<U> il, Args &&...args) {
3747 T t(il, std::forward<Args>(args)...);
3748 val() = std::move(t);
3750 auto tmp = std::move(err());
3751 err().~unexpected<E>();
3753#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
3755 ::new (valptr()) T(il, std::forward<Args>(args)...);
3756 this->m_has_val =
true;
3758 err() = std::move(tmp);
3762 ::new (valptr()) T(il, std::forward<Args>(args)...);
3763 this->m_has_val =
true;
3769 using t_is_void = std::true_type;
3770 using t_is_not_void = std::false_type;
3771 using t_is_nothrow_move_constructible = std::true_type;
3772 using move_constructing_t_can_throw = std::false_type;
3773 using e_is_nothrow_move_constructible = std::true_type;
3774 using move_constructing_e_can_throw = std::false_type;
3776 void swap_where_both_have_value(
expected & , t_is_void)
noexcept {
3780 void swap_where_both_have_value(expected &rhs, t_is_not_void) {
3782 swap(val(), rhs.val());
3785 void swap_where_only_one_has_value(expected &rhs, t_is_void)
noexcept(
3786 std::is_nothrow_move_constructible<E>::value) {
3787 ::new (errptr()) unexpected_type(std::move(rhs.err()));
3788 rhs.err().~unexpected_type();
3789 std::swap(this->m_has_val, rhs.m_has_val);
3792 void swap_where_only_one_has_value(expected &rhs, t_is_not_void) {
3793 swap_where_only_one_has_value_and_t_is_not_void(
3794 rhs,
typename std::is_nothrow_move_constructible<T>::type{},
3795 typename std::is_nothrow_move_constructible<E>::type{});
3798 void swap_where_only_one_has_value_and_t_is_not_void(
3799 expected &rhs, t_is_nothrow_move_constructible,
3800 e_is_nothrow_move_constructible)
noexcept {
3801 auto temp = std::move(val());
3803 ::new (errptr()) unexpected_type(std::move(rhs.err()));
3804 rhs.err().~unexpected_type();
3805 ::new (rhs.valptr()) T(std::move(temp));
3806 std::swap(this->m_has_val, rhs.m_has_val);
3809 void swap_where_only_one_has_value_and_t_is_not_void(
3810 expected &rhs, t_is_nothrow_move_constructible,
3811 move_constructing_e_can_throw) {
3812 auto temp = std::move(val());
3814#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
3816 ::new (errptr()) unexpected_type(std::move(rhs.err()));
3817 rhs.err().~unexpected_type();
3818 ::new (rhs.valptr()) T(std::move(temp));
3819 std::swap(this->m_has_val, rhs.m_has_val);
3821 val() = std::move(temp);
3825 ::new (errptr()) unexpected_type(std::move(rhs.err()));
3826 rhs.err().~unexpected_type();
3827 ::new (rhs.valptr()) T(std::move(temp));
3828 std::swap(this->m_has_val, rhs.m_has_val);
3832 void swap_where_only_one_has_value_and_t_is_not_void(
3833 expected &rhs, move_constructing_t_can_throw,
3834 e_is_nothrow_move_constructible) {
3835 auto temp = std::move(rhs.err());
3836 rhs.err().~unexpected_type();
3837#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
3839 ::new (rhs.valptr()) T(std::move(val()));
3841 ::new (errptr()) unexpected_type(std::move(temp));
3842 std::swap(this->m_has_val, rhs.m_has_val);
3844 rhs.err() = std::move(temp);
3848 ::new (rhs.valptr()) T(std::move(val()));
3850 ::new (errptr()) unexpected_type(std::move(temp));
3851 std::swap(this->m_has_val, rhs.m_has_val);
3856 template <
class OT = T,
class OE = E>
3857 detail::enable_if_t<detail::is_swappable<OT>::value &&
3858 detail::is_swappable<OE>::value &&
3859 (std::is_nothrow_move_constructible<OT>::value ||
3860 std::is_nothrow_move_constructible<OE>::value)>
3861 swap(
expected &rhs)
noexcept(std::is_nothrow_move_constructible<T>::value &&
3863 std::is_nothrow_move_constructible<E>::value &&
3866 swap_where_both_have_value(rhs,
typename std::is_void<T>::type{});
3867 }
else if (!has_value() && rhs.
has_value()) {
3869 }
else if (has_value()) {
3870 swap_where_only_one_has_value(rhs,
typename std::is_void<T>::type{});
3873 swap(err(), rhs.err());
3886 template <
class U = T,
3892 template <
class U = T,
3898 template <
class U = T,
3902 return std::move(val());
3904 template <
class U = T,
3908 return std::move(val());
3911 constexpr bool has_value() const noexcept {
return this->m_has_val; }
3912 constexpr explicit operator bool() const noexcept {
return this->m_has_val; }
3914 template <
class U = T,
3921 template <
class U = T,
3928 template <
class U = T,
3933 return std::move(val());
3935 template <
class U = T,
3940 return std::move(val());
3945 return err().value();
3949 return err().value();
3953 return std::move(err().value());
3957 return std::move(err().value());
3962 static_assert(std::is_copy_constructible<T>::value &&
3963 std::is_convertible<U &&, T>::value,
3964 "T must be copy-constructible and convertible to from U&&");
3965 return bool(*
this) ? **this :
static_cast<T
>(std::forward<U>(v));
3969 static_assert(std::is_move_constructible<T>::value &&
3970 std::is_convertible<U &&, T>::value,
3971 "T must be move-constructible and convertible to from U&&");
3972 return bool(*
this) ? std::move(**
this) :
static_cast<T
>(std::forward<U>(v));
3981template <
class Exp,
class Ret>
3984#ifdef TL_EXPECTED_CXX14
3985template <
class Exp,
class F,
3987 class Ret =
decltype(detail::invoke(std::declval<F>(),
3988 *std::declval<Exp>()))>
3992 return exp.has_value()
3993 ? detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp))
3994 : Ret(
unexpect, std::forward<Exp>(exp).error());
3997template <
class Exp,
class F,
3999 class Ret =
decltype(detail::invoke(std::declval<F>()))>
4000constexpr auto and_then_impl(Exp &&exp, F &&f) {
4003 return exp.has_value() ? detail::invoke(std::forward<F>(f))
4004 : Ret(
unexpect, std::forward<Exp>(exp).error());
4009template <
class Exp,
class F,
4010 class Ret =
decltype(detail::invoke(std::declval<F>(),
4011 *std::declval<Exp>())),
4016 return exp.has_value()
4017 ? detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp))
4018 : Ret(
unexpect, std::forward<Exp>(exp).error());
4021template <
class Exp,
class F,
4022 class Ret =
decltype(detail::invoke(std::declval<F>())),
4027 return exp.has_value() ? detail::invoke(std::forward<F>(f))
4028 : Ret(
unexpect, std::forward<Exp>(exp).error());
4032#ifdef TL_EXPECTED_CXX14
4033template <
class Exp,
class F,
4035 class Ret =
decltype(detail::invoke(std::declval<F>(),
4036 *std::declval<Exp>())),
4038constexpr auto expected_map_impl(Exp &&exp, F &&f) {
4039 using result = ret_t<Exp, detail::decay_t<Ret>>;
4040 return exp.has_value() ? result(detail::invoke(std::forward<F>(f),
4041 *std::forward<Exp>(exp)))
4042 : result(
unexpect, std::forward<Exp>(exp).error());
4045template <
class Exp,
class F,
4046 detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * =
nullptr,
4047 class Ret =
decltype(detail::invoke(std::declval<F>(),
4048 *std::declval<Exp>())),
4049 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4050auto expected_map_impl(Exp &&exp, F &&f) {
4051 using result = expected<void, err_t<Exp>>;
4052 if (exp.has_value()) {
4053 detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
4057 return result(unexpect, std::forward<Exp>(exp).error());
4060template <
class Exp,
class F,
4061 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4062 class Ret =
decltype(detail::invoke(std::declval<F>())),
4063 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4065 using result = ret_t<Exp, detail::decay_t<Ret>>;
4066 return exp.has_value() ?
result(detail::invoke(std::forward<F>(f)))
4070template <
class Exp,
class F,
4071 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4072 class Ret =
decltype(detail::invoke(std::declval<F>())),
4073 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4075 using result = expected<void, err_t<Exp>>;
4076 if (exp.has_value()) {
4077 detail::invoke(std::forward<F>(f));
4081 return result(unexpect, std::forward<Exp>(exp).error());
4084template <
class Exp,
class F,
4085 detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * =
nullptr,
4086 class Ret =
decltype(detail::invoke(std::declval<F>(),
4087 *std::declval<Exp>())),
4088 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4094 return exp.
has_value() ? result(detail::invoke(std::forward<F>(f),
4095 *std::forward<Exp>(exp)))
4096 : result(
unexpect, std::forward<Exp>(exp).error());
4099template <
class Exp,
class F,
4101 class Ret =
decltype(detail::invoke(std::declval<F>(),
4102 *std::declval<Exp>())),
4106 if (exp.has_value()) {
4107 detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
4114template <
class Exp,
class F,
4116 class Ret =
decltype(detail::invoke(std::declval<F>())),
4119constexpr auto expected_map_impl(Exp &&exp, F &&f)
4120 -> ret_t<Exp, detail::decay_t<Ret>> {
4121 using result = ret_t<Exp, detail::decay_t<Ret>>;
4123 return exp.has_value() ? result(detail::invoke(std::forward<F>(f)))
4124 : result(
unexpect, std::forward<Exp>(exp).error());
4127template <
class Exp,
class F,
4128 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4129 class Ret =
decltype(detail::invoke(std::declval<F>())),
4130 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4132auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> {
4133 if (exp.has_value()) {
4134 detail::invoke(std::forward<F>(f));
4138 return unexpected<err_t<Exp>>(std::forward<Exp>(exp).error());
4142#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
4143 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
4144template <
class Exp,
class F,
4145 detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * =
nullptr,
4146 class Ret =
decltype(detail::invoke(std::declval<F>(),
4147 std::declval<Exp>().error())),
4148 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4150 using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
4151 return exp.has_value()
4152 ?
result(*std::forward<Exp>(exp))
4154 std::forward<Exp>(exp).error()));
4156template <
class Exp,
class F,
4157 detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * =
nullptr,
4158 class Ret =
decltype(detail::invoke(std::declval<F>(),
4159 std::declval<Exp>().error())),
4160 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4162 using result = expected<exp_t<Exp>, monostate>;
4163 if (exp.has_value()) {
4164 return result(*std::forward<Exp>(exp));
4167 detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
4168 return result(unexpect, monostate{});
4170template <
class Exp,
class F,
4171 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4172 class Ret =
decltype(detail::invoke(std::declval<F>(),
4173 std::declval<Exp>().error())),
4174 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4176 using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
4177 return exp.has_value()
4180 std::forward<Exp>(exp).error()));
4182template <
class Exp,
class F,
4183 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4184 class Ret =
decltype(detail::invoke(std::declval<F>(),
4185 std::declval<Exp>().error())),
4186 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4188 using result = expected<exp_t<Exp>, monostate>;
4189 if (exp.has_value()) {
4193 detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
4194 return result(unexpect, monostate{});
4197template <
class Exp,
class F,
4198 detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * =
nullptr,
4199 class Ret =
decltype(detail::invoke(std::declval<F>(),
4200 std::declval<Exp>().error())),
4201 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4207 ? result(*std::forward<Exp>(exp))
4208 : result(
unexpect, detail::invoke(std::forward<F>(f),
4209 std::forward<Exp>(exp).error()));
4212template <
class Exp,
class F,
4214 class Ret =
decltype(detail::invoke(std::declval<F>(),
4215 std::declval<Exp>().error())),
4219 if (exp.has_value()) {
4220 return result(*std::forward<Exp>(exp));
4223 detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
4227template <
class Exp,
class F,
4229 class Ret =
decltype(detail::invoke(std::declval<F>(),
4230 std::declval<Exp>().error())),
4232constexpr auto map_error_impl(Exp &&exp, F &&f)
4238 : result(
unexpect, detail::invoke(std::forward<F>(f),
4239 std::forward<Exp>(exp).error()));
4242template <
class Exp,
class F,
4243 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4244 class Ret =
decltype(detail::invoke(std::declval<F>(),
4245 std::declval<Exp>().error())),
4246 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4247auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
4248 using result = expected<exp_t<Exp>, monostate>;
4249 if (exp.has_value()) {
4253 detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
4254 return result(unexpect, monostate{});
4258#ifdef TL_EXPECTED_CXX14
4259template <
class Exp,
class F,
4260 class Ret =
decltype(detail::invoke(std::declval<F>(),
4261 std::declval<Exp>().error())),
4262 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4264 static_assert(detail::is_expected<Ret>::value,
"F must return an expected");
4265 return exp.has_value() ? std::forward<Exp>(exp)
4266 : detail::
invoke(std::forward<F>(f),
4267 std::forward<Exp>(exp).error());
4270template <
class Exp,
class F,
4271 class Ret =
decltype(detail::invoke(std::declval<F>(),
4272 std::declval<Exp>().error())),
4273 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4275 return exp.has_value() ? std::forward<Exp>(exp)
4276 : (detail::
invoke(std::forward<F>(f),
4277 std::forward<Exp>(exp).error()),
4278 std::forward<Exp>(exp));
4281template <
class Exp,
class F,
4282 class Ret =
decltype(detail::invoke(std::declval<F>(),
4283 std::declval<Exp>().error())),
4284 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4287 return exp.has_value() ? std::forward<Exp>(exp)
4288 : detail::invoke(std::forward<F>(f),
4289 std::forward<Exp>(exp).error());
4292template <
class Exp,
class F,
4293 class Ret =
decltype(detail::invoke(std::declval<F>(),
4294 std::declval<Exp>().error())),
4297 return exp.has_value() ? std::forward<Exp>(exp)
4298 : (detail::invoke(std::forward<F>(f),
4299 std::forward<Exp>(exp).error()),
4300 std::forward<Exp>(exp));
4305template <
class T,
class E,
class U,
class F>
4312template <
class T,
class E,
class U,
class F>
4319template <
class E,
class F>
4326template <
class E,
class F>
4334template <
class T,
class E,
class U>
4338template <
class T,
class E,
class U>
4342template <
class T,
class E,
class U>
4346template <
class T,
class E,
class U>
4351template <
class T,
class E>
4355template <
class T,
class E>
4359template <
class T,
class E>
4363template <
class T,
class E>
4368template <
class T,
class E,
4369 detail::enable_if_t<(std::is_void<T>::value ||
4370 std::is_move_constructible<T>::value) &&
4371 detail::is_swappable<T>::value &&
4372 std::is_move_constructible<E>::value &&
4373 detail::is_swappable<E>::value> * =
nullptr>
4387struct url_aggregator;
4402template <
typename result_type = ada::url_aggregator>
4403result_type
parse_url(std::string_view user_input,
4404 const result_type* base_url =
nullptr);
4406extern template url_aggregator parse_url<url_aggregator>(
4407 std::string_view user_input,
const url_aggregator* base_url);
4408extern template url parse_url<url>(std::string_view user_input,
4409 const url* base_url);
4411template <
typename result_type = ada::url_aggregator,
bool store_values = true>
4413 const result_type* base_url =
nullptr);
4415extern template url_aggregator parse_url_impl<url_aggregator>(
4416 std::string_view user_input,
const url_aggregator* base_url);
4417extern template url parse_url_impl<url>(std::string_view user_input,
4418 const url* base_url);
4428#ifndef ADA_SCHEME_INL_H
4429#define ADA_SCHEME_INL_H
4441constexpr std::string_view is_special_list[] = {
"http",
" ",
"https",
"ws",
4442 "ftp",
"wss",
"file",
" "};
4444constexpr uint16_t special_ports[] = {80, 0, 443, 80, 21, 443, 0, 0};
4472 if (scheme.empty()) {
4475 int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7;
4476 const std::string_view target = details::is_special_list[hash_value];
4477 return (target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1));
4479constexpr uint16_t get_special_port(std::string_view scheme)
noexcept {
4480 if (scheme.empty()) {
4483 int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7;
4484 const std::string_view target = details::is_special_list[hash_value];
4485 if ((target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1))) {
4486 return details::special_ports[hash_value];
4492 return details::special_ports[int(type)];
4495 if (scheme.empty()) {
4498 int hash_value = (2 * scheme.size() + (unsigned)(scheme[0])) & 7;
4499 const std::string_view target = details::is_special_list[hash_value];
4500 if ((target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1))) {
4516#ifndef ADA_SERIALIZERS_H
4517#define ADA_SERIALIZERS_H
4533void find_longest_sequence_of_ipv6_pieces(
4534 const std::array<uint16_t, 8>& address,
size_t& compress,
4535 size_t& compress_length)
noexcept;
4543std::string ipv6(
const std::array<uint16_t, 8>& address)
noexcept;
4551std::string ipv4(uint64_t address)
noexcept;
4562#ifndef ADA_UNICODE_H
4563#define ADA_UNICODE_H
4620bool to_ascii(std::optional<std::string>& out, std::string_view plain,
4621 size_t first_percent);
4631 std::string_view user_input)
noexcept;
4646 const char* input,
size_t length)
noexcept;
4656contains_forbidden_domain_code_point_or_upper(
const char* input,
4657 size_t length)
noexcept;
4706 std::string_view input)
noexcept;
4714 std::string_view input)
noexcept;
4738std::string percent_decode(std::string_view input,
size_t first_percent);
4745std::string percent_encode(std::string_view input,
4746 const uint8_t character_set[]);
4753std::string percent_encode(std::string_view input,
4754 const uint8_t character_set[],
size_t index);
4763template <
bool append>
4764bool percent_encode(std::string_view input,
const uint8_t character_set[],
4772 const uint8_t character_set[]);
4778constexpr bool to_lower_ascii(
char* input,
size_t length)
noexcept;
4788#ifndef ADA_URL_BASE_INL_H
4789#define ADA_URL_BASE_INL_H
4796#ifndef ADA_URL_AGGREGATOR_H
4797#define ADA_URL_AGGREGATOR_H
4800#include <string_view>
4839 [[nodiscard]] std::
string get_origin() const noexcept override;
4848 [[nodiscard]] inline std::string_view get_href() const noexcept;
4855 [[nodiscard]] std::string_view get_username() const noexcept;
4862 [[nodiscard]] std::string_view get_password() const noexcept;
4869 [[nodiscard]] std::string_view get_port() const noexcept;
4876 [[nodiscard]] std::string_view get_hash() const noexcept;
4885 [[nodiscard]] std::string_view get_host() const noexcept;
4893 [[nodiscard]] std::string_view get_hostname() const noexcept;
4901 [[nodiscard]] std::string_view get_pathname() const noexcept;
4915 [[nodiscard]] std::string_view get_search() const noexcept;
4923 [[nodiscard]] std::string_view get_protocol() const noexcept;
4957 [[nodiscard]] std::
string to_string() const override;
4961 [[nodiscard]] std::
string to_diagram() const;
4968 [[nodiscard]]
bool validate() const noexcept;
4971 [[nodiscard]] inline
bool has_empty_hostname() const noexcept;
4973 [[nodiscard]] inline
bool has_hostname() const noexcept;
4975 [[nodiscard]] inline
bool has_non_empty_username() const noexcept;
4977 [[nodiscard]] inline
bool has_non_empty_password() const noexcept;
4979 [[nodiscard]] inline
bool has_port() const noexcept;
4981 [[nodiscard]] inline
bool has_password() const noexcept;
4983 [[nodiscard]] inline
bool has_hash() const noexcept override;
4985 [[nodiscard]] inline
bool has_search() const noexcept override;
4987 inline
void clear_port();
4988 inline
void clear_hash();
4989 inline
void clear_search() override;
4994 friend
void ada::helpers::strip_trailing_spaces_from_opaque_path<
5002 std::
string buffer{};
5012 inline
void add_authority_slashes_if_needed() noexcept;
5018 inline
void reserve(uint32_t capacity);
5021 std::string_view view,
bool check_trailing_content) noexcept override;
5024 return this->parse_port(view,
false);
5033 [[nodiscard]]
bool parse_ipv4(std::string_view input,
bool in_place);
5039 [[nodiscard]]
bool parse_ipv6(std::string_view input);
5045 [[nodiscard]]
bool parse_opaque_host(std::string_view input);
5053 [[nodiscard]]
inline bool cannot_have_credentials_or_port()
const;
5055 template <
bool overr
ide_hostname = false>
5056 bool set_host_or_hostname(std::string_view input);
5060 inline void update_base_authority(std::string_view base_buffer,
5062 inline void update_unencoded_base_hash(std::string_view input);
5063 inline void update_base_hostname(std::string_view input);
5064 inline void update_base_search(std::string_view input);
5065 inline void update_base_search(std::string_view input,
5066 const uint8_t *query_percent_encode_set);
5067 inline void update_base_pathname(std::string_view input);
5068 inline void update_base_username(std::string_view input);
5069 inline void append_base_username(std::string_view input);
5070 inline void update_base_password(std::string_view input);
5071 inline void append_base_password(std::string_view input);
5072 inline void update_base_port(uint32_t input);
5073 inline void append_base_pathname(std::string_view input);
5074 [[nodiscard]]
inline uint32_t retrieve_base_port()
const;
5075 inline void clear_hostname();
5076 inline void clear_password();
5077 inline void clear_pathname()
override;
5078 [[nodiscard]]
inline bool has_dash_dot() const noexcept;
5079 void delete_dash_dot();
5080 inline
void consume_prepared_path(std::string_view input);
5081 template <
bool has_state_override = false>
5083 std::string_view input);
5085 std::string_view input);
5086 [[nodiscard]] inline
bool has_authority() const noexcept;
5087 inline
void set_protocol_as_file();
5088 inline
void set_scheme(std::string_view new_scheme) noexcept;
5093 inline
void set_scheme_from_view_with_colon(
5094 std::string_view new_scheme_with_colon) noexcept;
5095 inline
void copy_scheme(const url_aggregator &u) noexcept;
5099inline std::ostream &operator<<(std::ostream &out, const
ada::url &u);
5109#ifndef ADA_CHECKERS_H
5110#define ADA_CHECKERS_H
5113#include <string_view>
5131constexpr char to_lower(
char x)
noexcept;
5140constexpr bool is_alpha(
char x)
noexcept;
5149inline bool has_hex_prefix_unsafe(std::string_view input);
5154inline bool has_hex_prefix(std::string_view input);
5161constexpr bool is_digit(
char x)
noexcept;
5175inline constexpr bool is_windows_drive_letter(std::string_view input)
noexcept;
5182inline constexpr bool is_normalized_windows_drive_letter(
5183 std::string_view input)
noexcept;
5190 std::string_view prefix);
5208 std::string_view input)
noexcept;
5222 std::string_view input)
noexcept;
5241#include <string_view>
5271 std::string username{};
5278 std::string password{};
5284 std::optional<std::string> host{};
5291 std::optional<uint16_t> port{};
5304 std::optional<std::string> query{};
5312 std::optional<std::string> hash{};
5317 [[nodiscard]] inline
bool has_port() const noexcept;
5319 [[nodiscard]] inline
bool has_hostname() const noexcept;
5320 [[nodiscard]]
bool has_valid_domain() const noexcept override;
5325 [[nodiscard]] std::
string to_string() const override;
5339 [[nodiscard]] std::
string get_origin() const noexcept override;
5347 [[nodiscard]] std::
string get_protocol() const noexcept;
5356 [[nodiscard]] std::
string get_host() const noexcept;
5364 [[nodiscard]] std::
string get_hostname() const noexcept;
5372 [[nodiscard]] std::string_view get_pathname() const noexcept;
5387 [[nodiscard]] std::
string get_search() const noexcept;
5394 [[nodiscard]] const std::
string &get_username() const noexcept;
5400 bool set_username(std::string_view input);
5406 bool set_password(std::string_view input);
5412 bool set_port(std::string_view input);
5418 void set_hash(std::string_view input);
5424 void set_search(std::string_view input);
5430 bool set_pathname(std::string_view input);
5436 bool set_host(std::string_view input);
5442 bool set_hostname(std::string_view input);
5448 bool set_protocol(std::string_view input);
5453 bool set_href(std::string_view input);
5460 [[nodiscard]] const std::
string &get_password() const noexcept;
5467 [[nodiscard]] std::
string get_port() const noexcept;
5474 [[nodiscard]] std::
string get_hash() const noexcept;
5506 [[nodiscard]] inline
bool has_hash() const noexcept override;
5508 [[nodiscard]] inline
bool has_search() const noexcept override;
5515 friend
void ada::helpers::strip_trailing_spaces_from_opaque_path<
ada::
url>(
5523 inline
void update_unencoded_base_hash(std::string_view input);
5524 inline
void update_base_hostname(std::string_view input);
5525 inline
void update_base_search(std::string_view input);
5526 inline
void update_base_search(std::string_view input,
5527 const uint8_t query_percent_encode_set[]);
5528 inline
void update_base_search(std::optional<std::
string> input);
5529 inline
void update_base_pathname(std::string_view input);
5530 inline
void update_base_username(std::string_view input);
5531 inline
void update_base_password(std::string_view input);
5532 inline
void update_base_port(std::optional<uint16_t> input);
5539 template <
bool override_hostname = false>
5540 bool set_host_or_hostname(std::string_view input);
5546 [[nodiscard]]
bool parse_ipv4(std::string_view input);
5552 [[nodiscard]]
bool parse_ipv6(std::string_view input);
5558 [[nodiscard]]
bool parse_opaque_host(std::string_view input);
5569 std::
string non_special_scheme{};
5575 [[nodiscard]]
inline bool cannot_have_credentials_or_port()
const;
5578 std::string_view view,
bool check_trailing_content)
noexcept override;
5581 return this->parse_port(view,
false);
5588 inline void copy_scheme(
const ada::url &u);
5600 template <
bool has_state_overr
ide = false>
5603 inline void clear_pathname()
override;
5604 inline void clear_search()
override;
5605 inline void set_protocol_as_file();
5624 inline void set_scheme(std::string &&new_scheme)
noexcept;
5630 inline void copy_scheme(
ada::url &&u)
noexcept;
5642#if ADA_REGULAR_VISUAL_STUDIO
5652[[nodiscard]]
inline uint16_t url_base::get_special_port() const noexcept {
5657url_base::scheme_default_port() const noexcept {
5658 return scheme::get_special_port(type);
5670#ifndef ADA_URL_INL_H
5671#define ADA_URL_INL_H
5676#if ADA_REGULAR_VISUAL_STUDIO
5682 return !username.empty() || !password.empty();
5685 return port.has_value();
5687[[nodiscard]]
inline bool url::cannot_have_credentials_or_port()
const {
5688 return !host.has_value() || host.value().empty() ||
5689 type == ada::scheme::type::FILE;
5691[[nodiscard]]
inline bool url::has_empty_hostname()
const noexcept {
5692 if (!host.has_value()) {
5695 return host.value().empty();
5697[[nodiscard]]
inline bool url::has_hostname()
const noexcept {
5698 return host.has_value();
5700inline std::ostream &operator<<(std::ostream &out,
const ada::url &u) {
5704[[nodiscard]]
size_t url::get_pathname_length()
const noexcept {
5710 url_components out{};
5716 size_t running_index = out.protocol_end;
5718 if (host.has_value()) {
5720 out.host_start = out.protocol_end + 2;
5722 if (has_credentials()) {
5723 out.username_end = uint32_t(out.host_start + username.size());
5725 out.host_start += uint32_t(username.size());
5727 if (!password.empty()) {
5728 out.host_start += uint32_t(password.size() + 1);
5731 out.host_end = uint32_t(out.host_start + host.value().size());
5733 out.username_end = out.host_start;
5736 out.host_end = uint32_t(out.host_start + host.value().size()) - 1;
5739 running_index = out.host_end + 1;
5743 out.host_start = out.protocol_end;
5744 out.host_end = out.host_start;
5746 if (!has_opaque_path && checkers::begins_with(path,
"//")) {
5750 running_index = out.protocol_end + 2;
5752 running_index = out.protocol_end;
5756 if (port.has_value()) {
5758 running_index += helpers::fast_digit_count(*port) + 1;
5761 out.pathname_start = uint32_t(running_index);
5763 running_index += path.size();
5765 if (query.has_value()) {
5766 out.search_start = uint32_t(running_index);
5767 running_index += get_search().size();
5768 if (get_search().empty()) {
5773 if (hash.has_value()) {
5774 out.hash_start = uint32_t(running_index);
5780inline void url::update_base_hostname(std::string_view input) { host = input; }
5782inline void url::update_unencoded_base_hash(std::string_view input) {
5784 hash = unicode::percent_encode(input,
5788inline void url::update_base_search(std::string_view input,
5789 const uint8_t query_percent_encode_set[]) {
5790 query = ada::unicode::percent_encode(input, query_percent_encode_set);
5793inline void url::update_base_search(std::optional<std::string> input) {
5797inline void url::update_base_pathname(
const std::string_view input) {
5801inline void url::update_base_username(
const std::string_view input) {
5805inline void url::update_base_password(
const std::string_view input) {
5809inline void url::update_base_port(std::optional<uint16_t> input) {
5813inline void url::clear_pathname() { path.clear(); }
5815inline void url::clear_search() { query = std::nullopt; }
5817[[nodiscard]]
inline bool url::has_hash()
const noexcept {
5818 return hash.has_value();
5821[[nodiscard]]
inline bool url::has_search()
const noexcept {
5822 return query.has_value();
5825inline void url::set_protocol_as_file() { type = ada::scheme::type::FILE; }
5827inline void url::set_scheme(std::string &&new_scheme)
noexcept {
5830 if (!is_special()) {
5831 non_special_scheme = new_scheme;
5835inline void url::copy_scheme(
ada::url &&u)
noexcept {
5836 non_special_scheme = u.non_special_scheme;
5840inline void url::copy_scheme(
const ada::url &u) {
5841 non_special_scheme = u.non_special_scheme;
5846 std::string output = get_protocol();
5848 if (host.has_value()) {
5850 if (has_credentials()) {
5852 if (!password.empty()) {
5853 output +=
":" + get_password();
5857 output += host.value();
5858 if (port.has_value()) {
5859 output +=
":" + get_port();
5861 }
else if (!has_opaque_path && checkers::begins_with(path,
"//")) {
5868 if (query.has_value()) {
5869 output +=
"?" + query.value();
5871 if (hash.has_value()) {
5872 output +=
"#" + hash.value();
5878 bool check_trailing_content)
noexcept {
5879 ada_log(
"parse_port('", view,
"') ", view.size());
5880 uint16_t parsed_port{};
5881 auto r = std::from_chars(view.data(), view.data() + view.size(), parsed_port);
5882 if (r.ec == std::errc::result_out_of_range) {
5883 ada_log(
"parse_port: std::errc::result_out_of_range");
5887 ada_log(
"parse_port: ", parsed_port);
5888 const size_t consumed = size_t(r.ptr - view.data());
5889 ada_log(
"parse_port: consumed ", consumed);
5890 if (check_trailing_content) {
5892 (consumed == view.size() || view[consumed] ==
'/' ||
5893 view[consumed] ==
'?' || (is_special() && view[consumed] ==
'\\'));
5895 ada_log(
"parse_port: is_valid = ", is_valid);
5898 auto default_port = scheme_default_port();
5899 bool is_port_valid = (default_port == 0 && parsed_port == 0) ||
5900 (default_port != parsed_port);
5901 port = (r.ec == std::errc() && is_port_valid)
5902 ? std::optional<uint16_t>(parsed_port)
5917#ifndef ADA_URL_AGGREGATOR_INL_H
5918#define ADA_URL_AGGREGATOR_INL_H
5925#ifndef ADA_UNICODE_INL_H
5926#define ADA_UNICODE_INL_H
5939 const uint8_t character_set[]) {
5940 return std::distance(
5942 std::find_if(input.begin(), input.end(), [character_set](
const char c) {
5943 return character_sets::bit_at(character_set, c);
5952#include <string_view>
5956inline void url_aggregator::update_base_authority(
5958 std::string_view input = base_buffer.substr(
5959 base.protocol_end,
base.host_start -
base.protocol_end);
5960 ada_log(
"url_aggregator::update_base_authority ", input);
5962 bool input_starts_with_dash = checkers::begins_with(input,
"//");
5963 uint32_t diff = components.host_start - components.protocol_end;
5965 buffer.erase(components.protocol_end,
5966 components.host_start - components.protocol_end);
5967 components.username_end = components.protocol_end;
5969 if (input_starts_with_dash) {
5970 input.remove_prefix(2);
5972 buffer.insert(components.protocol_end,
"//");
5973 components.username_end += 2;
5976 size_t password_delimiter = input.find(
':');
5980 if (password_delimiter != std::string_view::npos) {
5982 std::string_view username = input.substr(0, password_delimiter);
5983 std::string_view password = input.substr(password_delimiter + 1);
5985 buffer.insert(components.protocol_end + diff, username);
5986 diff += uint32_t(username.size());
5987 buffer.insert(components.protocol_end + diff,
":");
5988 components.username_end = components.protocol_end + diff;
5989 buffer.insert(components.protocol_end + diff + 1, password);
5990 diff += uint32_t(password.size()) + 1;
5991 }
else if (!input.empty()) {
5993 buffer.insert(components.protocol_end + diff, input);
5994 components.username_end =
5995 components.protocol_end + diff + uint32_t(input.size());
5996 diff += uint32_t(input.size());
5999 components.host_start += diff;
6001 if (buffer.size() >
base.host_start && buffer[
base.host_start] !=
'@') {
6002 buffer.insert(components.host_start,
"@");
6005 components.host_end += diff;
6006 components.pathname_start += diff;
6007 if (components.search_start != url_components::omitted) {
6008 components.search_start += diff;
6010 if (components.hash_start != url_components::omitted) {
6011 components.hash_start += diff;
6015inline void url_aggregator::update_unencoded_base_hash(std::string_view input) {
6016 ada_log(
"url_aggregator::update_unencoded_base_hash ", input,
" [",
6017 input.size(),
" bytes], buffer is '", buffer,
"' [", buffer.size(),
6018 " bytes] components.hash_start = ", components.hash_start);
6021 if (components.hash_start != url_components::omitted) {
6022 buffer.resize(components.hash_start);
6024 components.hash_start = uint32_t(buffer.size());
6026 bool encoding_required = unicode::percent_encode<true>(
6030 if (!encoding_required) {
6031 buffer.append(input);
6033 ada_log(
"url_aggregator::update_unencoded_base_hash final buffer is '",
6034 buffer,
"' [", buffer.size(),
" bytes]");
6039 uint32_t start, uint32_t end, std::string_view input) {
6040 uint32_t current_length = end - start;
6041 uint32_t input_size = uint32_t(input.size());
6042 uint32_t new_difference = input_size - current_length;
6044 if (current_length == 0) {
6045 buffer.insert(start, input);
6046 }
else if (input_size == current_length) {
6047 buffer.replace(start, input_size, input);
6048 }
else if (input_size < current_length) {
6049 buffer.erase(start, current_length - input_size);
6050 buffer.replace(start, input_size, input);
6052 buffer.replace(start, current_length, input.substr(0, current_length));
6053 buffer.insert(start + current_length, input.substr(current_length));
6056 return new_difference;
6059inline void url_aggregator::update_base_hostname(
const std::string_view input) {
6060 ada_log(
"url_aggregator::update_base_hostname ", input,
" [", input.size(),
6061 " bytes], buffer is '", buffer,
"' [", buffer.size(),
" bytes]");
6066 add_authority_slashes_if_needed();
6068 bool has_credentials = components.protocol_end + 2 < components.host_start;
6069 uint32_t new_difference =
6070 replace_and_resize(components.host_start, components.host_end, input);
6072 if (has_credentials) {
6073 buffer.insert(components.host_start,
"@");
6076 components.host_end += new_difference;
6077 components.pathname_start += new_difference;
6078 if (components.search_start != url_components::omitted) {
6079 components.search_start += new_difference;
6081 if (components.hash_start != url_components::omitted) {
6082 components.hash_start += new_difference;
6088url_aggregator::get_pathname_length() const noexcept {
6089 ada_log(
"url_aggregator::get_pathname_length");
6090 uint32_t ending_index = uint32_t(buffer.size());
6091 if (components.search_start != url_components::omitted) {
6092 ending_index = components.search_start;
6093 }
else if (components.hash_start != url_components::omitted) {
6094 ending_index = components.hash_start;
6096 return ending_index - components.pathname_start;
6101 return buffer.size() == components.pathname_start;
6104inline void url_aggregator::update_base_search(std::string_view input) {
6105 ada_log(
"url_aggregator::update_base_search ", input);
6108 if (input.empty()) {
6113 if (input[0] ==
'?') {
6114 input.remove_prefix(1);
6117 if (components.hash_start == url_components::omitted) {
6118 if (components.search_start == url_components::omitted) {
6119 components.search_start = uint32_t(buffer.size());
6122 buffer.resize(components.search_start + 1);
6125 buffer.append(input);
6127 if (components.search_start == url_components::omitted) {
6128 components.search_start = components.hash_start;
6130 buffer.erase(components.search_start,
6131 components.hash_start - components.search_start);
6132 components.hash_start = components.search_start;
6135 buffer.insert(components.search_start,
"?");
6136 buffer.insert(components.search_start + 1, input);
6137 components.hash_start += uint32_t(input.size() + 1);
6143inline void url_aggregator::update_base_search(
6144 std::string_view input,
const uint8_t query_percent_encode_set[]) {
6145 ada_log(
"url_aggregator::update_base_search ", input,
6146 " with encoding parameter ",
to_string(),
"\n", to_diagram());
6150 if (components.hash_start == url_components::omitted) {
6151 if (components.search_start == url_components::omitted) {
6152 components.search_start = uint32_t(buffer.size());
6155 buffer.resize(components.search_start + 1);
6158 bool encoding_required =
6159 unicode::percent_encode<true>(input, query_percent_encode_set, buffer);
6162 if (!encoding_required) {
6163 buffer.append(input);
6166 if (components.search_start == url_components::omitted) {
6167 components.search_start = components.hash_start;
6169 buffer.erase(components.search_start,
6170 components.hash_start - components.search_start);
6171 components.hash_start = components.search_start;
6174 buffer.insert(components.search_start,
"?");
6177 if (idx == input.size()) {
6178 buffer.insert(components.search_start + 1, input);
6179 components.hash_start += uint32_t(input.size() + 1);
6181 buffer.insert(components.search_start + 1, input, 0, idx);
6182 input.remove_prefix(idx);
6185 std::string encoded =
6186 ada::unicode::percent_encode(input, query_percent_encode_set);
6187 buffer.insert(components.search_start + idx + 1, encoded);
6188 components.hash_start +=
6189 uint32_t(encoded.size() + idx + 1);
6196inline void url_aggregator::update_base_pathname(
const std::string_view input) {
6197 ada_log(
"url_aggregator::update_base_pathname '", input,
"' [", input.size(),
6198 " bytes] \n", to_diagram());
6202 const bool begins_with_dashdash = checkers::begins_with(input,
"//");
6203 if (!begins_with_dashdash && has_dash_dot()) {
6204 ada_log(
"url_aggregator::update_base_pathname has /.: \n", to_diagram());
6209 if (begins_with_dashdash && !has_opaque_path && !has_authority() &&
6214 buffer.insert(components.pathname_start,
"/.");
6215 components.pathname_start += 2;
6218 uint32_t difference = replace_and_resize(
6219 components.pathname_start,
6220 components.pathname_start + get_pathname_length(), input);
6221 if (components.search_start != url_components::omitted) {
6222 components.search_start += difference;
6224 if (components.hash_start != url_components::omitted) {
6225 components.hash_start += difference;
6227 ada_log(
"url_aggregator::update_base_pathname end '", input,
"' [",
6228 input.size(),
" bytes] \n", to_diagram());
6232inline void url_aggregator::append_base_pathname(
const std::string_view input) {
6234 "\n", to_diagram());
6237#if ADA_DEVELOPMENT_CHECKS
6239 std::string path_expected(get_pathname());
6240 path_expected.append(input);
6242 uint32_t ending_index = uint32_t(buffer.size());
6243 if (components.search_start != url_components::omitted) {
6244 ending_index = components.search_start;
6245 }
else if (components.hash_start != url_components::omitted) {
6246 ending_index = components.hash_start;
6248 buffer.insert(ending_index, input);
6250 if (components.search_start != url_components::omitted) {
6251 components.search_start += uint32_t(input.size());
6253 if (components.hash_start != url_components::omitted) {
6254 components.hash_start += uint32_t(input.size());
6256#if ADA_DEVELOPMENT_CHECKS
6257 std::string path_after = std::string(get_pathname());
6259 path_expected, path_after,
6260 "append_base_pathname problem after inserting " + std::string(input));
6265inline void url_aggregator::update_base_username(
const std::string_view input) {
6266 ada_log(
"url_aggregator::update_base_username '", input,
"' ",
to_string(),
6267 "\n", to_diagram());
6271 add_authority_slashes_if_needed();
6273 bool has_password = has_non_empty_password();
6274 bool host_starts_with_at = buffer.size() > components.host_start &&
6275 buffer[components.host_start] ==
'@';
6276 uint32_t diff = replace_and_resize(components.protocol_end + 2,
6277 components.username_end, input);
6279 components.username_end += diff;
6280 components.host_start += diff;
6282 if (!input.empty() && !host_starts_with_at) {
6283 buffer.insert(components.host_start,
"@");
6285 }
else if (input.empty() && host_starts_with_at && !has_password) {
6288 buffer.erase(components.host_start, 1);
6292 components.host_end += diff;
6293 components.pathname_start += diff;
6294 if (components.search_start != url_components::omitted) {
6295 components.search_start += diff;
6297 if (components.hash_start != url_components::omitted) {
6298 components.hash_start += diff;
6303inline void url_aggregator::append_base_username(
const std::string_view input) {
6304 ada_log(
"url_aggregator::append_base_username ", input);
6307#if ADA_DEVELOPMENT_CHECKS
6309 std::string username_expected(get_username());
6310 username_expected.append(input);
6312 add_authority_slashes_if_needed();
6315 if (input.empty()) {
6319 uint32_t difference = uint32_t(input.size());
6320 buffer.insert(components.username_end, input);
6321 components.username_end += difference;
6322 components.host_start += difference;
6324 if (buffer[components.host_start] !=
'@' &&
6325 components.host_start != components.host_end) {
6326 buffer.insert(components.host_start,
"@");
6330 components.host_end += difference;
6331 components.pathname_start += difference;
6332 if (components.search_start != url_components::omitted) {
6333 components.search_start += difference;
6335 if (components.hash_start != url_components::omitted) {
6336 components.hash_start += difference;
6338#if ADA_DEVELOPMENT_CHECKS
6339 std::string username_after(get_username());
6341 username_expected, username_after,
6342 "append_base_username problem after inserting " + std::string(input));
6347inline void url_aggregator::clear_password() {
6348 ada_log(
"url_aggregator::clear_password ",
to_string(),
"\n", to_diagram());
6350 if (!has_password()) {
6354 uint32_t diff = components.host_start - components.username_end;
6355 buffer.erase(components.username_end, diff);
6356 components.host_start -= diff;
6357 components.host_end -= diff;
6358 components.pathname_start -= diff;
6359 if (components.search_start != url_components::omitted) {
6360 components.search_start -= diff;
6362 if (components.hash_start != url_components::omitted) {
6363 components.hash_start -= diff;
6367inline void url_aggregator::update_base_password(
const std::string_view input) {
6368 ada_log(
"url_aggregator::update_base_password ", input);
6372 add_authority_slashes_if_needed();
6375 if (input.empty()) {
6379 if (!has_non_empty_username()) {
6380 update_base_username(
"");
6386 bool password_exists = has_password();
6387 uint32_t difference = uint32_t(input.size());
6389 if (password_exists) {
6390 uint32_t current_length =
6391 components.host_start - components.username_end - 1;
6392 buffer.erase(components.username_end + 1, current_length);
6393 difference -= current_length;
6395 buffer.insert(components.username_end,
":");
6399 buffer.insert(components.username_end + 1, input);
6400 components.host_start += difference;
6405 if (buffer[components.host_start] !=
'@') {
6406 buffer.insert(components.host_start,
"@");
6410 components.host_end += difference;
6411 components.pathname_start += difference;
6412 if (components.search_start != url_components::omitted) {
6413 components.search_start += difference;
6415 if (components.hash_start != url_components::omitted) {
6416 components.hash_start += difference;
6421inline void url_aggregator::append_base_password(
const std::string_view input) {
6423 "\n", to_diagram());
6426#if ADA_DEVELOPMENT_CHECKS
6428 std::string password_expected = std::string(get_password());
6429 password_expected.append(input);
6431 add_authority_slashes_if_needed();
6434 if (input.empty()) {
6438 uint32_t difference = uint32_t(input.size());
6439 if (has_password()) {
6440 buffer.insert(components.host_start, input);
6443 buffer.insert(components.username_end,
":");
6444 buffer.insert(components.username_end + 1, input);
6446 components.host_start += difference;
6451 if (buffer[components.host_start] !=
'@') {
6452 buffer.insert(components.host_start,
"@");
6456 components.host_end += difference;
6457 components.pathname_start += difference;
6458 if (components.search_start != url_components::omitted) {
6459 components.search_start += difference;
6461 if (components.hash_start != url_components::omitted) {
6462 components.hash_start += difference;
6464#if ADA_DEVELOPMENT_CHECKS
6465 std::string password_after(get_password());
6467 password_expected, password_after,
6468 "append_base_password problem after inserting " + std::string(input));
6473inline void url_aggregator::update_base_port(uint32_t input) {
6474 ada_log(
"url_aggregator::update_base_port");
6476 if (input == url_components::omitted) {
6482 std::string value = helpers::concat(
":", std::to_string(input));
6483 uint32_t difference = uint32_t(value.size());
6485 if (components.port != url_components::omitted) {
6486 difference -= components.pathname_start - components.host_end;
6487 buffer.erase(components.host_end,
6488 components.pathname_start - components.host_end);
6491 buffer.insert(components.host_end, value);
6492 components.pathname_start += difference;
6493 if (components.search_start != url_components::omitted) {
6494 components.search_start += difference;
6496 if (components.hash_start != url_components::omitted) {
6497 components.hash_start += difference;
6499 components.port = input;
6503inline void url_aggregator::clear_port() {
6504 ada_log(
"url_aggregator::clear_port");
6506 if (components.port == url_components::omitted) {
6509 uint32_t length = components.pathname_start - components.host_end;
6510 buffer.erase(components.host_end, length);
6511 components.pathname_start -= length;
6512 if (components.search_start != url_components::omitted) {
6513 components.search_start -= length;
6515 if (components.hash_start != url_components::omitted) {
6516 components.hash_start -= length;
6518 components.port = url_components::omitted;
6522[[nodiscard]]
inline uint32_t url_aggregator::retrieve_base_port()
const {
6523 ada_log(
"url_aggregator::retrieve_base_port");
6524 return components.port;
6527inline void url_aggregator::clear_search() {
6528 ada_log(
"url_aggregator::clear_search");
6530 if (components.search_start == url_components::omitted) {
6534 if (components.hash_start == url_components::omitted) {
6535 buffer.resize(components.search_start);
6537 buffer.erase(components.search_start,
6538 components.hash_start - components.search_start);
6539 components.hash_start = components.search_start;
6542 components.search_start = url_components::omitted;
6544#if ADA_DEVELOPMENT_CHECKS
6546 "search should have been cleared on buffer=" + buffer +
6547 " with " + components.to_string() +
"\n" + to_diagram());
6552inline void url_aggregator::clear_hash() {
6553 ada_log(
"url_aggregator::clear_hash");
6555 if (components.hash_start == url_components::omitted) {
6558 buffer.resize(components.hash_start);
6559 components.hash_start = url_components::omitted;
6561#if ADA_DEVELOPMENT_CHECKS
6563 "hash should have been cleared on buffer=" + buffer +
6564 " with " + components.to_string() +
"\n" + to_diagram());
6569inline void url_aggregator::clear_pathname() {
6570 ada_log(
"url_aggregator::clear_pathname");
6572 uint32_t ending_index = uint32_t(buffer.size());
6573 if (components.search_start != url_components::omitted) {
6574 ending_index = components.search_start;
6575 }
else if (components.hash_start != url_components::omitted) {
6576 ending_index = components.hash_start;
6578 uint32_t pathname_length = ending_index - components.pathname_start;
6579 buffer.erase(components.pathname_start, pathname_length);
6580 uint32_t difference = pathname_length;
6581 if (components.pathname_start == components.host_end + 2 &&
6582 buffer[components.host_end] ==
'/' &&
6583 buffer[components.host_end + 1] ==
'.') {
6584 components.pathname_start -= 2;
6585 buffer.erase(components.host_end, 2);
6588 if (components.search_start != url_components::omitted) {
6589 components.search_start -= difference;
6591 if (components.hash_start != url_components::omitted) {
6592 components.hash_start -= difference;
6594 ada_log(
"url_aggregator::clear_pathname completed, running checks...");
6595#if ADA_DEVELOPMENT_CHECKS
6597 "pathname should have been cleared on buffer=" + buffer +
6598 " with " + components.to_string() +
"\n" + to_diagram());
6601 ada_log(
"url_aggregator::clear_pathname completed, running checks... ok");
6604inline void url_aggregator::clear_hostname() {
6605 ada_log(
"url_aggregator::clear_hostname");
6607 if (!has_authority()) {
6612 uint32_t hostname_length = components.host_end - components.host_start;
6613 uint32_t start = components.host_start;
6616 if (hostname_length > 0 && buffer[start] ==
'@') {
6620 buffer.erase(start, hostname_length);
6621 components.host_end = start;
6622 components.pathname_start -= hostname_length;
6623 if (components.search_start != url_components::omitted) {
6624 components.search_start -= hostname_length;
6626 if (components.hash_start != url_components::omitted) {
6627 components.hash_start -= hostname_length;
6629#if ADA_DEVELOPMENT_CHECKS
6631 "hostname should have been cleared on buffer=" + buffer +
6632 " with " + components.to_string() +
"\n" + to_diagram());
6636 "hostname should have been cleared on buffer=" + buffer +
6637 " with " + components.to_string() +
"\n" + to_diagram());
6641[[nodiscard]]
inline bool url_aggregator::has_hash() const noexcept {
6642 ada_log(
"url_aggregator::has_hash");
6643 return components.hash_start != url_components::omitted;
6646[[nodiscard]]
inline bool url_aggregator::has_search() const noexcept {
6647 ada_log(
"url_aggregator::has_search");
6648 return components.search_start != url_components::omitted;
6652 ada_log(
"url_aggregator::has_credentials");
6653 return has_non_empty_username() || has_non_empty_password();
6656inline bool url_aggregator::cannot_have_credentials_or_port()
const {
6657 ada_log(
"url_aggregator::cannot_have_credentials_or_port");
6658 return type == ada::scheme::type::FILE ||
6659 components.host_start == components.host_end;
6663url_aggregator::get_components() const noexcept {
6667[[nodiscard]]
inline bool ada::url_aggregator::has_authority() const noexcept {
6668 ada_log(
"url_aggregator::has_authority");
6671 return components.protocol_end + 2 <= components.host_start &&
6672 helpers::substring(buffer, components.protocol_end,
6673 components.protocol_end + 2) ==
"//";
6676inline void ada::url_aggregator::add_authority_slashes_if_needed() noexcept {
6677 ada_log(
"url_aggregator::add_authority_slashes_if_needed");
6682 if (has_authority()) {
6688 buffer.insert(components.protocol_end,
"//");
6689 components.username_end += 2;
6690 components.host_start += 2;
6691 components.host_end += 2;
6692 components.pathname_start += 2;
6693 if (components.search_start != url_components::omitted) {
6694 components.search_start += 2;
6696 if (components.hash_start != url_components::omitted) {
6697 components.hash_start += 2;
6702inline void ada::url_aggregator::reserve(uint32_t capacity) {
6703 buffer.reserve(capacity);
6706inline bool url_aggregator::has_non_empty_username() const noexcept {
6707 ada_log(
"url_aggregator::has_non_empty_username");
6708 return components.protocol_end + 2 < components.username_end;
6711inline bool url_aggregator::has_non_empty_password() const noexcept {
6712 ada_log(
"url_aggregator::has_non_empty_password");
6713 return components.host_start - components.username_end > 0;
6716inline bool url_aggregator::has_password() const noexcept {
6717 ada_log(
"url_aggregator::has_password");
6719 return components.host_start > components.username_end &&
6720 buffer[components.username_end] ==
':';
6723inline bool url_aggregator::has_empty_hostname() const noexcept {
6724 if (!has_hostname()) {
6727 if (components.host_start == components.host_end) {
6730 if (components.host_end > components.host_start + 1) {
6733 return components.username_end != components.host_start;
6736inline bool url_aggregator::has_hostname() const noexcept {
6737 return has_authority();
6740inline bool url_aggregator::has_port() const noexcept {
6741 ada_log(
"url_aggregator::has_port");
6744 return has_hostname() && components.pathname_start != components.host_end;
6747[[nodiscard]]
inline bool url_aggregator::has_dash_dot() const noexcept {
6751 ada_log(
"url_aggregator::has_dash_dot");
6752#if ADA_DEVELOPMENT_CHECKS
6756 if (components.pathname_start == components.host_end + 2) {
6758 buffer[components.host_end + 1] ==
'.') ||
6759 (buffer[components.host_end] ==
':' &&
6760 checkers::is_digit(buffer[components.host_end + 1])));
6762 if (components.pathname_start == components.host_end + 2 &&
6763 buffer[components.host_end] ==
'/' &&
6764 buffer[components.host_end + 1] ==
'.') {
6774 return components.pathname_start == components.host_end + 2 &&
6775 !has_opaque_path && buffer[components.host_end] ==
'/' &&
6776 buffer[components.host_end + 1] ==
'.';
6779[[nodiscard]]
inline std::string_view url_aggregator::get_href()
6781 ada_log(
"url_aggregator::get_href");
6786 std::string_view view,
bool check_trailing_content)
noexcept {
6787 ada_log(
"url_aggregator::parse_port('", view,
"') ", view.size());
6788 uint16_t parsed_port{};
6789 auto r = std::from_chars(view.data(), view.data() + view.size(), parsed_port);
6790 if (r.ec == std::errc::result_out_of_range) {
6791 ada_log(
"parse_port: std::errc::result_out_of_range");
6795 ada_log(
"parse_port: ", parsed_port);
6796 const size_t consumed = size_t(r.ptr - view.data());
6797 ada_log(
"parse_port: consumed ", consumed);
6798 if (check_trailing_content) {
6800 (consumed == view.size() || view[consumed] ==
'/' ||
6801 view[consumed] ==
'?' || (is_special() && view[consumed] ==
'\\'));
6803 ada_log(
"parse_port: is_valid = ", is_valid);
6805 ada_log(
"parse_port", r.ec == std::errc());
6807 auto default_port = scheme_default_port();
6808 bool is_port_valid = (default_port == 0 && parsed_port == 0) ||
6809 (default_port != parsed_port);
6810 if (r.ec == std::errc() && is_port_valid) {
6811 update_base_port(parsed_port);
6819inline void url_aggregator::set_protocol_as_file() {
6820 ada_log(
"url_aggregator::set_protocol_as_file ");
6822 type = ada::scheme::type::FILE;
6825 uint32_t new_difference = 5 - components.protocol_end;
6827 if (buffer.empty()) {
6828 buffer.append(
"file:");
6830 buffer.erase(0, components.protocol_end);
6831 buffer.insert(0,
"file:");
6833 components.protocol_end = 5;
6836 components.username_end += new_difference;
6837 components.host_start += new_difference;
6838 components.host_end += new_difference;
6839 components.pathname_start += new_difference;
6840 if (components.search_start != url_components::omitted) {
6841 components.search_start += new_difference;
6843 if (components.hash_start != url_components::omitted) {
6844 components.hash_start += new_difference;
6849inline std::ostream &
operator<<(std::ostream &out,
6862#ifndef ADA_URL_SEARCH_PARAMS_H
6863#define ADA_URL_SEARCH_PARAMS_H
6867#include <string_view>
6878template <
typename T, url_search_params_iter_type Type>
6879struct url_search_params_iter;
6881typedef std::pair<std::string_view, std::string_view> key_value_view_pair;
6883using url_search_params_keys_iter =
6884 url_search_params_iter<std::string_view, url_search_params_iter_type::KEYS>;
6885using url_search_params_values_iter =
6886 url_search_params_iter<std::string_view,
6887 url_search_params_iter_type::VALUES>;
6888using url_search_params_entries_iter =
6889 url_search_params_iter<key_value_view_pair,
6890 url_search_params_iter_type::ENTRIES>;
6910 [[nodiscard]]
inline size_t size() const noexcept;
6915 inline
void append(std::string_view key, std::string_view value);
6920 inline
void remove(std::string_view key);
6921 inline
void remove(std::string_view key, std::string_view value);
6926 inline std::optional<std::string_view> get(std::string_view key);
6931 inline std::vector<std::
string> get_all(std::string_view key);
6936 inline
bool has(std::string_view key) noexcept;
6937 inline
bool has(std::string_view key, std::string_view value) noexcept;
6942 inline
void set(std::string_view key, std::string_view value);
6952 inline std::
string to_string() const;
6984 inline auto begin()
const {
return params.begin(); }
6985 inline auto end()
const {
return params.end(); }
6986 inline auto front()
const {
return params.front(); }
6987 inline auto back()
const {
return params.back(); }
6988 inline auto operator[](
size_t index)
const {
return params[index]; }
6996 void reset(std::string_view input);
6999 typedef std::pair<std::string, std::string> key_value_pair;
7000 std::vector<key_value_pair> params{};
7005 void initialize(std::string_view init);
7007 template <
typename T, url_search_params_iter_type Type>
7017template <
typename T, url_search_params_iter_type Type>
7052#ifndef ADA_URL_SEARCH_PARAMS_INL_H
7053#define ADA_URL_SEARCH_PARAMS_INL_H
7059#include <string_view>
7065template <
typename T, ada::url_search_params_iter_type Type>
7066url_search_params url_search_params_iter<T, Type>::EMPTY;
7068inline void url_search_params::reset(std::string_view input) {
7073inline void url_search_params::initialize(std::string_view input) {
7074 if (!input.empty() && input.front() ==
'?') {
7075 input.remove_prefix(1);
7078 auto process_key_value = [&](
const std::string_view current) {
7079 auto equal = current.find(
'=');
7081 if (equal == std::string_view::npos) {
7082 std::string name(current);
7083 std::replace(name.begin(), name.end(),
'+',
' ');
7084 params.emplace_back(unicode::percent_decode(name, name.find(
'%')),
"");
7086 std::string name(current.substr(0, equal));
7087 std::string value(current.substr(equal + 1));
7089 std::replace(name.begin(), name.end(),
'+',
' ');
7090 std::replace(value.begin(), value.end(),
'+',
' ');
7092 params.emplace_back(unicode::percent_decode(name, name.find(
'%')),
7093 unicode::percent_decode(value, value.find(
'%')));
7097 while (!input.empty()) {
7098 auto ampersand_index = input.find(
'&');
7100 if (ampersand_index == std::string_view::npos) {
7101 if (!input.empty()) {
7102 process_key_value(input);
7105 }
else if (ampersand_index != 0) {
7106 process_key_value(input.substr(0, ampersand_index));
7109 input.remove_prefix(ampersand_index + 1);
7114 const std::string_view value) {
7115 params.emplace_back(key, value);
7121 const std::string_view key) {
7122 auto entry = std::find_if(params.begin(), params.end(),
7123 [&key](
auto ¶m) { return param.first == key; });
7125 if (entry == params.end()) {
7126 return std::nullopt;
7129 return entry->second;
7133 const std::string_view key) {
7134 std::vector<std::string> out{};
7136 for (
auto ¶m : params) {
7137 if (param.first == key) {
7138 out.emplace_back(param.second);
7146 auto entry = std::find_if(params.begin(), params.end(),
7147 [&key](
auto ¶m) { return param.first == key; });
7148 return entry != params.end();
7152 std::string_view value)
noexcept {
7154 std::find_if(params.begin(), params.end(), [&key, &value](
auto ¶m) {
7155 return param.first == key && param.second == value;
7157 return entry != params.end();
7163 for (
size_t i = 0; i < params.size(); i++) {
7164 auto key = ada::unicode::percent_encode(params[i].first, character_set);
7165 auto value = ada::unicode::percent_encode(params[i].second, character_set);
7168 std::replace(key.begin(), key.end(),
' ',
'+');
7169 std::replace(value.begin(), value.end(),
' ',
'+');
7182 const std::string_view value) {
7183 const auto find = [&key](
auto ¶m) {
return param.first == key; };
7185 auto it = std::find_if(params.begin(), params.end(), find);
7187 if (it == params.end()) {
7188 params.emplace_back(key, value);
7191 params.erase(std::remove_if(std::next(it), params.end(), find),
7198 std::remove_if(params.begin(), params.end(),
7199 [&key](
auto ¶m) { return param.first == key; }),
7204 const std::string_view value) {
7205 params.erase(std::remove_if(params.begin(), params.end(),
7206 [&key, &value](
auto ¶m) {
7207 return param.first == key &&
7208 param.second == value;
7214 std::stable_sort(params.begin(), params.end(),
7215 [](
const key_value_pair &lhs,
const key_value_pair &rhs) {
7216 return lhs.first < rhs.first;
7238template <
typename T, url_search_params_iter_type Type>
7240 return pos < params.params.size();
7246 return std::nullopt;
7248 return params.params[pos++].first;
7254 return std::nullopt;
7256 return params.params[pos++].second;
7260inline std::optional<key_value_view_pair>
7263 return std::nullopt;
7265 return params.params[pos++];
7279#ifndef ADA_ADA_VERSION_H
7280#define ADA_ADA_VERSION_H
7282#define ADA_VERSION "2.9.0"
7302#ifndef ADA_IMPLEMENTATION_H
7303#define ADA_IMPLEMENTATION_H
7312template <
class result_type = ada::url_aggregator>
7324template <
class result_type = ada::url_aggregator>
7326 std::string_view input,
const result_type* base_url =
nullptr);
7329 const url* base_url);
7331 std::string_view input,
const url_aggregator* base_url);
7340 const std::string_view* base_input =
nullptr);
virtual const char * what() const noexcept override
const E & error() const &
const E && error() const &&
constexpr expected(const unexpected< G > &e)
expected & operator=(const expected &rhs)=default
constexpr T value_or(U &&v) const &
TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval< expected >(), std::declval< F && >())) transform(F &&f) &&
constexpr decltype(map_error_impl(std::declval< const expected && >(), std::declval< F && >())) transform_error(F &&f) const &&
TL_EXPECTED_11_CONSTEXPR T * operator->()
TL_EXPECTED_11_CONSTEXPR expected(const expected< U, G > &rhs)
TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval< expected && >(), std::declval< F && >())) transform_error(F &&f) &&
constexpr auto and_then(F &&f) const &&-> decltype(and_then_impl(std::declval< expected const && >(), std::forward< F >(f)))
constexpr const E && error() const &&
TL_EXPECTED_11_CONSTEXPR const U & value() const &
constexpr decltype(expected_map_impl(std::declval< const expected && >(), std::declval< F && >())) transform(F &&f) const &&
TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) &&-> decltype(and_then_impl(std::declval< expected && >(), std::forward< F >(f)))
TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval< expected >(), std::declval< F && >())) map(F &&f) &&
void emplace(std::initializer_list< U > il, Args &&...args)
constexpr expected(const expected &rhs)=default
TL_EXPECTED_11_CONSTEXPR U & operator*() &
constexpr const E & error() const &
constexpr bool has_value() const noexcept
TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) &&
detail::enable_if_t< detail::is_swappable< OT >::value &&detail::is_swappable< OE >::value &&(std::is_nothrow_move_constructible< OT >::value||std::is_nothrow_move_constructible< OE >::value)> swap(expected &rhs) noexcept(std::is_nothrow_move_constructible< T >::value &&detail::is_nothrow_swappable< T >::value &&std::is_nothrow_move_constructible< E >::value &&detail::is_nothrow_swappable< E >::value)
TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval< expected & >(), std::declval< F && >())) map_error(F &&f) &
constexpr expected()=default
TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval< expected & >(), std::declval< F && >())) map(F &&f) &
constexpr auto and_then(F &&f) const &-> decltype(and_then_impl(std::declval< expected const & >(), std::forward< F >(f)))
TL_EXPECTED_11_CONSTEXPR expected(expected< U, G > &&rhs)
constexpr expected(unexpected< G > &&e) noexcept(std::is_nothrow_constructible< E, G && >::value)
TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v)
constexpr expected(unexpect_t, Args &&...args)
expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) &
constexpr const T * operator->() const
constexpr decltype(expected_map_impl(std::declval< const expected & >(), std::declval< F && >())) transform(F &&f) const &
constexpr expected(unexpected< G > const &e)
expected & operator=(const unexpected< G > &rhs)
void emplace(Args &&...args)
constexpr expected(unexpect_t, std::initializer_list< U > il, Args &&...args)
constexpr decltype(map_error_impl(std::declval< const expected & >(), std::declval< F && >())) map_error(F &&f) const &
expected constexpr or_else(F &&f) const &
TL_EXPECTED_11_CONSTEXPR E && error() &&
constexpr expected(in_place_t, std::initializer_list< U > il, Args &&...args)
constexpr expected(expected &&rhs)=default
TL_EXPECTED_11_CONSTEXPR decltype(expected_map_impl(std::declval< expected & >(), std::declval< F && >())) transform(F &&f) &
constexpr decltype(map_error_impl(std::declval< const expected && >(), std::declval< F && >())) map_error(F &&f) const &&
constexpr const U & operator*() const &
TL_EXPECTED_11_CONSTEXPR const U && value() const &&
constexpr expected(in_place_t, Args &&...args)
TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval< expected & >(), std::declval< F && >())) transform_error(F &&f) &
TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) &-> decltype(and_then_impl(std::declval< expected & >(), std::forward< F >(f)))
expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) &&
unexpected< E > unexpected_type
expected & operator=(expected &&rhs)=default
expected constexpr or_else(F &&f) const &&
expected & operator=(unexpected< G > &&rhs) noexcept
TL_EXPECTED_11_CONSTEXPR U && operator*() &&
constexpr const U && operator*() const &&
constexpr decltype(map_error_impl(std::declval< const expected & >(), std::declval< F && >())) transform_error(F &&f) const &
TL_EXPECTED_11_CONSTEXPR E & error() &
TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval< expected && >(), std::declval< F && >())) map_error(F &&f) &&
TL_EXPECTED_11_CONSTEXPR U & value() &
constexpr decltype(expected_map_impl(std::declval< const expected & >(), std::declval< F && >())) map(F &&f) const &
TL_EXPECTED_11_CONSTEXPR U && value() &&
constexpr decltype(expected_map_impl(std::declval< const expected && >(), std::declval< F && >())) map(F &&f) const &&
TL_EXPECTED_11_CONSTEXPR E & value() &
constexpr unexpected(const E &e)
constexpr unexpected(Args &&...args)
constexpr const E & value() const &
TL_EXPECTED_11_CONSTEXPR E && value() &&
constexpr unexpected(std::initializer_list< U > l, Args &&...args)
constexpr const E && value() const &&
constexpr unexpected(E &&e)
#define ADA_ASSERT_TRUE(COND)
#define ADA_ASSERT_EQUAL(LHS, RHS, MESSAGE)
#define ada_really_inline
Includes the definitions for unicode character sets.
constexpr uint8_t C0_CONTROL_PERCENT_ENCODE[32]
constexpr uint8_t FRAGMENT_PERCENT_ENCODE[32]
constexpr uint8_t PATH_PERCENT_ENCODE[32]
constexpr uint8_t USERINFO_PERCENT_ENCODE[32]
constexpr uint8_t WWW_FORM_URLENCODED_PERCENT_ENCODE[32]
constexpr uint8_t SPECIAL_QUERY_PERCENT_ENCODE[32]
constexpr uint8_t QUERY_PERCENT_ENCODE[32]
ada_really_inline bool bit_at(const uint8_t a[], const uint8_t i)
Includes the definitions for validation functions.
bool has_hex_prefix_unsafe(std::string_view input)
constexpr bool is_normalized_windows_drive_letter(std::string_view input) noexcept
constexpr bool is_windows_drive_letter(std::string_view input) noexcept
constexpr char to_lower(char x) noexcept
bool has_hex_prefix(std::string_view input)
constexpr bool is_alpha(char x) noexcept
constexpr bool is_digit(char x) noexcept
ada_really_inline bool begins_with(std::string_view view, std::string_view prefix)
Includes the definitions for helper functions.
void ascii_map(char *input, size_t length)
bool punycode_to_utf32(std::string_view input, std::u32string &out)
size_t utf32_length_from_utf8(const char *buf, size_t len)
size_t utf32_to_utf8(const char32_t *buf, size_t len, char *utf8_output)
bool constexpr is_ascii(std::u32string_view view)
void normalize(std::u32string &input)
bool utf32_to_punycode(std::u32string_view input, std::string &out)
std::string to_ascii(std::string_view ut8_string)
std::string to_unicode(std::string_view input)
bool begins_with(std::u32string_view view, std::u32string_view prefix)
size_t utf8_length_from_utf32(const char32_t *buf, size_t len)
bool is_label_valid(std::u32string_view label)
bool ascii_has_upper_case(char *input, size_t length)
bool contains_forbidden_domain_code_point(std::string_view ascii_string)
std::u32string map(std::u32string_view input)
size_t utf8_to_utf32(const char *buf, size_t len, char32_t *utf32_output)
bool verify_punycode(std::string_view input)
Includes the definitions for supported parsers.
result_type parse_url(std::string_view user_input, const result_type *base_url=nullptr)
result_type parse_url_impl(std::string_view user_input, const result_type *base_url=nullptr)
Includes the scheme declarations.
constexpr ada::scheme::type get_scheme_type(std::string_view scheme) noexcept
constexpr uint16_t get_special_port(std::string_view scheme) noexcept
Includes the definitions for URL serializers.
Includes the declarations for unicode operations.
ada_really_inline size_t percent_encode_index(const std::string_view input, const uint8_t character_set[])
bool can_parse(std::string_view input, const std::string_view *base_input=nullptr)
template ada::result< url > parse< url >(std::string_view input, const url *base_url)
url_search_params_iter< key_value_view_pair, url_search_params_iter_type::ENTRIES > url_search_params_entries_iter
std::string href_from_file(std::string_view path)
std::ostream & operator<<(std::ostream &out, const ada::url &u)
ada_warn_unused std::string to_string(encoding_type type)
url_search_params_iter< std::string_view, url_search_params_iter_type::KEYS > url_search_params_keys_iter
@ SPECIAL_RELATIVE_OR_AUTHORITY
@ SPECIAL_AUTHORITY_SLASHES
@ SPECIAL_AUTHORITY_IGNORE_SLASHES
template ada::result< url_aggregator > parse< url_aggregator >(std::string_view input, const url_aggregator *base_url)
url_search_params_iter_type
url_search_params_iter< std::string_view, url_search_params_iter_type::VALUES > url_search_params_values_iter
tl::expected< result_type, ada::errors > result
ada_warn_unused ada::result< result_type > parse(std::string_view input, const result_type *base_url=nullptr)
std::false_type can_swap(...) noexcept(false)
static constexpr no_init_t no_init
typename std::remove_reference< T >::type remove_reference_t
is_void_or< T, std::is_move_assignable< T > > is_move_assignable_or_void
typename std::enable_if< E, T >::type enable_if_t
is_void_or< T, std::is_copy_assignable< T > > is_copy_assignable_or_void
typename std::decay< T >::type decay_t
constexpr auto invoke(Fn &&f, Args &&...args) noexcept(noexcept(std::mem_fn(f)(std::forward< Args >(args)...))) -> decltype(std::mem_fn(f)(std::forward< Args >(args)...))
typename detail::decay_t< Exp >::error_type err_t
conditional_t< std::is_void< T >::value, std::true_type, U > is_void_or
typename std::remove_const< T >::type remove_const_t
detail::enable_if_t< std::is_constructible< T, U && >::value && !std::is_same< detail::decay_t< U >, in_place_t >::value && !std::is_same< expected< T, E >, detail::decay_t< U > >::value && !std::is_same< unexpected< E >, detail::decay_t< U > >::value > expected_enable_forward_value
constexpr auto map_error_impl(Exp &&exp, F &&f) -> expected< exp_t< Exp >, detail::decay_t< Ret > >
auto and_then_impl(Exp &&exp, F &&f) -> Ret
typename std::conditional< B, T, F >::type conditional_t
is_void_or< T, std::is_move_constructible< T > > is_move_constructible_or_void
TL_EXPECTED_11_CONSTEXPR void throw_exception(E &&e)
typename invoke_result< F, Us... >::type invoke_result_t
detail::enable_if_t< std::is_constructible< T, UR >::value && std::is_constructible< E, GR >::value && !std::is_constructible< T, expected< U, G > & >::value && !std::is_constructible< T, expected< U, G > && >::value && !std::is_constructible< T, const expected< U, G > & >::value && !std::is_constructible< T, const expected< U, G > && >::value && !std::is_convertible< expected< U, G > &, T >::value && !std::is_convertible< expected< U, G > &&, T >::value && !std::is_convertible< const expected< U, G > &, T >::value && !std::is_convertible< const expected< U, G > &&, T >::value > expected_enable_from_other
auto or_else_impl(Exp &&exp, F &&f) -> Ret
constexpr auto expected_map_impl(Exp &&exp, F &&f) -> ret_t< Exp, detail::decay_t< Ret > >
typename detail::decay_t< Exp >::value_type exp_t
is_void_or< T, std::is_copy_constructible< T > > is_copy_constructible_or_void
constexpr bool operator>=(const unexpected< E > &lhs, const unexpected< E > &rhs)
constexpr bool operator>(const unexpected< E > &lhs, const unexpected< E > &rhs)
constexpr bool operator!=(const unexpected< E > &lhs, const unexpected< E > &rhs)
constexpr bool operator==(const unexpected< E > &lhs, const unexpected< E > &rhs)
constexpr bool operator<=(const unexpected< E > &lhs, const unexpected< E > &rhs)
static constexpr in_place_t in_place
static constexpr unexpect_t unexpect
constexpr bool operator<(const unexpected< E > &lhs, const unexpected< E > &rhs)
unexpected< typename std::decay< E >::type > make_unexpected(E &&e)
url_aggregator & operator=(const url_aggregator &u)=default
url_aggregator & operator=(url_aggregator &&u) noexcept=default
void set_hash(std::string_view input)
std::string to_string() const override
bool set_protocol(std::string_view input)
bool has_valid_domain() const noexcept override
bool set_hostname(std::string_view input)
bool set_password(std::string_view input)
~url_aggregator() override=default
bool set_pathname(std::string_view input)
bool set_href(std::string_view input)
void set_search(std::string_view input)
url_aggregator(url_aggregator &&u) noexcept=default
bool set_host(std::string_view input)
bool set_port(std::string_view input)
url_aggregator(const url_aggregator &u)=default
bool set_username(std::string_view input)
Base class of URL implementations.
virtual ~url_base()=default
ada_really_inline bool is_special() const noexcept
virtual bool has_valid_domain() const noexcept=0
virtual std::string get_origin() const noexcept=0
virtual std::string to_string() const =0
URL Component representations using offsets.
bool check_offset_consistency() const noexcept
std::string to_string() const
url_components & operator=(url_components &&u) noexcept=default
~url_components()=default
url_components(url_components &&u) noexcept=default
url_components(const url_components &u)=default
url_components & operator=(const url_components &u)=default
static constexpr uint32_t omitted
url_search_params_iter(const url_search_params_iter &u)=default
url_search_params_iter & operator=(url_search_params_iter &&u) noexcept=default
std::optional< T > next()
std::optional< T > next()
url_search_params_iter(url_search_params_iter &&u) noexcept=default
~url_search_params_iter()=default
url_search_params_iter & operator=(const url_search_params_iter &u)=default
void set(std::string_view key, std::string_view value)
std::vector< std::string > get_all(std::string_view key)
void remove(std::string_view key)
url_search_params(const url_search_params &u)=default
url_search_params(url_search_params &&u) noexcept=default
auto operator[](size_t index) const
url_search_params_entries_iter get_entries()
url_search_params()=default
std::string to_string() const
url_search_params & operator=(url_search_params &&u) noexcept=default
url_search_params_keys_iter get_keys()
size_t size() const noexcept
url_search_params & operator=(const url_search_params &u)=default
void append(std::string_view key, std::string_view value)
url_search_params(const std::string_view input)
url_search_params_values_iter get_values()
~url_search_params()=default
std::optional< std::string_view > get(std::string_view key)
bool has(std::string_view key) noexcept
Generic URL struct reliant on std::string instantiation.
url(url &&u) noexcept=default
bool has_empty_hostname() const noexcept
url & operator=(url &&u) noexcept=default
url & operator=(const url &u)=default
url(const url &u)=default
std::string to_string() const override
constexpr default_constructor_tag()=default
expected_copy_assign_base(const expected_copy_assign_base &rhs)=default
expected_copy_assign_base(expected_copy_assign_base &&rhs)=default
expected_copy_assign_base & operator=(expected_copy_assign_base &&rhs)=default
expected_copy_assign_base & operator=(const expected_copy_assign_base &rhs)
expected_copy_assign_base()=default
expected_copy_base(expected_copy_base &&rhs)=default
expected_copy_base()=default
expected_copy_base & operator=(expected_copy_base &&rhs)=default
expected_copy_base(const expected_copy_base &rhs)
expected_copy_base & operator=(const expected_copy_base &rhs)=default
constexpr expected_default_ctor_base() noexcept=delete
constexpr expected_default_ctor_base() noexcept=default
expected_delete_assign_base(expected_delete_assign_base &&) noexcept=default
expected_delete_assign_base()=default
expected_delete_assign_base(const expected_delete_assign_base &)=default
expected_delete_assign_base(expected_delete_assign_base &&) noexcept=default
expected_delete_assign_base()=default
expected_delete_assign_base(const expected_delete_assign_base &)=default
expected_delete_assign_base(const expected_delete_assign_base &)=default
expected_delete_assign_base()=default
expected_delete_assign_base(expected_delete_assign_base &&) noexcept=default
expected_delete_assign_base(const expected_delete_assign_base &)=default
expected_delete_assign_base(expected_delete_assign_base &&) noexcept=default
expected_delete_assign_base()=default
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept=delete
expected_delete_ctor_base()=default
expected_delete_ctor_base(const expected_delete_ctor_base &)=delete
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept=default
expected_delete_ctor_base(const expected_delete_ctor_base &)=delete
expected_delete_ctor_base()=default
expected_delete_ctor_base()=default
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept=delete
expected_delete_ctor_base(const expected_delete_ctor_base &)=default
expected_delete_ctor_base()=default
expected_delete_ctor_base(const expected_delete_ctor_base &)=default
expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept=default
expected_move_assign_base()=default
expected_move_assign_base & operator=(expected_move_assign_base &&rhs) noexcept(std::is_nothrow_move_constructible< T >::value &&std::is_nothrow_move_assignable< T >::value)
expected_move_assign_base(expected_move_assign_base &&rhs)=default
expected_move_assign_base(const expected_move_assign_base &rhs)=default
expected_move_assign_base & operator=(const expected_move_assign_base &rhs)=default
expected_move_base & operator=(expected_move_base &&rhs)=default
expected_move_base & operator=(const expected_move_base &rhs)=default
expected_move_base()=default
expected_move_base(const expected_move_base &rhs)=default
expected_move_base(expected_move_base &&rhs) noexcept(std::is_nothrow_move_constructible< T >::value)
void construct() noexcept
constexpr const unexpected< E > && geterr() const &&
constexpr const unexpected< E > & geterr() const &
void assign(Rhs &&rhs) noexcept
void construct_error(Args &&...args) noexcept
TL_EXPECTED_11_CONSTEXPR void destroy_val()
TL_EXPECTED_11_CONSTEXPR unexpected< E > & geterr() &
void construct_with(Rhs &&) noexcept
TL_EXPECTED_11_CONSTEXPR unexpected< E > && geterr() &&
constexpr const T && get() const &&
TL_EXPECTED_11_CONSTEXPR unexpected< E > && geterr() &&
constexpr const unexpected< E > & geterr() const &
constexpr const T & get() const &
TL_EXPECTED_11_CONSTEXPR void destroy_val()
constexpr const unexpected< E > && geterr() const &&
void construct(Args &&...args) noexcept
void assign(const expected_operations_base &rhs) noexcept
TL_EXPECTED_11_CONSTEXPR unexpected< E > & geterr() &
void construct_with(Rhs &&rhs) noexcept
void construct_error(Args &&...args) noexcept
TL_EXPECTED_11_CONSTEXPR T && get() &&
void assign_common(Rhs &&rhs)
void assign(expected_operations_base &&rhs) noexcept
TL_EXPECTED_11_CONSTEXPR T & get() &
constexpr expected_storage_base(in_place_t, std::initializer_list< U > il, Args &&...args)
constexpr expected_storage_base(no_init_t)
constexpr expected_storage_base(in_place_t, Args &&...args)
constexpr expected_storage_base()
constexpr expected_storage_base(unexpect_t, Args &&...args)
constexpr expected_storage_base(unexpect_t, std::initializer_list< U > il, Args &&...args)
unexpected< E > m_unexpect
TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t)
constexpr expected_storage_base()
constexpr expected_storage_base(unexpect_t, std::initializer_list< U > il, Args &&...args)
constexpr expected_storage_base(unexpect_t, Args &&...args)
unexpected< E > m_unexpect
constexpr expected_storage_base(in_place_t, Args &&...args)
constexpr expected_storage_base(in_place_t, std::initializer_list< U > il, Args &&...args)
constexpr expected_storage_base()
constexpr expected_storage_base(no_init_t)
~expected_storage_base()=default
constexpr expected_storage_base(in_place_t, Args &&...args)
constexpr expected_storage_base(in_place_t, std::initializer_list< U > il, Args &&...args)
constexpr expected_storage_base(unexpect_t, Args &&...args)
constexpr expected_storage_base(unexpect_t, std::initializer_list< U > il, Args &&...args)
unexpected< E > m_unexpect
constexpr expected_storage_base(in_place_t)
constexpr expected_storage_base()
constexpr expected_storage_base(unexpect_t, std::initializer_list< U > il, Args &&...args)
unexpected< E > m_unexpect
constexpr expected_storage_base(unexpect_t, Args &&...args)
constexpr expected_storage_base(no_init_t)
constexpr expected_storage_base(in_place_t)
constexpr expected_storage_base(no_init_t)
constexpr expected_storage_base(unexpect_t, Args &&...args)
~expected_storage_base()=default
constexpr expected_storage_base(unexpect_t, std::initializer_list< U > il, Args &&...args)
unexpected< E > m_unexpect
constexpr expected_storage_base(unexpect_t, Args &&...args)
constexpr expected_storage_base(no_init_t)
constexpr expected_storage_base()
constexpr expected_storage_base(in_place_t, std::initializer_list< U > il, Args &&...args)
constexpr expected_storage_base(in_place_t, Args &&...args)
unexpected< E > m_unexpect
constexpr expected_storage_base(unexpect_t, std::initializer_list< U > il, Args &&...args)
decltype(detail::invoke(std::declval< F >(), std::declval< Us >()...)) type