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)
482#ifndef __has_cpp_attribute
483#define ada_lifetime_bound
484#elif __has_cpp_attribute(msvc::lifetimebound)
485#define ada_lifetime_bound [[msvc::lifetimebound]]
486#elif __has_cpp_attribute(clang::lifetimebound)
487#define ada_lifetime_bound [[clang::lifetimebound]]
488#elif __has_cpp_attribute(lifetimebound)
489#define ada_lifetime_bound [[lifetimebound]]
491#define ada_lifetime_bound
519constexpr char hex[1024] =
520 "%00\0%01\0%02\0%03\0%04\0%05\0%06\0%07\0"
521 "%08\0%09\0%0A\0%0B\0%0C\0%0D\0%0E\0%0F\0"
522 "%10\0%11\0%12\0%13\0%14\0%15\0%16\0%17\0"
523 "%18\0%19\0%1A\0%1B\0%1C\0%1D\0%1E\0%1F\0"
524 "%20\0%21\0%22\0%23\0%24\0%25\0%26\0%27\0"
525 "%28\0%29\0%2A\0%2B\0%2C\0%2D\0%2E\0%2F\0"
526 "%30\0%31\0%32\0%33\0%34\0%35\0%36\0%37\0"
527 "%38\0%39\0%3A\0%3B\0%3C\0%3D\0%3E\0%3F\0"
528 "%40\0%41\0%42\0%43\0%44\0%45\0%46\0%47\0"
529 "%48\0%49\0%4A\0%4B\0%4C\0%4D\0%4E\0%4F\0"
530 "%50\0%51\0%52\0%53\0%54\0%55\0%56\0%57\0"
531 "%58\0%59\0%5A\0%5B\0%5C\0%5D\0%5E\0%5F\0"
532 "%60\0%61\0%62\0%63\0%64\0%65\0%66\0%67\0"
533 "%68\0%69\0%6A\0%6B\0%6C\0%6D\0%6E\0%6F\0"
534 "%70\0%71\0%72\0%73\0%74\0%75\0%76\0%77\0"
535 "%78\0%79\0%7A\0%7B\0%7C\0%7D\0%7E\0%7F\0"
536 "%80\0%81\0%82\0%83\0%84\0%85\0%86\0%87\0"
537 "%88\0%89\0%8A\0%8B\0%8C\0%8D\0%8E\0%8F\0"
538 "%90\0%91\0%92\0%93\0%94\0%95\0%96\0%97\0"
539 "%98\0%99\0%9A\0%9B\0%9C\0%9D\0%9E\0%9F\0"
540 "%A0\0%A1\0%A2\0%A3\0%A4\0%A5\0%A6\0%A7\0"
541 "%A8\0%A9\0%AA\0%AB\0%AC\0%AD\0%AE\0%AF\0"
542 "%B0\0%B1\0%B2\0%B3\0%B4\0%B5\0%B6\0%B7\0"
543 "%B8\0%B9\0%BA\0%BB\0%BC\0%BD\0%BE\0%BF\0"
544 "%C0\0%C1\0%C2\0%C3\0%C4\0%C5\0%C6\0%C7\0"
545 "%C8\0%C9\0%CA\0%CB\0%CC\0%CD\0%CE\0%CF\0"
546 "%D0\0%D1\0%D2\0%D3\0%D4\0%D5\0%D6\0%D7\0"
547 "%D8\0%D9\0%DA\0%DB\0%DC\0%DD\0%DE\0%DF\0"
548 "%E0\0%E1\0%E2\0%E3\0%E4\0%E5\0%E6\0%E7\0"
549 "%E8\0%E9\0%EA\0%EB\0%EC\0%ED\0%EE\0%EF\0"
550 "%F0\0%F1\0%F2\0%F3\0%F4\0%F5\0%F6\0%F7\0"
551 "%F8\0%F9\0%FA\0%FB\0%FC\0%FD\0%FE\0%FF";
555 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
557 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
559 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
561 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
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 | 0x00,
575 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
577 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
579 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
581 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
583 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
585 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 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,
607 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 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
621 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
623 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
625 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
627 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
629 0x01 | 0x00 | 0x04 | 0x08 | 0x00 | 0x00 | 0x00 | 0x80,
631 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
633 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
635 0x00 | 0x00 | 0x00 | 0x00 | 0x10 | 0x00 | 0x40 | 0x00,
637 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
639 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
641 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
643 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
645 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
647 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
649 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
651 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 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,
673 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 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
687 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
689 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
691 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
693 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
695 0x01 | 0x00 | 0x04 | 0x08 | 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 | 0x10 | 0x00 | 0x40 | 0x00,
703 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
705 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
707 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
709 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
711 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
713 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
715 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
717 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 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,
739 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 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
753 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
755 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
757 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
759 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
761 0x01 | 0x00 | 0x04 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
763 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
765 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
767 0x00 | 0x00 | 0x00 | 0x00 | 0x10 | 0x00 | 0x40 | 0x00,
769 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
771 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
773 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
775 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
777 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
779 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
781 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
783 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 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,
805 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 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
819 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
821 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
823 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
825 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
827 0x01 | 0x00 | 0x04 | 0x08 | 0x00 | 0x00 | 0x00 | 0x00,
829 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x80,
831 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
833 0x00 | 0x00 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
835 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
837 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
839 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
841 0x00 | 0x00 | 0x00 | 0x08 | 0x10 | 0x20 | 0x40 | 0x00,
843 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
845 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
847 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
849 0x00 | 0x00 | 0x00 | 0x08 | 0x10 | 0x20 | 0x00 | 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,
871 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 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
885 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
887 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
889 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
891 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
893 0x01 | 0x00 | 0x04 | 0x08 | 0x00 | 0x00 | 0x00 | 0x00,
895 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
897 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
899 0x00 | 0x00 | 0x00 | 0x00 | 0x10 | 0x00 | 0x40 | 0x80,
901 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
903 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
905 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
907 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
909 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
911 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
913 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
915 0x00 | 0x00 | 0x00 | 0x08 | 0x00 | 0x20 | 0x00 | 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,
937 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 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
951 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
953 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
955 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
957 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
959 0x00 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
961 0x01 | 0x02 | 0x00 | 0x08 | 0x10 | 0x00 | 0x00 | 0x80,
963 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
965 0x00 | 0x00 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
967 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
969 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
971 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
973 0x00 | 0x00 | 0x00 | 0x08 | 0x00 | 0x20 | 0x40 | 0x00,
975 0x01 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
977 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
979 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00 | 0x00,
981 0x00 | 0x00 | 0x00 | 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,
1003 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
1005 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
1007 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
1009 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
1011 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80,
1013 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80};
1016 return !!(a[i >> 3] & (1 << (i & 7)));
1028#ifndef ADA_CHECKERS_INL_H
1029#define ADA_CHECKERS_INL_H
1033#include <string_view>
1040 uint32_t value_one = 1;
1041 bool is_little_endian = (
reinterpret_cast<char*
>(&value_one)[0] == 1);
1043 std::memcpy(&word0x,
"0x", 2);
1045 uint16_t two_first_bytes{};
1046 std::memcpy(&two_first_bytes, input.data(), 2);
1047 if (is_little_endian) {
1048 two_first_bytes |= 0x2000;
1050 two_first_bytes |= 0x020;
1052 return two_first_bytes == word0x;
1059constexpr bool is_digit(
char x)
noexcept {
return (x >=
'0') & (x <=
'9'); }
1061constexpr char to_lower(
char x)
noexcept {
return (x | 0x20); }
1063constexpr bool is_alpha(
char x)
noexcept {
1068 return input.size() >= 2 &&
1069 (
is_alpha(input[0]) && ((input[1] ==
':') || (input[1] ==
'|'))) &&
1070 ((input.size() == 2) || (input[2] ==
'/' || input[2] ==
'\\' ||
1071 input[2] ==
'?' || input[2] ==
'#'));
1075 std::string_view input)
noexcept {
1076 return input.size() >= 2 && (
is_alpha(input[0]) && (input[1] ==
':'));
1080 std::string_view prefix) {
1083 return view.size() >= prefix.size() &&
1084 std::equal(prefix.begin(), prefix.end(), view.begin());
1103#define ADA_LOGGING 0
1112template <
typename T>
1115 std::cout << t << std::endl;
1123template <
typename T,
typename... Args>
1125 [[maybe_unused]] Args... args) {
1136template <
typename T,
typename... Args>
1138 [[maybe_unused]] Args... args) {
1140 std::cout <<
"ADA_LOG: " << t;
1149template <
typename T>
1152 std::cout <<
"ADA_LOG: " << t << std::endl;
1160#define ada_log(...) \
1162 ada::log(__VA_ARGS__); \
1176#ifndef ADA_ENCODING_TYPE_H
1177#define ADA_ENCODING_TYPE_H
1209#ifndef ADA_HELPERS_H
1210#define ADA_HELPERS_H
1344#ifndef ADA_URL_BASE_H
1345#define ADA_URL_BASE_H
1352#ifndef ADA_URL_COMPONENTS_H
1353#define ADA_URL_COMPONENTS_H
1357#include <string_view>
1369struct url_components {
1370 constexpr static uint32_t
omitted = uint32_t(-1);
1489constexpr uint16_t get_special_port(std::string_view
scheme)
noexcept;
1507#include <string_view>
1574 [[nodiscard]] virtual std::
string get_origin() const noexcept = 0;
1589 [[nodiscard]] inline uint16_t get_special_port() const noexcept;
1609 virtual
size_t parse_port(std::string_view view,
1610 bool check_trailing_content) noexcept = 0;
1613 return this->parse_port(view,
false);
1622 virtual inline void clear_pathname() = 0;
1625 virtual inline void clear_search() = 0;
1628 [[nodiscard]]
virtual inline bool has_hash() const noexcept = 0;
1631 [[nodiscard]] virtual inline
bool has_search() const noexcept = 0;
1640#include <string_view>
1656template <
typename out_iter>
1657void encode_json(std::string_view view, out_iter out);
1673 std::string_view& input)
noexcept;
1720 size_t pos)
noexcept;
1726bool overlaps(std::string_view input1,
const std::string& input2)
noexcept;
1735 size_t pos2)
noexcept {
1736#if ADA_DEVELOPMENT_CHECKS
1738 std::cerr <<
"Negative-length substring: [" << pos1 <<
" to " << pos2 <<
")"
1743 return std::string_view(input.data() + pos1, pos2 - pos1);
1759 const bool is_special, std::string_view& view)
noexcept;
1773template <
class url_type>
1775 url_type&
url)
noexcept;
1782find_authority_delimiter_special(std::string_view view)
noexcept;
1789find_authority_delimiter(std::string_view view)
noexcept;
1794template <
typename T,
typename... Args>
1795inline void inner_concat(std::string& buffer, T t) {
1802template <
typename T,
typename... Args>
1803inline void inner_concat(std::string& buffer, T t, Args... args) {
1805 return inner_concat(buffer, args...);
1813template <
typename... Args>
1814std::string concat(Args... args) {
1816 inner_concat(answer, args...);
1824inline int leading_zeroes(uint32_t input_num)
noexcept {
1825#if ADA_REGULAR_VISUAL_STUDIO
1826 unsigned long leading_zero(0);
1827 unsigned long in(input_num);
1828 return _BitScanReverse(&leading_zero, in) ? int(31 - leading_zero) : 32;
1830 return __builtin_clz(input_num);
1840inline int fast_digit_count(uint32_t x)
noexcept {
1841 auto int_log2 = [](uint32_t z) ->
int {
1842 return 31 - ada::helpers::leading_zeroes(z | 1);
1848 const static uint64_t table[] = {
1849 4294967296, 8589934582, 8589934582, 8589934582, 12884901788,
1850 12884901788, 12884901788, 17179868184, 17179868184, 17179868184,
1851 21474826480, 21474826480, 21474826480, 21474826480, 25769703776,
1852 25769703776, 25769703776, 30063771072, 30063771072, 30063771072,
1853 34349738368, 34349738368, 34349738368, 34349738368, 38554705664,
1854 38554705664, 38554705664, 41949672960, 41949672960, 41949672960,
1855 42949672960, 42949672960};
1856 return int((x + table[int_log2(x)]) >> 32);
1871#include <string_view>
1894#ifndef TL_EXPECTED_HPP
1895#define TL_EXPECTED_HPP
1897#define TL_EXPECTED_VERSION_MAJOR 1
1898#define TL_EXPECTED_VERSION_MINOR 1
1899#define TL_EXPECTED_VERSION_PATCH 0
1902#include <functional>
1903#include <type_traits>
1906#if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
1907#define TL_EXPECTED_EXCEPTIONS_ENABLED
1910#if (defined(_MSC_VER) && _MSC_VER == 1900)
1911#define TL_EXPECTED_MSVC2015
1912#define TL_EXPECTED_MSVC2015_CONSTEXPR
1914#define TL_EXPECTED_MSVC2015_CONSTEXPR constexpr
1917#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
1918 !defined(__clang__))
1919#define TL_EXPECTED_GCC49
1922#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \
1923 !defined(__clang__))
1924#define TL_EXPECTED_GCC54
1927#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \
1928 !defined(__clang__))
1929#define TL_EXPECTED_GCC55
1932#if !defined(TL_ASSERT)
1934#if (__cplusplus > 201103L) && !defined(TL_EXPECTED_GCC49)
1936#define TL_ASSERT(x) assert(x)
1942#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
1943 !defined(__clang__))
1946#define TL_EXPECTED_NO_CONSTRR
1948#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
1949 std::has_trivial_copy_constructor<T>
1950#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
1951 std::has_trivial_copy_assign<T>
1954#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \
1955 std::is_trivially_destructible<T>
1959#elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__))
1960#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
1961#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
1965struct is_trivially_copy_constructible
1966 : std::is_trivially_copy_constructible<T> {};
1967#ifdef _GLIBCXX_VECTOR
1968template <
class T,
class A>
1969struct is_trivially_copy_constructible<std::vector<T, A>> : std::false_type {};
1975#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
1976 tl::detail::is_trivially_copy_constructible<T>
1977#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
1978 std::is_trivially_copy_assignable<T>
1979#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \
1980 std::is_trivially_destructible<T>
1982#define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
1983 std::is_trivially_copy_constructible<T>
1984#define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
1985 std::is_trivially_copy_assignable<T>
1986#define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \
1987 std::is_trivially_destructible<T>
1990#if __cplusplus > 201103L
1991#define TL_EXPECTED_CXX14
1994#ifdef TL_EXPECTED_GCC49
1995#define TL_EXPECTED_GCC49_CONSTEXPR
1997#define TL_EXPECTED_GCC49_CONSTEXPR constexpr
2000#if (__cplusplus == 201103L || defined(TL_EXPECTED_MSVC2015) || \
2001 defined(TL_EXPECTED_GCC49))
2002#define TL_EXPECTED_11_CONSTEXPR
2004#define TL_EXPECTED_11_CONSTEXPR constexpr
2008template <
class T,
class E>
2011#ifndef TL_MONOSTATE_INPLACE_MUTEX
2012#define TL_MONOSTATE_INPLACE_MUTEX
2024 static_assert(!std::is_same<E, void>::value,
"E must not be void");
2031 template <
class... Args,
typename std::enable_if<std::is_constructible<
2032 E, Args &&...>::value>::type * =
nullptr>
2034 : m_val(std::forward<Args>(args)...) {}
2036 class U,
class... Args,
2037 typename std::enable_if<std::is_constructible<
2038 E, std::initializer_list<U> &, Args &&...>::value>::type * =
nullptr>
2039 constexpr explicit unexpected(std::initializer_list<U> l, Args &&...args)
2040 : m_val(l, std::forward<Args>(args)...) {}
2042 constexpr const E &
value() const & {
return m_val; }
2045 constexpr const E &&
value() const && {
return std::move(m_val); }
2051#ifdef __cpp_deduction_guides
2053unexpected(E) -> unexpected<E>;
2092template <
typename E>
2094#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
2095 throw std::forward<E>(e);
2101 __builtin_unreachable();
2106#ifndef TL_TRAITS_MUTEX
2107#define TL_TRAITS_MUTEX
2115template <
bool E,
class T =
void>
2117template <
bool B,
class T,
class F>
2125template <
class B,
class... Bs>
2127 : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
2129#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
2130#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
2136#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
2138struct is_pointer_to_non_const_member_func : std::false_type {};
2139template <
class T,
class Ret,
class... Args>
2140struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)>
2141 : std::true_type {};
2142template <
class T,
class Ret,
class... Args>
2143struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &>
2144 : std::true_type {};
2145template <
class T,
class Ret,
class... Args>
2146struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &&>
2147 : std::true_type {};
2148template <
class T,
class Ret,
class... Args>
2149struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile>
2150 : std::true_type {};
2151template <
class T,
class Ret,
class... Args>
2152struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile &>
2153 : std::true_type {};
2154template <
class T,
class Ret,
class... Args>
2155struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile &&>
2156 : std::true_type {};
2159struct is_const_or_const_ref : std::false_type {};
2161struct is_const_or_const_ref<T const &> : std::true_type {};
2163struct is_const_or_const_ref<T const> : std::true_type {};
2169 typename Fn,
typename... Args,
2170#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
2171 typename =
enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value &&
2172 is_const_or_const_ref<Args...>::value)>,
2174 typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
int = 0>
2175constexpr auto invoke(Fn &&f, Args &&...args)
noexcept(
2176 noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
2177 ->
decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
2178 return std::mem_fn(f)(std::forward<Args>(args)...);
2181template <
typename Fn,
typename... Args,
2182 typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
2183constexpr auto invoke(Fn &&f, Args &&...args)
noexcept(
2184 noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
2185 ->
decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
2186 return std::forward<Fn>(f)(std::forward<Args>(args)...);
2190template <
class F,
class,
class... Us>
2193template <
class F,
class... Us>
2196 decltype(
detail::
invoke(std::declval<F>(), std::declval<Us>()...), void()),
2199 decltype(
detail::invoke(std::declval<F>(), std::declval<Us>()...));
2202template <
class F,
class... Us>
2205template <
class F,
class... Us>
2208#if defined(_MSC_VER) && _MSC_VER <= 1900
2210template <
class T,
class U = T>
2213template <
class T,
class U = T>
2214struct is_nothrow_swappable : std::true_type {};
2224template <
class T, std::
size_t N>
2229template <
class,
class>
2231template <class T, class U,
2232 class = decltype(
swap(std::declval<T &>(), std::declval<U &>()))>
2234 std::declval<U &>())));
2236template <class, class>
2238template <class T, class U>
2239std::is_same<decltype(
swap(std::declval<T &>(), std::declval<U &>())),
tag>
2244 : std::integral_constant<
bool,
2245 std::is_nothrow_move_constructible<T>::value &&
2246 std::is_nothrow_move_assignable<T>::value> {};
2248template <
class T, std::
size_t N>
2251template <
class T,
class U>
2253 : std::integral_constant<bool, noexcept(can_swap<T, U>(0))> {};
2256template <
class T,
class U = T>
2258 : std::integral_constant<
2260 decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
2261 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
2262 (std::is_move_assignable<T>::value &&
2263 std::is_move_constructible<T>::value))> {};
2265template <
class T, std::
size_t N>
2267 : std::integral_constant<
2269 decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
2270 (!decltype(detail::swap_adl_tests::uses_std<T[N], T[N]>(
2272 is_swappable<T, T>::value)> {};
2274template <
class T,
class U = T>
2276 : std::integral_constant<
2278 is_swappable<T, U>::value &&
2279 ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
2280 detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
2281 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
2282 detail::swap_adl_tests::is_adl_swap_noexcept<T, U>::value))> {};
2289template <
class T,
class E>
2294template <
class T,
class E,
class U>
2296 std::is_constructible<T, U &&>::value &&
2297 !std::is_same<detail::decay_t<U>,
in_place_t>::value &&
2301template <
class T,
class E,
class U,
class G,
class UR,
class GR>
2303 std::is_constructible<T, UR>::value &&
2304 std::is_constructible<E, GR>::value &&
2305 !std::is_constructible<T, expected<U, G> &>::value &&
2306 !std::is_constructible<T, expected<U, G> &&>::value &&
2307 !std::is_constructible<T, const expected<U, G> &>::value &&
2308 !std::is_constructible<T, const expected<U, G> &&>::value &&
2309 !std::is_convertible<expected<U, G> &, T>::value &&
2310 !std::is_convertible<expected<U, G> &&, T>::value &&
2311 !std::is_convertible<const expected<U, G> &, T>::value &&
2312 !std::is_convertible<const expected<U, G> &&, T>::value>;
2314template <
class T,
class U>
2343template <class T, class E, bool = std::is_trivially_destructible<T>::value,
2344 bool = std::is_trivially_destructible<E>::value>
2349 template <
class... Args,
2355 template <
class U,
class... Args,
2357 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2361 template <
class... Args,
2367 template <
class U,
class... Args,
2369 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2371 std::initializer_list<U> il,
2392template <
class T,
class E>
2397 template <
class... Args,
2403 template <
class U,
class... Args,
2405 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2409 template <
class... Args,
2415 template <
class U,
class... Args,
2417 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2419 std::initializer_list<U> il,
2433template <
class T,
class E>
2439 template <
class... Args,
2445 template <
class U,
class... Args,
2447 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2451 template <
class... Args,
2457 template <
class U,
class... Args,
2459 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2461 std::initializer_list<U> il,
2480template <
class T,
class E>
2485 template <
class... Args,
2491 template <
class U,
class... Args,
2493 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2497 template <
class... Args,
2503 template <
class U,
class... Args,
2505 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2507 std::initializer_list<U> il,
2538 template <
class... Args,
2544 template <
class U,
class... Args,
2546 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2548 std::initializer_list<U> il,
2569 template <
class... Args,
2575 template <
class U,
class... Args,
2577 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
2579 std::initializer_list<U> il,
2598template <
class T,
class E>
2602 template <
class... Args>
2604 new (std::addressof(this->
m_val)) T(std::forward<Args>(args)...);
2608 template <
class Rhs>
2610 new (std::addressof(this->
m_val)) T(std::forward<Rhs>(rhs).
get());
2614 template <
class... Args>
2621#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
2629 template <
class U = T,
2633 if (!this->m_has_val && rhs.m_has_val) {
2634 geterr().~unexpected<E>();
2635 construct(rhs.get());
2643 template <
class U = T,
2644 detail::enable_if_t<!std::is_nothrow_copy_constructible<U>::value &&
2645 std::is_nothrow_move_constructible<U>::value>
2647 void assign(
const expected_operations_base &rhs)
noexcept {
2648 if (!this->m_has_val && rhs.m_has_val) {
2650 geterr().~unexpected<E>();
2651 construct(std::move(tmp));
2662 template <
class U = T,
2663 detail::enable_if_t<!std::is_nothrow_copy_constructible<U>::value &&
2664 !std::is_nothrow_move_constructible<U>::value>
2666 void assign(
const expected_operations_base &rhs) {
2667 if (!this->m_has_val && rhs.m_has_val) {
2668 auto tmp = std::move(geterr());
2669 geterr().~unexpected<E>();
2671#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
2673 construct(rhs.get());
2675 geterr() = std::move(tmp);
2679 construct(rhs.get());
2687 template <
class U = T,
2688 detail::enable_if_t<std::is_nothrow_move_constructible<U>::value>
2690 void assign(expected_operations_base &&rhs)
noexcept {
2691 if (!this->m_has_val && rhs.m_has_val) {
2692 geterr().~unexpected<E>();
2693 construct(std::move(rhs).get());
2695 assign_common(std::move(rhs));
2699 template <
class U = T,
2700 detail::enable_if_t<!std::is_nothrow_move_constructible<U>::value>
2702 void assign(expected_operations_base &&rhs) {
2703 if (!this->m_has_val && rhs.m_has_val) {
2704 auto tmp = std::move(geterr());
2705 geterr().~unexpected<E>();
2706#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
2708 construct(std::move(rhs).get());
2710 geterr() = std::move(tmp);
2714 construct(std::move(rhs).get());
2717 assign_common(std::move(rhs));
2725 if (!this->
m_has_val && rhs.m_has_val) {
2726 geterr().~unexpected<E>();
2734 if (!this->
m_has_val && rhs.m_has_val) {
2735 geterr().~unexpected<E>();
2745 template <
class Rhs>
2748 if (rhs.m_has_val) {
2749 get() = std::forward<Rhs>(rhs).get();
2755 if (!rhs.m_has_val) {
2756 geterr() = std::forward<Rhs>(rhs).geterr();
2764 constexpr const T &
get() const & {
return this->
m_val; }
2766#ifndef TL_EXPECTED_NO_CONSTRR
2767 constexpr const T &&
get() const && {
return std::move(this->
m_val); }
2777#ifndef TL_EXPECTED_NO_CONSTRR
2792 template <
class... Args>
2799 template <
class Rhs>
2804 template <
class... Args>
2811 template <
class Rhs>
2814 if (rhs.m_has_val) {
2815 geterr().~unexpected<E>();
2818 geterr() = std::forward<Rhs>(rhs).geterr();
2821 if (!rhs.m_has_val) {
2836#ifndef TL_EXPECTED_NO_CONSTRR
2849template <
class T,
class E,
2858template <
class T,
class E>
2866 this->construct_with(rhs);
2868 this->construct_error(rhs.geterr());
2882#ifndef TL_EXPECTED_GCC49
2883template <
class T,
class E,
2886 std::is_trivially_move_constructible<E>::value>
2891template <
class T,
class E,
bool = false>
2894template <
class T,
class E>
2902 std::is_nothrow_move_constructible<T>::value)
2904 if (rhs.has_value()) {
2905 this->construct_with(std::move(rhs));
2907 this->construct_error(std::move(rhs.geterr()));
2929template <
class T,
class E>
2950#ifndef TL_EXPECTED_GCC49
2955 std::is_trivially_move_constructible<T>,
2956 std::is_trivially_move_assignable<T>>>::value &&
2957 std::is_trivially_destructible<E>::value &&
2958 std::is_trivially_move_constructible<E>::value &&
2959 std::is_trivially_move_assignable<E>::value>
2964template <
class T,
class E,
bool = false>
2968template <
class T,
class E>
2983 &&rhs)
noexcept(std::is_nothrow_move_constructible<T>::value &&
2984 std::is_nothrow_move_assignable<T>::value) {
2985 this->
assign(std::move(rhs));
2992template <
class T,
class E,
2993 bool EnableCopy = (is_copy_constructible_or_void<T>::value &&
2994 std::is_copy_constructible<E>::value),
2995 bool EnableMove = (is_move_constructible_or_void<T>::value &&
2996 std::is_move_constructible<E>::value)>
3007template <class T, class E>
3018template <class T, class E>
3029template <class T, class E>
3043template <class T, class E,
3045 std::is_copy_constructible<E>::value &&
3047 std::is_copy_assignable<E>::value),
3049 std::is_move_constructible<E>::value &&
3051 std::is_move_assignable<E>::value)>
3063template <class T, class E>
3075template <class T, class E>
3087template <class T, class E>
3108template <
class T,
class E,
3110 std::is_default_constructible<T>::value || std::is_void<T>::value>
3126template <
class T,
class E>
3147 virtual const char *
what() const noexcept
override {
3148 return "Bad expected access";
3151 const E &
error() const & {
return m_val; }
3153 const E &&
error() const && {
return std::move(m_val); }
3154 E &&
error() && {
return std::move(m_val); }
3167template <
class T,
class E>
3172 static_assert(!std::is_reference<T>::value,
"T must not be a reference");
3173 static_assert(!std::is_same<T, std::remove_cv<in_place_t>::type>
::value,
3174 "T must not be in_place_t");
3175 static_assert(!std::is_same<T, std::remove_cv<unexpect_t>::type>
::value,
3176 "T must not be unexpect_t");
3178 !std::is_same<T, typename std::remove_cv<unexpected<E>>::type>
::value,
3179 "T must not be unexpected<E>");
3180 static_assert(!std::is_reference<E>::value,
"E must not be a reference");
3182 T *valptr() {
return std::addressof(this->
m_val); }
3183 const T *valptr()
const {
return std::addressof(this->
m_val); }
3189 template <
class U = T,
3196 template <
class U = T,
3198 constexpr const U &val()
const {
3211#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
3212 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
3215 return and_then_impl(*
this, std::forward<F>(f));
3219 return and_then_impl(std::move(*
this), std::forward<F>(f));
3222 constexpr auto and_then(F &&f)
const & {
3223 return and_then_impl(*
this, std::forward<F>(f));
3226#ifndef TL_EXPECTED_NO_CONSTRR
3228 constexpr auto and_then(F &&f)
const && {
3236 std::declval<expected &>(), std::forward<F>(f))) {
3237 return and_then_impl(*
this, std::forward<F>(f));
3241 std::declval<expected &&>(), std::forward<F>(f))) {
3242 return and_then_impl(std::move(*
this), std::forward<F>(f));
3245 constexpr auto and_then(F &&f)
const & ->
decltype(and_then_impl(
3246 std::declval<expected const &>(), std::forward<F>(f))) {
3247 return and_then_impl(*
this, std::forward<F>(f));
3250#ifndef TL_EXPECTED_NO_CONSTRR
3252 constexpr auto and_then(F &&f)
const && ->
decltype(and_then_impl(
3253 std::declval<expected const &&>(), std::forward<F>(f))) {
3254 return and_then_impl(std::move(*
this), std::forward<F>(f));
3259#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
3260 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
3263 return expected_map_impl(*
this, std::forward<F>(f));
3267 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3270 constexpr auto map(F &&f)
const & {
3274 constexpr auto map(F &&f)
const && {
3280 std::declval<expected &>(), std::declval<F &&>()))
3282 return expected_map_impl(*
this, std::forward<F>(f));
3286 std::declval<F &&>()))
3288 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3291 constexpr decltype(expected_map_impl(std::declval<const expected &>(),
3292 std::declval<F &&>()))
3294 return expected_map_impl(*
this, std::forward<F>(f));
3297#ifndef TL_EXPECTED_NO_CONSTRR
3299 constexpr decltype(expected_map_impl(std::declval<const expected &&>(),
3300 std::declval<F &&>()))
3302 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3307#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
3308 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
3311 return expected_map_impl(*
this, std::forward<F>(f));
3315 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3318 constexpr auto transform(F &&f)
const & {
3322 constexpr auto transform(F &&f)
const && {
3328 std::declval<expected &>(), std::declval<F &&>()))
3330 return expected_map_impl(*
this, std::forward<F>(f));
3334 std::declval<F &&>()))
3336 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3339 constexpr decltype(expected_map_impl(std::declval<const expected &>(),
3340 std::declval<F &&>()))
3342 return expected_map_impl(*
this, std::forward<F>(f));
3345#ifndef TL_EXPECTED_NO_CONSTRR
3347 constexpr decltype(expected_map_impl(std::declval<const expected &&>(),
3348 std::declval<F &&>()))
3350 return expected_map_impl(std::move(*
this), std::forward<F>(f));
3355#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
3356 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
3359 return map_error_impl(*
this, std::forward<F>(f));
3363 return map_error_impl(std::move(*
this), std::forward<F>(f));
3366 constexpr auto map_error(F &&f)
const & {
3370 constexpr auto map_error(F &&f)
const && {
3376 std::declval<F &&>()))
3378 return map_error_impl(*
this, std::forward<F>(f));
3382 std::declval<F &&>()))
3384 return map_error_impl(std::move(*
this), std::forward<F>(f));
3387 constexpr decltype(map_error_impl(std::declval<const expected &>(),
3388 std::declval<F &&>()))
3390 return map_error_impl(*
this, std::forward<F>(f));
3393#ifndef TL_EXPECTED_NO_CONSTRR
3395 constexpr decltype(map_error_impl(std::declval<const expected &&>(),
3396 std::declval<F &&>()))
3398 return map_error_impl(std::move(*
this), std::forward<F>(f));
3402#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
3403 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
3406 return map_error_impl(*
this, std::forward<F>(f));
3410 return map_error_impl(std::move(*
this), std::forward<F>(f));
3413 constexpr auto transform_error(F &&f)
const & {
3417 constexpr auto transform_error(F &&f)
const && {
3423 std::declval<F &&>()))
3425 return map_error_impl(*
this, std::forward<F>(f));
3429 std::declval<F &&>()))
3431 return map_error_impl(std::move(*
this), std::forward<F>(f));
3434 constexpr decltype(map_error_impl(std::declval<const expected &>(),
3435 std::declval<F &&>()))
3437 return map_error_impl(*
this, std::forward<F>(f));
3440#ifndef TL_EXPECTED_NO_CONSTRR
3442 constexpr decltype(map_error_impl(std::declval<const expected &&>(),
3443 std::declval<F &&>()))
3445 return map_error_impl(std::move(*
this), std::forward<F>(f));
3451 return or_else_impl(*
this, std::forward<F>(f));
3456 return or_else_impl(std::move(*
this), std::forward<F>(f));
3461 return or_else_impl(*
this, std::forward<F>(f));
3464#ifndef TL_EXPECTED_NO_CONSTRR
3467 return or_else_impl(std::move(*
this), std::forward<F>(f));
3476 template <
class... Args,
3480 : impl_base(
in_place, std::forward<Args>(args)...),
3481 ctor_base(
detail::default_constructor_tag{}) {}
3483 template <
class U,
class... Args,
3485 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
3487 : impl_base(
in_place, il, std::forward<Args>(args)...),
3488 ctor_base(
detail::default_constructor_tag{}) {}
3490 template <
class G = E,
3497 ctor_base(
detail::default_constructor_tag{}) {}
3506 ctor_base(
detail::default_constructor_tag{}) {}
3513 std::is_nothrow_constructible<E, G &&>::value)
3515 ctor_base(
detail::default_constructor_tag{}) {}
3522 std::is_nothrow_constructible<E, G &&>::value)
3524 ctor_base(
detail::default_constructor_tag{}) {}
3526 template <
class... Args,
3530 : impl_base(
unexpect, std::forward<Args>(args)...),
3531 ctor_base(
detail::default_constructor_tag{}) {}
3533 template <
class U,
class... Args,
3535 E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
3538 : impl_base(
unexpect, il, std::forward<Args>(args)...),
3539 ctor_base(
detail::default_constructor_tag{}) {}
3541 template <
class U,
class G,
3543 std::is_convertible<G const &, E>::value)> * =
3548 : ctor_base(
detail::default_constructor_tag{}) {
3550 this->construct(*rhs);
3552 this->construct_error(rhs.error());
3556 template <
class U,
class G,
3558 std::is_convertible<G const &, E>::value)> * =
3563 : ctor_base(
detail::default_constructor_tag{}) {
3565 this->construct(*rhs);
3567 this->construct_error(rhs.error());
3574 std::is_convertible<G &&, E>::value)> * =
nullptr,
3577 : ctor_base(
detail::default_constructor_tag{}) {
3578 if (rhs.has_value()) {
3579 this->construct(std::move(*rhs));
3581 this->construct_error(std::move(rhs.error()));
3588 std::is_convertible<G &&, E>::value)> * =
nullptr,
3591 : ctor_base(
detail::default_constructor_tag{}) {
3592 if (rhs.has_value()) {
3593 this->construct(std::move(*rhs));
3595 this->construct_error(std::move(rhs.error()));
3614 class U = T,
class G = T,
3621 std::is_same<T, detail::decay_t<U>>>::value &&
3622 std::is_constructible<T, U>::value &&
3623 std::is_assignable<G &, U>::value &&
3624 std::is_nothrow_move_constructible<E>::value)> * =
nullptr>
3627 val() = std::forward<U>(v);
3629 err().~unexpected<E>();
3630 ::new (valptr()) T(std::forward<U>(v));
3638 class U = T,
class G = T,
3645 std::is_same<T, detail::decay_t<U>>>::value &&
3646 std::is_constructible<T, U>::value &&
3647 std::is_assignable<G &, U>::value &&
3648 std::is_nothrow_move_constructible<E>::value)> * =
nullptr>
3651 val() = std::forward<U>(v);
3653 auto tmp = std::move(err());
3654 err().~unexpected<E>();
3656#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
3658 ::new (valptr()) T(std::forward<U>(v));
3661 err() = std::move(tmp);
3665 ::new (valptr()) T(std::forward<U>(v));
3673 template <
class G = E,
3675 std::is_assignable<G &, G>::value> * =
nullptr>
3688 template <
class G = E,
3690 std::is_move_assignable<G>::value> * =
nullptr>
3693 err() = std::move(rhs);
3704 T, Args &&...>::value> * =
nullptr>
3709 err().~unexpected<E>();
3712 ::new (valptr()) T(std::forward<Args>(args)...);
3716 T, Args &&...>::value> * =
nullptr>
3720 ::new (valptr()) T(std::forward<Args>(args)...);
3722 auto tmp = std::move(err());
3723 err().~unexpected<E>();
3725#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
3727 ::new (valptr()) T(std::forward<Args>(args)...);
3730 err() = std::move(tmp);
3734 ::new (valptr()) T(std::forward<Args>(args)...);
3740 template <
class U,
class... Args,
3742 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
3743 void emplace(std::initializer_list<U> il, Args &&...args) {
3745 T t(il, std::forward<Args>(args)...);
3746 val() = std::move(t);
3748 err().~unexpected<E>();
3749 ::new (valptr()) T(il, std::forward<Args>(args)...);
3754 template <
class U,
class... Args,
3756 T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
3757 void emplace(std::initializer_list<U> il, Args &&...args) {
3759 T t(il, std::forward<Args>(args)...);
3760 val() = std::move(t);
3762 auto tmp = std::move(err());
3763 err().~unexpected<E>();
3765#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
3767 ::new (valptr()) T(il, std::forward<Args>(args)...);
3770 err() = std::move(tmp);
3774 ::new (valptr()) T(il, std::forward<Args>(args)...);
3781 using t_is_void = std::true_type;
3782 using t_is_not_void = std::false_type;
3783 using t_is_nothrow_move_constructible = std::true_type;
3784 using move_constructing_t_can_throw = std::false_type;
3785 using e_is_nothrow_move_constructible = std::true_type;
3786 using move_constructing_e_can_throw = std::false_type;
3788 void swap_where_both_have_value(
expected & , t_is_void)
noexcept {
3792 void swap_where_both_have_value(expected &rhs, t_is_not_void) {
3794 swap(val(), rhs.val());
3797 void swap_where_only_one_has_value(expected &rhs, t_is_void)
noexcept(
3798 std::is_nothrow_move_constructible<E>::value) {
3799 ::new (errptr()) unexpected_type(std::move(rhs.err()));
3800 rhs.err().~unexpected_type();
3801 std::swap(this->m_has_val, rhs.m_has_val);
3804 void swap_where_only_one_has_value(expected &rhs, t_is_not_void) {
3805 swap_where_only_one_has_value_and_t_is_not_void(
3806 rhs,
typename std::is_nothrow_move_constructible<T>::type{},
3807 typename std::is_nothrow_move_constructible<E>::type{});
3810 void swap_where_only_one_has_value_and_t_is_not_void(
3811 expected &rhs, t_is_nothrow_move_constructible,
3812 e_is_nothrow_move_constructible)
noexcept {
3813 auto temp = std::move(val());
3815 ::new (errptr()) unexpected_type(std::move(rhs.err()));
3816 rhs.err().~unexpected_type();
3817 ::new (rhs.valptr()) T(std::move(temp));
3818 std::swap(this->m_has_val, rhs.m_has_val);
3821 void swap_where_only_one_has_value_and_t_is_not_void(
3822 expected &rhs, t_is_nothrow_move_constructible,
3823 move_constructing_e_can_throw) {
3824 auto temp = std::move(val());
3826#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
3828 ::new (errptr()) unexpected_type(std::move(rhs.err()));
3829 rhs.err().~unexpected_type();
3830 ::new (rhs.valptr()) T(std::move(temp));
3831 std::swap(this->m_has_val, rhs.m_has_val);
3833 val() = std::move(temp);
3837 ::new (errptr()) unexpected_type(std::move(rhs.err()));
3838 rhs.err().~unexpected_type();
3839 ::new (rhs.valptr()) T(std::move(temp));
3840 std::swap(this->m_has_val, rhs.m_has_val);
3844 void swap_where_only_one_has_value_and_t_is_not_void(
3845 expected &rhs, move_constructing_t_can_throw,
3846 e_is_nothrow_move_constructible) {
3847 auto temp = std::move(rhs.err());
3848 rhs.err().~unexpected_type();
3849#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
3851 ::new (rhs.valptr()) T(std::move(val()));
3853 ::new (errptr()) unexpected_type(std::move(temp));
3854 std::swap(this->m_has_val, rhs.m_has_val);
3856 rhs.err() = std::move(temp);
3860 ::new (rhs.valptr()) T(std::move(val()));
3862 ::new (errptr()) unexpected_type(std::move(temp));
3863 std::swap(this->m_has_val, rhs.m_has_val);
3868 template <
class OT = T,
class OE = E>
3869 detail::enable_if_t<detail::is_swappable<OT>::value &&
3870 detail::is_swappable<OE>::value &&
3871 (std::is_nothrow_move_constructible<OT>::value ||
3872 std::is_nothrow_move_constructible<OE>::value)>
3873 swap(
expected &rhs)
noexcept(std::is_nothrow_move_constructible<T>::value &&
3875 std::is_nothrow_move_constructible<E>::value &&
3878 swap_where_both_have_value(rhs,
typename std::is_void<T>::type{});
3879 }
else if (!
has_value() && rhs.has_value()) {
3882 swap_where_only_one_has_value(rhs,
typename std::is_void<T>::type{});
3885 swap(err(), rhs.err());
3898 template <
class U = T,
3904 template <
class U = T,
3910 template <
class U = T,
3914 return std::move(val());
3916 template <
class U = T,
3920 return std::move(val());
3923 constexpr bool has_value() const noexcept {
return this->m_has_val; }
3924 constexpr explicit operator bool() const noexcept {
return this->m_has_val; }
3926 template <
class U = T,
3933 template <
class U = T,
3940 template <
class U = T,
3945 return std::move(val());
3947 template <
class U = T,
3952 return std::move(val());
3957 return err().value();
3961 return err().value();
3965 return std::move(err().
value());
3969 return std::move(err().
value());
3974 static_assert(std::is_copy_constructible<T>::value &&
3975 std::is_convertible<U &&, T>::value,
3976 "T must be copy-constructible and convertible to from U&&");
3977 return bool(*
this) ? **this :
static_cast<T
>(std::forward<U>(v));
3981 static_assert(std::is_move_constructible<T>::value &&
3982 std::is_convertible<U &&, T>::value,
3983 "T must be move-constructible and convertible to from U&&");
3984 return bool(*
this) ? std::move(**
this) :
static_cast<T
>(std::forward<U>(v));
3993template <
class Exp,
class Ret>
3996#ifdef TL_EXPECTED_CXX14
3997template <
class Exp,
class F,
4000 *std::declval<Exp>()))>
4004 return exp.has_value()
4006 : Ret(
unexpect, std::forward<Exp>(exp).error());
4009template <
class Exp,
class F,
4012constexpr auto and_then_impl(Exp &&exp, F &&f) {
4016 : Ret(
unexpect, std::forward<Exp>(exp).error());
4021template <
class Exp,
class F,
4023 *std::declval<Exp>())),
4028 return exp.has_value()
4030 : Ret(
unexpect, std::forward<Exp>(exp).error());
4033template <
class Exp,
class F,
4040 : Ret(
unexpect, std::forward<Exp>(exp).error());
4044#ifdef TL_EXPECTED_CXX14
4045template <
class Exp,
class F,
4048 *std::declval<Exp>())),
4050constexpr auto expected_map_impl(Exp &&exp, F &&f) {
4051 using result = ret_t<Exp, detail::decay_t<Ret>>;
4053 *std::forward<Exp>(exp)))
4054 : result(
unexpect, std::forward<Exp>(exp).error());
4057template <
class Exp,
class F,
4058 detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * =
nullptr,
4059 class Ret =
decltype(detail::invoke(std::declval<F>(),
4060 *std::declval<Exp>())),
4061 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4062auto expected_map_impl(Exp &&exp, F &&f) {
4063 using result = expected<void, err_t<Exp>>;
4064 if (exp.has_value()) {
4065 detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
4069 return result(unexpect, std::forward<Exp>(exp).error());
4072template <
class Exp,
class F,
4073 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4074 class Ret =
decltype(detail::invoke(std::declval<F>())),
4075 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4077 using result = ret_t<Exp, detail::decay_t<Ret>>;
4082template <
class Exp,
class F,
4083 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4084 class Ret =
decltype(detail::invoke(std::declval<F>())),
4085 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4087 using result = expected<void, err_t<Exp>>;
4088 if (exp.has_value()) {
4089 detail::invoke(std::forward<F>(f));
4093 return result(unexpect, std::forward<Exp>(exp).error());
4096template <
class Exp,
class F,
4097 detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * =
nullptr,
4098 class Ret =
decltype(detail::invoke(std::declval<F>(),
4099 *std::declval<Exp>())),
4100 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4106 return exp.has_value() ? result(
detail::invoke(std::forward<F>(f),
4107 *std::forward<Exp>(exp)))
4108 : result(
unexpect, std::forward<Exp>(exp).error());
4111template <
class Exp,
class F,
4114 *std::declval<Exp>())),
4118 if (exp.has_value()) {
4126template <
class Exp,
class F,
4131constexpr auto expected_map_impl(Exp &&exp, F &&f)
4132 -> ret_t<Exp, detail::decay_t<Ret>> {
4133 using result = ret_t<Exp, detail::decay_t<Ret>>;
4136 : result(
unexpect, std::forward<Exp>(exp).error());
4139template <
class Exp,
class F,
4140 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4141 class Ret =
decltype(detail::invoke(std::declval<F>())),
4142 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4144auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> {
4145 if (exp.has_value()) {
4146 detail::invoke(std::forward<F>(f));
4150 return unexpected<err_t<Exp>>(std::forward<Exp>(exp).error());
4154#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
4155 !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
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>, detail::decay_t<Ret>>;
4164 ?
result(*std::forward<Exp>(exp))
4166 std::forward<Exp>(exp).error()));
4168template <
class Exp,
class F,
4169 detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * =
nullptr,
4170 class Ret =
decltype(detail::invoke(std::declval<F>(),
4171 std::declval<Exp>().error())),
4172 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4174 using result = expected<exp_t<Exp>, monostate>;
4175 if (exp.has_value()) {
4176 return result(*std::forward<Exp>(exp));
4179 detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
4180 return result(unexpect, monostate{});
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>, detail::decay_t<Ret>>;
4192 std::forward<Exp>(exp).error()));
4194template <
class Exp,
class F,
4195 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4196 class Ret =
decltype(detail::invoke(std::declval<F>(),
4197 std::declval<Exp>().error())),
4198 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4200 using result = expected<exp_t<Exp>, monostate>;
4201 if (exp.has_value()) {
4205 detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
4206 return result(unexpect, monostate{});
4209template <
class Exp,
class F,
4210 detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * =
nullptr,
4211 class Ret =
decltype(detail::invoke(std::declval<F>(),
4212 std::declval<Exp>().error())),
4213 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4218 return exp.has_value()
4219 ? result(*std::forward<Exp>(exp))
4221 std::forward<Exp>(exp).error()));
4224template <
class Exp,
class F,
4227 std::declval<Exp>().error())),
4231 if (exp.has_value()) {
4232 return result(*std::forward<Exp>(exp));
4235 detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
4239template <
class Exp,
class F,
4242 std::declval<Exp>().error())),
4244constexpr auto map_error_impl(Exp &&exp, F &&f)
4248 return exp.has_value()
4251 std::forward<Exp>(exp).error()));
4254template <
class Exp,
class F,
4255 detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * =
nullptr,
4256 class Ret =
decltype(detail::invoke(std::declval<F>(),
4257 std::declval<Exp>().error())),
4258 detail::enable_if_t<std::is_void<Ret>::value> * =
nullptr>
4259auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
4260 using result = expected<exp_t<Exp>, monostate>;
4261 if (exp.has_value()) {
4265 detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
4266 return result(unexpect, monostate{});
4270#ifdef TL_EXPECTED_CXX14
4271template <
class Exp,
class F,
4272 class Ret =
decltype(detail::invoke(std::declval<F>(),
4273 std::declval<Exp>().error())),
4274 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4276 static_assert(detail::is_expected<Ret>::value,
"F must return an expected");
4277 return exp.has_value() ? std::forward<Exp>(exp)
4278 : detail::
invoke(std::forward<F>(f),
4279 std::forward<Exp>(exp).error());
4282template <
class Exp,
class F,
4283 class Ret =
decltype(detail::invoke(std::declval<F>(),
4284 std::declval<Exp>().error())),
4285 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()),
4290 std::forward<Exp>(exp));
4293template <
class Exp,
class F,
4294 class Ret =
decltype(detail::invoke(std::declval<F>(),
4295 std::declval<Exp>().error())),
4296 detail::enable_if_t<!std::is_void<Ret>::value> * =
nullptr>
4299 return exp.has_value() ? std::forward<Exp>(exp)
4301 std::forward<Exp>(exp).error());
4304template <
class Exp,
class F,
4306 std::declval<Exp>().error())),
4309 return exp.has_value() ? std::forward<Exp>(exp)
4311 std::forward<Exp>(exp).error()),
4312 std::forward<Exp>(exp));
4317template <
class T,
class E,
class U,
class F>
4324template <
class T,
class E,
class U,
class F>
4331template <
class E,
class F>
4338template <
class E,
class F>
4346template <
class T,
class E,
class U>
4350template <
class T,
class E,
class U>
4354template <
class T,
class E,
class U>
4358template <
class T,
class E,
class U>
4363template <
class T,
class E>
4367template <
class T,
class E>
4371template <
class T,
class E>
4375template <
class T,
class E>
4380template <
class T,
class E,
4381 detail::enable_if_t<(std::is_void<T>::value ||
4382 std::is_move_constructible<T>::value) &&
4383 detail::is_swappable<T>::value &&
4384 std::is_move_constructible<E>::value &&
4385 detail::is_swappable<E>::value> * =
nullptr>
4399struct url_aggregator;
4407namespace ada::parser {
4414template <
typename result_type = ada::url_aggregator>
4415result_type
parse_url(std::string_view user_input,
4416 const result_type* base_url =
nullptr);
4418extern template url_aggregator parse_url<url_aggregator>(
4419 std::string_view user_input,
const url_aggregator* base_url);
4420extern template url parse_url<url>(std::string_view user_input,
4421 const url* base_url);
4423template <
typename result_type = ada::url_aggregator,
bool store_values = true>
4425 const result_type* base_url =
nullptr);
4427extern template url_aggregator parse_url_impl<url_aggregator>(
4428 std::string_view user_input,
const url_aggregator* base_url);
4429extern template url parse_url_impl<url>(std::string_view user_input,
4430 const url* base_url);
4440#ifndef ADA_SCHEME_INL_H
4441#define ADA_SCHEME_INL_H
4453constexpr std::string_view is_special_list[] = {
"http",
" ",
"https",
"ws",
4454 "ftp",
"wss",
"file",
" "};
4456constexpr uint16_t special_ports[] = {80, 0, 443, 80, 21, 443, 0, 0};
4484 if (scheme.empty()) {
4487 int hash_value = (2 * scheme.size() + (
unsigned)(scheme[0])) & 7;
4488 const std::string_view target = details::is_special_list[hash_value];
4489 return (target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1));
4491constexpr uint16_t get_special_port(std::string_view scheme)
noexcept {
4492 if (scheme.empty()) {
4495 int hash_value = (2 * scheme.size() + (
unsigned)(scheme[0])) & 7;
4496 const std::string_view target = details::is_special_list[hash_value];
4497 if ((target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1))) {
4498 return details::special_ports[hash_value];
4504 return details::special_ports[int(type)];
4507 if (scheme.empty()) {
4510 int hash_value = (2 * scheme.size() + (
unsigned)(scheme[0])) & 7;
4511 const std::string_view target = details::is_special_list[hash_value];
4512 if ((target[0] == scheme[0]) && (target.substr(1) == scheme.substr(1))) {
4528#ifndef ADA_SERIALIZERS_H
4529#define ADA_SERIALIZERS_H
4545void find_longest_sequence_of_ipv6_pieces(
4546 const std::array<uint16_t, 8>& address,
size_t& compress,
4547 size_t& compress_length)
noexcept;
4555std::string ipv6(
const std::array<uint16_t, 8>& address)
noexcept;
4563std::string ipv4(uint64_t address)
noexcept;
4574#ifndef ADA_UNICODE_H
4575#define ADA_UNICODE_H
4632bool to_ascii(std::optional<std::string>& out, std::string_view plain,
4633 size_t first_percent);
4643 std::string_view user_input)
noexcept;
4658 const char* input,
size_t length)
noexcept;
4668contains_forbidden_domain_code_point_or_upper(
const char* input,
4669 size_t length)
noexcept;
4718 std::string_view input)
noexcept;
4726 std::string_view input)
noexcept;
4750std::string percent_decode(std::string_view input,
size_t first_percent);
4757std::string percent_encode(std::string_view input,
4758 const uint8_t character_set[]);
4765std::string percent_encode(std::string_view input,
4766 const uint8_t character_set[],
size_t index);
4775template <
bool append>
4776bool percent_encode(std::string_view input,
const uint8_t character_set[],
4784 const uint8_t character_set[]);
4790constexpr bool to_lower_ascii(
char* input,
size_t length)
noexcept;
4800#ifndef ADA_URL_BASE_INL_H
4801#define ADA_URL_BASE_INL_H
4808#ifndef ADA_URL_AGGREGATOR_H
4809#define ADA_URL_AGGREGATOR_H
4812#include <string_view>
4825struct url_aggregator : url_base {
4860 [[nodiscard]] inline std::string_view
get_href() const noexcept
5001 [[nodiscard]] inline
bool has_hash() const noexcept override;
5020 std::
string buffer{};
5030 inline
void add_authority_slashes_if_needed() noexcept;
5036 inline
void reserve(uint32_t capacity);
5039 std::string_view view,
bool check_trailing_content) noexcept override;
5042 return this->parse_port(view,
false);
5051 [[nodiscard]]
bool parse_ipv4(std::string_view input,
bool in_place);
5057 [[nodiscard]]
bool parse_ipv6(std::string_view input);
5063 [[nodiscard]]
bool parse_opaque_host(std::string_view input);
5071 [[nodiscard]]
inline bool cannot_have_credentials_or_port()
const;
5073 template <
bool overr
ide_hostname = false>
5074 bool set_host_or_hostname(std::string_view input);
5078 inline void update_base_authority(std::string_view base_buffer,
5079 const ada::url_components &base);
5080 inline void update_unencoded_base_hash(std::string_view input);
5081 inline void update_base_hostname(std::string_view input);
5082 inline void update_base_search(std::string_view input);
5083 inline void update_base_search(std::string_view input,
5084 const uint8_t *query_percent_encode_set);
5085 inline void update_base_pathname(std::string_view input);
5086 inline void update_base_username(std::string_view input);
5087 inline void append_base_username(std::string_view input);
5088 inline void update_base_password(std::string_view input);
5089 inline void append_base_password(std::string_view input);
5090 inline void update_base_port(uint32_t input);
5091 inline void append_base_pathname(std::string_view input);
5092 [[nodiscard]]
inline uint32_t retrieve_base_port()
const;
5093 inline void clear_hostname();
5094 inline void clear_password();
5095 inline void clear_pathname()
override;
5096 [[nodiscard]]
inline bool has_dash_dot() const noexcept;
5097 void delete_dash_dot();
5098 inline
void consume_prepared_path(std::string_view input);
5099 template <
bool has_state_override = false>
5101 std::string_view input);
5103 std::string_view input);
5104 [[nodiscard]] inline
bool has_authority() const noexcept;
5105 inline
void set_protocol_as_file();
5106 inline
void set_scheme(std::string_view new_scheme) noexcept;
5111 inline
void set_scheme_from_view_with_colon(
5112 std::string_view new_scheme_with_colon) noexcept;
5113 inline
void copy_scheme(const url_aggregator &u) noexcept;
5117inline std::ostream &operator<<(std::ostream &out, const ada::url &u);
5127#ifndef ADA_CHECKERS_H
5128#define ADA_CHECKERS_H
5131#include <string_view>
5149constexpr char to_lower(
char x)
noexcept;
5158constexpr bool is_alpha(
char x)
noexcept;
5167inline bool has_hex_prefix_unsafe(std::string_view input);
5172inline bool has_hex_prefix(std::string_view input);
5179constexpr bool is_digit(
char x)
noexcept;
5193inline constexpr bool is_windows_drive_letter(std::string_view input)
noexcept;
5200inline constexpr bool is_normalized_windows_drive_letter(
5201 std::string_view input)
noexcept;
5208 std::string_view prefix);
5226 std::string_view input)
noexcept;
5240 std::string_view input)
noexcept;
5259#include <string_view>
5276struct url : url_base {
5289 std::string username{};
5296 std::string password{};
5302 std::optional<std::string> host{};
5309 std::optional<uint16_t> port{};
5322 std::optional<std::string> query{};
5330 std::optional<std::string> hash{};
5524 [[nodiscard]] inline
bool has_hash() const noexcept override;
5541 inline
void update_unencoded_base_hash(std::string_view input);
5542 inline
void update_base_hostname(std::string_view input);
5543 inline
void update_base_search(std::string_view input);
5544 inline
void update_base_search(std::string_view input,
5545 const uint8_t query_percent_encode_set[]);
5546 inline
void update_base_search(std::optional<std::
string> input);
5547 inline
void update_base_pathname(std::string_view input);
5548 inline
void update_base_username(std::string_view input);
5549 inline
void update_base_password(std::string_view input);
5550 inline
void update_base_port(std::optional<uint16_t> input);
5557 template <
bool override_hostname = false>
5558 bool set_host_or_hostname(std::string_view input);
5564 [[nodiscard]]
bool parse_ipv4(std::string_view input);
5570 [[nodiscard]]
bool parse_ipv6(std::string_view input);
5576 [[nodiscard]]
bool parse_opaque_host(std::string_view input);
5587 std::
string non_special_scheme{};
5593 [[nodiscard]]
inline bool cannot_have_credentials_or_port()
const;
5596 std::string_view view,
bool check_trailing_content)
noexcept override;
5599 return this->parse_port(view,
false);
5606 inline void copy_scheme(
const ada::url &u);
5618 template <
bool has_state_overr
ide = false>
5621 inline void clear_pathname()
override;
5622 inline void clear_search()
override;
5623 inline void set_protocol_as_file();
5642 inline void set_scheme(std::string &&new_scheme)
noexcept;
5648 inline void copy_scheme(
ada::url &&u)
noexcept;
5652inline std::ostream &
operator<<(std::ostream &out,
const ada::url &u);
5660#if ADA_REGULAR_VISUAL_STUDIO
5670[[nodiscard]]
inline uint16_t url_base::get_special_port() const noexcept {
5675url_base::scheme_default_port() const noexcept {
5676 return scheme::get_special_port(type);
5688#ifndef ADA_URL_INL_H
5689#define ADA_URL_INL_H
5694#if ADA_REGULAR_VISUAL_STUDIO
5700 return !username.empty() || !password.empty();
5703 return port.has_value();
5705[[nodiscard]]
inline bool url::cannot_have_credentials_or_port()
const {
5706 return !host.has_value() || host.value().empty() ||
5707 type == ada::scheme::type::FILE;
5709[[nodiscard]]
inline bool url::has_empty_hostname()
const noexcept {
5710 if (!host.has_value()) {
5713 return host.value().empty();
5715[[nodiscard]]
inline bool url::has_hostname()
const noexcept {
5716 return host.has_value();
5718inline std::ostream &operator<<(std::ostream &out,
const ada::url &u) {
5722[[nodiscard]]
size_t url::get_pathname_length()
const noexcept {
5728 url_components out{};
5731 out.protocol_end = uint32_t(get_protocol().size());
5734 size_t running_index = out.protocol_end;
5736 if (host.has_value()) {
5738 out.host_start = out.protocol_end + 2;
5740 if (has_credentials()) {
5741 out.username_end = uint32_t(out.host_start + username.size());
5743 out.host_start += uint32_t(username.size());
5745 if (!password.empty()) {
5746 out.host_start += uint32_t(password.size() + 1);
5749 out.host_end = uint32_t(out.host_start + host.value().size());
5751 out.username_end = out.host_start;
5754 out.host_end = uint32_t(out.host_start + host.value().size()) - 1;
5757 running_index = out.host_end + 1;
5761 out.host_start = out.protocol_end;
5762 out.host_end = out.host_start;
5764 if (!has_opaque_path && checkers::begins_with(path,
"//")) {
5768 running_index = out.protocol_end + 2;
5770 running_index = out.protocol_end;
5774 if (port.has_value()) {
5776 running_index += helpers::fast_digit_count(*port) + 1;
5779 out.pathname_start = uint32_t(running_index);
5781 running_index += path.size();
5783 if (query.has_value()) {
5784 out.search_start = uint32_t(running_index);
5785 running_index += get_search().size();
5786 if (get_search().empty()) {
5791 if (hash.has_value()) {
5792 out.hash_start = uint32_t(running_index);
5798inline void url::update_base_hostname(std::string_view input) { host = input; }
5800inline void url::update_unencoded_base_hash(std::string_view input) {
5802 hash = unicode::percent_encode(input,
5806inline void url::update_base_search(std::string_view input,
5807 const uint8_t query_percent_encode_set[]) {
5808 query = ada::unicode::percent_encode(input, query_percent_encode_set);
5811inline void url::update_base_search(std::optional<std::string> input) {
5815inline void url::update_base_pathname(
const std::string_view input) {
5819inline void url::update_base_username(
const std::string_view input) {
5823inline void url::update_base_password(
const std::string_view input) {
5827inline void url::update_base_port(std::optional<uint16_t> input) {
5831inline void url::clear_pathname() { path.clear(); }
5833inline void url::clear_search() { query = std::nullopt; }
5835[[nodiscard]]
inline bool url::has_hash()
const noexcept {
5836 return hash.has_value();
5839[[nodiscard]]
inline bool url::has_search()
const noexcept {
5840 return query.has_value();
5843inline void url::set_protocol_as_file() { type = ada::scheme::type::FILE; }
5845inline void url::set_scheme(std::string &&new_scheme)
noexcept {
5848 if (!is_special()) {
5849 non_special_scheme = std::move(new_scheme);
5853inline void url::copy_scheme(
ada::url &&u)
noexcept {
5854 non_special_scheme = u.non_special_scheme;
5858inline void url::copy_scheme(
const ada::url &u) {
5859 non_special_scheme = u.non_special_scheme;
5864 std::string output = get_protocol();
5866 if (host.has_value()) {
5868 if (has_credentials()) {
5870 if (!password.empty()) {
5871 output +=
":" + get_password();
5875 output += host.value();
5876 if (port.has_value()) {
5877 output +=
":" + get_port();
5879 }
else if (!has_opaque_path && checkers::begins_with(path,
"//")) {
5886 if (query.has_value()) {
5887 output +=
"?" + query.value();
5889 if (hash.has_value()) {
5890 output +=
"#" + hash.value();
5896 bool check_trailing_content)
noexcept {
5897 ada_log(
"parse_port('", view,
"') ", view.size());
5898 if (!view.empty() && view[0] ==
'-') {
5899 ada_log(
"parse_port: view[0] == '0' && view.size() > 1");
5903 uint16_t parsed_port{};
5904 auto r = std::from_chars(view.data(), view.data() + view.size(), parsed_port);
5905 if (r.ec == std::errc::result_out_of_range) {
5906 ada_log(
"parse_port: r.ec == std::errc::result_out_of_range");
5910 ada_log(
"parse_port: ", parsed_port);
5911 const size_t consumed = size_t(r.ptr - view.data());
5912 ada_log(
"parse_port: consumed ", consumed);
5913 if (check_trailing_content) {
5915 (consumed == view.size() || view[consumed] ==
'/' ||
5916 view[consumed] ==
'?' || (is_special() && view[consumed] ==
'\\'));
5918 ada_log(
"parse_port: is_valid = ", is_valid);
5921 auto default_port = scheme_default_port();
5922 bool is_port_valid = (default_port == 0 && parsed_port == 0) ||
5923 (default_port != parsed_port);
5924 port = (r.ec == std::errc() && is_port_valid)
5925 ? std::optional<uint16_t>(parsed_port)
5940#ifndef ADA_URL_AGGREGATOR_INL_H
5941#define ADA_URL_AGGREGATOR_INL_H
5948#ifndef ADA_UNICODE_INL_H
5949#define ADA_UNICODE_INL_H
5962 const uint8_t character_set[]) {
5963 return std::distance(
5965 std::find_if(input.begin(), input.end(), [character_set](
const char c) {
5966 return character_sets::bit_at(character_set, c);
5975#include <string_view>
5979inline void url_aggregator::update_base_authority(
5980 std::string_view base_buffer,
const ada::url_components &base) {
5981 std::string_view input = base_buffer.substr(
5982 base.protocol_end,
base.host_start -
base.protocol_end);
5983 ada_log(
"url_aggregator::update_base_authority ", input);
5985 bool input_starts_with_dash = checkers::begins_with(input,
"//");
5986 uint32_t diff = components.host_start - components.protocol_end;
5988 buffer.erase(components.protocol_end,
5989 components.host_start - components.protocol_end);
5990 components.username_end = components.protocol_end;
5992 if (input_starts_with_dash) {
5993 input.remove_prefix(2);
5995 buffer.insert(components.protocol_end,
"//");
5996 components.username_end += 2;
5999 size_t password_delimiter = input.find(
':');
6003 if (password_delimiter != std::string_view::npos) {
6005 std::string_view username = input.substr(0, password_delimiter);
6006 std::string_view password = input.substr(password_delimiter + 1);
6008 buffer.insert(components.protocol_end + diff, username);
6009 diff += uint32_t(username.size());
6010 buffer.insert(components.protocol_end + diff,
":");
6011 components.username_end = components.protocol_end + diff;
6012 buffer.insert(components.protocol_end + diff + 1, password);
6013 diff += uint32_t(password.size()) + 1;
6014 }
else if (!input.empty()) {
6016 buffer.insert(components.protocol_end + diff, input);
6017 components.username_end =
6018 components.protocol_end + diff + uint32_t(input.size());
6019 diff += uint32_t(input.size());
6022 components.host_start += diff;
6024 if (buffer.size() >
base.host_start && buffer[
base.host_start] !=
'@') {
6025 buffer.insert(components.host_start,
"@");
6028 components.host_end += diff;
6029 components.pathname_start += diff;
6030 if (components.search_start != url_components::omitted) {
6031 components.search_start += diff;
6033 if (components.hash_start != url_components::omitted) {
6034 components.hash_start += diff;
6038inline void url_aggregator::update_unencoded_base_hash(std::string_view input) {
6039 ada_log(
"url_aggregator::update_unencoded_base_hash ", input,
" [",
6040 input.size(),
" bytes], buffer is '", buffer,
"' [", buffer.size(),
6041 " bytes] components.hash_start = ", components.hash_start);
6044 if (components.hash_start != url_components::omitted) {
6045 buffer.resize(components.hash_start);
6047 components.hash_start = uint32_t(buffer.size());
6049 bool encoding_required = unicode::percent_encode<true>(
6053 if (!encoding_required) {
6054 buffer.append(input);
6056 ada_log(
"url_aggregator::update_unencoded_base_hash final buffer is '",
6057 buffer,
"' [", buffer.size(),
" bytes]");
6062 uint32_t start, uint32_t end, std::string_view input) {
6063 uint32_t current_length = end - start;
6064 uint32_t input_size = uint32_t(input.size());
6065 uint32_t new_difference = input_size - current_length;
6067 if (current_length == 0) {
6068 buffer.insert(start, input);
6069 }
else if (input_size == current_length) {
6070 buffer.replace(start, input_size, input);
6071 }
else if (input_size < current_length) {
6072 buffer.erase(start, current_length - input_size);
6073 buffer.replace(start, input_size, input);
6075 buffer.replace(start, current_length, input.substr(0, current_length));
6076 buffer.insert(start + current_length, input.substr(current_length));
6079 return new_difference;
6082inline void url_aggregator::update_base_hostname(
const std::string_view input) {
6083 ada_log(
"url_aggregator::update_base_hostname ", input,
" [", input.size(),
6084 " bytes], buffer is '", buffer,
"' [", buffer.size(),
" bytes]");
6089 add_authority_slashes_if_needed();
6091 bool has_credentials = components.protocol_end + 2 < components.host_start;
6092 uint32_t new_difference =
6093 replace_and_resize(components.host_start, components.host_end, input);
6095 if (has_credentials) {
6096 buffer.insert(components.host_start,
"@");
6099 components.host_end += new_difference;
6100 components.pathname_start += new_difference;
6101 if (components.search_start != url_components::omitted) {
6102 components.search_start += new_difference;
6104 if (components.hash_start != url_components::omitted) {
6105 components.hash_start += new_difference;
6111url_aggregator::get_pathname_length() const noexcept {
6112 ada_log(
"url_aggregator::get_pathname_length");
6113 uint32_t ending_index = uint32_t(buffer.size());
6114 if (components.search_start != url_components::omitted) {
6115 ending_index = components.search_start;
6116 }
else if (components.hash_start != url_components::omitted) {
6117 ending_index = components.hash_start;
6119 return ending_index - components.pathname_start;
6124 return buffer.size() == components.pathname_start;
6127inline void url_aggregator::update_base_search(std::string_view input) {
6128 ada_log(
"url_aggregator::update_base_search ", input);
6131 if (input.empty()) {
6136 if (input[0] ==
'?') {
6137 input.remove_prefix(1);
6140 if (components.hash_start == url_components::omitted) {
6141 if (components.search_start == url_components::omitted) {
6142 components.search_start = uint32_t(buffer.size());
6145 buffer.resize(components.search_start + 1);
6148 buffer.append(input);
6150 if (components.search_start == url_components::omitted) {
6151 components.search_start = components.hash_start;
6153 buffer.erase(components.search_start,
6154 components.hash_start - components.search_start);
6155 components.hash_start = components.search_start;
6158 buffer.insert(components.search_start,
"?");
6159 buffer.insert(components.search_start + 1, input);
6160 components.hash_start += uint32_t(input.size() + 1);
6166inline void url_aggregator::update_base_search(
6167 std::string_view input,
const uint8_t query_percent_encode_set[]) {
6168 ada_log(
"url_aggregator::update_base_search ", input,
6169 " with encoding parameter ",
to_string(),
"\n", to_diagram());
6173 if (components.hash_start == url_components::omitted) {
6174 if (components.search_start == url_components::omitted) {
6175 components.search_start = uint32_t(buffer.size());
6178 buffer.resize(components.search_start + 1);
6181 bool encoding_required =
6182 unicode::percent_encode<true>(input, query_percent_encode_set, buffer);
6185 if (!encoding_required) {
6186 buffer.append(input);
6189 if (components.search_start == url_components::omitted) {
6190 components.search_start = components.hash_start;
6192 buffer.erase(components.search_start,
6193 components.hash_start - components.search_start);
6194 components.hash_start = components.search_start;
6197 buffer.insert(components.search_start,
"?");
6200 if (idx == input.size()) {
6201 buffer.insert(components.search_start + 1, input);
6202 components.hash_start += uint32_t(input.size() + 1);
6204 buffer.insert(components.search_start + 1, input, 0, idx);
6205 input.remove_prefix(idx);
6208 std::string encoded =
6209 ada::unicode::percent_encode(input, query_percent_encode_set);
6210 buffer.insert(components.search_start + idx + 1, encoded);
6211 components.hash_start +=
6212 uint32_t(encoded.size() + idx + 1);
6219inline void url_aggregator::update_base_pathname(
const std::string_view input) {
6220 ada_log(
"url_aggregator::update_base_pathname '", input,
"' [", input.size(),
6221 " bytes] \n", to_diagram());
6225 const bool begins_with_dashdash = checkers::begins_with(input,
"//");
6226 if (!begins_with_dashdash && has_dash_dot()) {
6227 ada_log(
"url_aggregator::update_base_pathname has /.: \n", to_diagram());
6232 if (begins_with_dashdash && !has_opaque_path && !has_authority() &&
6237 buffer.insert(components.pathname_start,
"/.");
6238 components.pathname_start += 2;
6241 uint32_t difference = replace_and_resize(
6242 components.pathname_start,
6243 components.pathname_start + get_pathname_length(), input);
6244 if (components.search_start != url_components::omitted) {
6245 components.search_start += difference;
6247 if (components.hash_start != url_components::omitted) {
6248 components.hash_start += difference;
6250 ada_log(
"url_aggregator::update_base_pathname end '", input,
"' [",
6251 input.size(),
" bytes] \n", to_diagram());
6255inline void url_aggregator::append_base_pathname(
const std::string_view input) {
6257 "\n", to_diagram());
6260#if ADA_DEVELOPMENT_CHECKS
6262 std::string path_expected(get_pathname());
6263 path_expected.append(input);
6265 uint32_t ending_index = uint32_t(buffer.size());
6266 if (components.search_start != url_components::omitted) {
6267 ending_index = components.search_start;
6268 }
else if (components.hash_start != url_components::omitted) {
6269 ending_index = components.hash_start;
6271 buffer.insert(ending_index, input);
6273 if (components.search_start != url_components::omitted) {
6274 components.search_start += uint32_t(input.size());
6276 if (components.hash_start != url_components::omitted) {
6277 components.hash_start += uint32_t(input.size());
6279#if ADA_DEVELOPMENT_CHECKS
6280 std::string path_after = std::string(get_pathname());
6282 path_expected, path_after,
6283 "append_base_pathname problem after inserting " + std::string(input));
6288inline void url_aggregator::update_base_username(
const std::string_view input) {
6289 ada_log(
"url_aggregator::update_base_username '", input,
"' ",
to_string(),
6290 "\n", to_diagram());
6294 add_authority_slashes_if_needed();
6296 bool has_password = has_non_empty_password();
6297 bool host_starts_with_at = buffer.size() > components.host_start &&
6298 buffer[components.host_start] ==
'@';
6299 uint32_t diff = replace_and_resize(components.protocol_end + 2,
6300 components.username_end, input);
6302 components.username_end += diff;
6303 components.host_start += diff;
6305 if (!input.empty() && !host_starts_with_at) {
6306 buffer.insert(components.host_start,
"@");
6308 }
else if (input.empty() && host_starts_with_at && !has_password) {
6311 buffer.erase(components.host_start, 1);
6315 components.host_end += diff;
6316 components.pathname_start += diff;
6317 if (components.search_start != url_components::omitted) {
6318 components.search_start += diff;
6320 if (components.hash_start != url_components::omitted) {
6321 components.hash_start += diff;
6326inline void url_aggregator::append_base_username(
const std::string_view input) {
6327 ada_log(
"url_aggregator::append_base_username ", input);
6330#if ADA_DEVELOPMENT_CHECKS
6332 std::string username_expected(get_username());
6333 username_expected.append(input);
6335 add_authority_slashes_if_needed();
6338 if (input.empty()) {
6342 uint32_t difference = uint32_t(input.size());
6343 buffer.insert(components.username_end, input);
6344 components.username_end += difference;
6345 components.host_start += difference;
6347 if (buffer[components.host_start] !=
'@' &&
6348 components.host_start != components.host_end) {
6349 buffer.insert(components.host_start,
"@");
6353 components.host_end += difference;
6354 components.pathname_start += difference;
6355 if (components.search_start != url_components::omitted) {
6356 components.search_start += difference;
6358 if (components.hash_start != url_components::omitted) {
6359 components.hash_start += difference;
6361#if ADA_DEVELOPMENT_CHECKS
6362 std::string username_after(get_username());
6364 username_expected, username_after,
6365 "append_base_username problem after inserting " + std::string(input));
6370inline void url_aggregator::clear_password() {
6371 ada_log(
"url_aggregator::clear_password ",
to_string(),
"\n", to_diagram());
6373 if (!has_password()) {
6377 uint32_t diff = components.host_start - components.username_end;
6378 buffer.erase(components.username_end, diff);
6379 components.host_start -= diff;
6380 components.host_end -= diff;
6381 components.pathname_start -= diff;
6382 if (components.search_start != url_components::omitted) {
6383 components.search_start -= diff;
6385 if (components.hash_start != url_components::omitted) {
6386 components.hash_start -= diff;
6390inline void url_aggregator::update_base_password(
const std::string_view input) {
6391 ada_log(
"url_aggregator::update_base_password ", input);
6395 add_authority_slashes_if_needed();
6398 if (input.empty()) {
6402 if (!has_non_empty_username()) {
6403 update_base_username(
"");
6409 bool password_exists = has_password();
6410 uint32_t difference = uint32_t(input.size());
6412 if (password_exists) {
6413 uint32_t current_length =
6414 components.host_start - components.username_end - 1;
6415 buffer.erase(components.username_end + 1, current_length);
6416 difference -= current_length;
6418 buffer.insert(components.username_end,
":");
6422 buffer.insert(components.username_end + 1, input);
6423 components.host_start += difference;
6428 if (buffer[components.host_start] !=
'@') {
6429 buffer.insert(components.host_start,
"@");
6433 components.host_end += difference;
6434 components.pathname_start += difference;
6435 if (components.search_start != url_components::omitted) {
6436 components.search_start += difference;
6438 if (components.hash_start != url_components::omitted) {
6439 components.hash_start += difference;
6444inline void url_aggregator::append_base_password(
const std::string_view input) {
6446 "\n", to_diagram());
6449#if ADA_DEVELOPMENT_CHECKS
6451 std::string password_expected = std::string(get_password());
6452 password_expected.append(input);
6454 add_authority_slashes_if_needed();
6457 if (input.empty()) {
6461 uint32_t difference = uint32_t(input.size());
6462 if (has_password()) {
6463 buffer.insert(components.host_start, input);
6466 buffer.insert(components.username_end,
":");
6467 buffer.insert(components.username_end + 1, input);
6469 components.host_start += difference;
6474 if (buffer[components.host_start] !=
'@') {
6475 buffer.insert(components.host_start,
"@");
6479 components.host_end += difference;
6480 components.pathname_start += difference;
6481 if (components.search_start != url_components::omitted) {
6482 components.search_start += difference;
6484 if (components.hash_start != url_components::omitted) {
6485 components.hash_start += difference;
6487#if ADA_DEVELOPMENT_CHECKS
6488 std::string password_after(get_password());
6490 password_expected, password_after,
6491 "append_base_password problem after inserting " + std::string(input));
6496inline void url_aggregator::update_base_port(uint32_t input) {
6497 ada_log(
"url_aggregator::update_base_port");
6499 if (input == url_components::omitted) {
6505 std::string value = helpers::concat(
":", std::to_string(input));
6506 uint32_t difference = uint32_t(value.size());
6508 if (components.port != url_components::omitted) {
6509 difference -= components.pathname_start - components.host_end;
6510 buffer.erase(components.host_end,
6511 components.pathname_start - components.host_end);
6514 buffer.insert(components.host_end, value);
6515 components.pathname_start += difference;
6516 if (components.search_start != url_components::omitted) {
6517 components.search_start += difference;
6519 if (components.hash_start != url_components::omitted) {
6520 components.hash_start += difference;
6522 components.port = input;
6526inline void url_aggregator::clear_port() {
6527 ada_log(
"url_aggregator::clear_port");
6529 if (components.port == url_components::omitted) {
6532 uint32_t length = components.pathname_start - components.host_end;
6533 buffer.erase(components.host_end, length);
6534 components.pathname_start -= length;
6535 if (components.search_start != url_components::omitted) {
6536 components.search_start -= length;
6538 if (components.hash_start != url_components::omitted) {
6539 components.hash_start -= length;
6541 components.port = url_components::omitted;
6545[[nodiscard]]
inline uint32_t url_aggregator::retrieve_base_port()
const {
6546 ada_log(
"url_aggregator::retrieve_base_port");
6547 return components.port;
6550inline void url_aggregator::clear_search() {
6551 ada_log(
"url_aggregator::clear_search");
6553 if (components.search_start == url_components::omitted) {
6557 if (components.hash_start == url_components::omitted) {
6558 buffer.resize(components.search_start);
6560 buffer.erase(components.search_start,
6561 components.hash_start - components.search_start);
6562 components.hash_start = components.search_start;
6565 components.search_start = url_components::omitted;
6567#if ADA_DEVELOPMENT_CHECKS
6569 "search should have been cleared on buffer=" + buffer +
6570 " with " + components.to_string() +
"\n" + to_diagram());
6575inline void url_aggregator::clear_hash() {
6576 ada_log(
"url_aggregator::clear_hash");
6578 if (components.hash_start == url_components::omitted) {
6581 buffer.resize(components.hash_start);
6582 components.hash_start = url_components::omitted;
6584#if ADA_DEVELOPMENT_CHECKS
6586 "hash should have been cleared on buffer=" + buffer +
6587 " with " + components.to_string() +
"\n" + to_diagram());
6592inline void url_aggregator::clear_pathname() {
6593 ada_log(
"url_aggregator::clear_pathname");
6595 uint32_t ending_index = uint32_t(buffer.size());
6596 if (components.search_start != url_components::omitted) {
6597 ending_index = components.search_start;
6598 }
else if (components.hash_start != url_components::omitted) {
6599 ending_index = components.hash_start;
6601 uint32_t pathname_length = ending_index - components.pathname_start;
6602 buffer.erase(components.pathname_start, pathname_length);
6603 uint32_t difference = pathname_length;
6604 if (components.pathname_start == components.host_end + 2 &&
6605 buffer[components.host_end] ==
'/' &&
6606 buffer[components.host_end + 1] ==
'.') {
6607 components.pathname_start -= 2;
6608 buffer.erase(components.host_end, 2);
6611 if (components.search_start != url_components::omitted) {
6612 components.search_start -= difference;
6614 if (components.hash_start != url_components::omitted) {
6615 components.hash_start -= difference;
6617 ada_log(
"url_aggregator::clear_pathname completed, running checks...");
6618#if ADA_DEVELOPMENT_CHECKS
6620 "pathname should have been cleared on buffer=" + buffer +
6621 " with " + components.to_string() +
"\n" + to_diagram());
6624 ada_log(
"url_aggregator::clear_pathname completed, running checks... ok");
6627inline void url_aggregator::clear_hostname() {
6628 ada_log(
"url_aggregator::clear_hostname");
6630 if (!has_authority()) {
6635 uint32_t hostname_length = components.host_end - components.host_start;
6636 uint32_t start = components.host_start;
6639 if (hostname_length > 0 && buffer[start] ==
'@') {
6643 buffer.erase(start, hostname_length);
6644 components.host_end = start;
6645 components.pathname_start -= hostname_length;
6646 if (components.search_start != url_components::omitted) {
6647 components.search_start -= hostname_length;
6649 if (components.hash_start != url_components::omitted) {
6650 components.hash_start -= hostname_length;
6652#if ADA_DEVELOPMENT_CHECKS
6654 "hostname should have been cleared on buffer=" + buffer +
6655 " with " + components.to_string() +
"\n" + to_diagram());
6659 "hostname should have been cleared on buffer=" + buffer +
6660 " with " + components.to_string() +
"\n" + to_diagram());
6664[[nodiscard]]
inline bool url_aggregator::has_hash() const noexcept {
6665 ada_log(
"url_aggregator::has_hash");
6666 return components.hash_start != url_components::omitted;
6669[[nodiscard]]
inline bool url_aggregator::has_search() const noexcept {
6670 ada_log(
"url_aggregator::has_search");
6671 return components.search_start != url_components::omitted;
6675 ada_log(
"url_aggregator::has_credentials");
6676 return has_non_empty_username() || has_non_empty_password();
6679inline bool url_aggregator::cannot_have_credentials_or_port()
const {
6680 ada_log(
"url_aggregator::cannot_have_credentials_or_port");
6681 return type == ada::scheme::type::FILE ||
6682 components.host_start == components.host_end;
6686url_aggregator::get_components() const noexcept {
6690[[nodiscard]]
inline bool ada::url_aggregator::has_authority() const noexcept {
6691 ada_log(
"url_aggregator::has_authority");
6694 return components.protocol_end + 2 <= components.host_start &&
6695 helpers::substring(buffer, components.protocol_end,
6696 components.protocol_end + 2) ==
"//";
6699inline void ada::url_aggregator::add_authority_slashes_if_needed() noexcept {
6700 ada_log(
"url_aggregator::add_authority_slashes_if_needed");
6705 if (has_authority()) {
6711 buffer.insert(components.protocol_end,
"//");
6712 components.username_end += 2;
6713 components.host_start += 2;
6714 components.host_end += 2;
6715 components.pathname_start += 2;
6716 if (components.search_start != url_components::omitted) {
6717 components.search_start += 2;
6719 if (components.hash_start != url_components::omitted) {
6720 components.hash_start += 2;
6725inline void ada::url_aggregator::reserve(uint32_t capacity) {
6726 buffer.reserve(capacity);
6729inline bool url_aggregator::has_non_empty_username() const noexcept {
6730 ada_log(
"url_aggregator::has_non_empty_username");
6731 return components.protocol_end + 2 < components.username_end;
6734inline bool url_aggregator::has_non_empty_password() const noexcept {
6735 ada_log(
"url_aggregator::has_non_empty_password");
6736 return components.host_start - components.username_end > 0;
6739inline bool url_aggregator::has_password() const noexcept {
6740 ada_log(
"url_aggregator::has_password");
6742 return components.host_start > components.username_end &&
6743 buffer[components.username_end] ==
':';
6746inline bool url_aggregator::has_empty_hostname() const noexcept {
6747 if (!has_hostname()) {
6750 if (components.host_start == components.host_end) {
6753 if (components.host_end > components.host_start + 1) {
6756 return components.username_end != components.host_start;
6759inline bool url_aggregator::has_hostname() const noexcept {
6760 return has_authority();
6763inline bool url_aggregator::has_port() const noexcept {
6764 ada_log(
"url_aggregator::has_port");
6767 return has_hostname() && components.pathname_start != components.host_end;
6770[[nodiscard]]
inline bool url_aggregator::has_dash_dot() const noexcept {
6774 ada_log(
"url_aggregator::has_dash_dot");
6775#if ADA_DEVELOPMENT_CHECKS
6779 if (components.pathname_start == components.host_end + 2) {
6781 buffer[components.host_end + 1] ==
'.') ||
6782 (buffer[components.host_end] ==
':' &&
6783 checkers::is_digit(buffer[components.host_end + 1])));
6785 if (components.pathname_start == components.host_end + 2 &&
6786 buffer[components.host_end] ==
'/' &&
6787 buffer[components.host_end + 1] ==
'.') {
6797 return components.pathname_start == components.host_end + 2 &&
6798 !has_opaque_path && buffer[components.host_end] ==
'/' &&
6799 buffer[components.host_end + 1] ==
'.';
6802[[nodiscard]]
inline std::string_view url_aggregator::get_href() const noexcept
6804 ada_log(
"url_aggregator::get_href");
6809 std::string_view view,
bool check_trailing_content)
noexcept {
6810 ada_log(
"url_aggregator::parse_port('", view,
"') ", view.size());
6811 if (!view.empty() && view[0] ==
'-') {
6812 ada_log(
"parse_port: view[0] == '0' && view.size() > 1");
6816 uint16_t parsed_port{};
6817 auto r = std::from_chars(view.data(), view.data() + view.size(), parsed_port);
6818 if (r.ec == std::errc::result_out_of_range) {
6819 ada_log(
"parse_port: r.ec == std::errc::result_out_of_range");
6823 ada_log(
"parse_port: ", parsed_port);
6824 const size_t consumed = size_t(r.ptr - view.data());
6825 ada_log(
"parse_port: consumed ", consumed);
6826 if (check_trailing_content) {
6828 (consumed == view.size() || view[consumed] ==
'/' ||
6829 view[consumed] ==
'?' || (is_special() && view[consumed] ==
'\\'));
6831 ada_log(
"parse_port: is_valid = ", is_valid);
6833 ada_log(
"parse_port", r.ec == std::errc());
6835 auto default_port = scheme_default_port();
6836 bool is_port_valid = (default_port == 0 && parsed_port == 0) ||
6837 (default_port != parsed_port);
6838 if (r.ec == std::errc() && is_port_valid) {
6839 update_base_port(parsed_port);
6847inline void url_aggregator::set_protocol_as_file() {
6848 ada_log(
"url_aggregator::set_protocol_as_file ");
6850 type = ada::scheme::type::FILE;
6853 uint32_t new_difference = 5 - components.protocol_end;
6855 if (buffer.empty()) {
6856 buffer.append(
"file:");
6858 buffer.erase(0, components.protocol_end);
6859 buffer.insert(0,
"file:");
6861 components.protocol_end = 5;
6864 components.username_end += new_difference;
6865 components.host_start += new_difference;
6866 components.host_end += new_difference;
6867 components.pathname_start += new_difference;
6868 if (components.search_start != url_components::omitted) {
6869 components.search_start += new_difference;
6871 if (components.hash_start != url_components::omitted) {
6872 components.hash_start += new_difference;
6877inline std::ostream &
operator<<(std::ostream &out,
6878 const ada::url_aggregator &u) {
6890#ifndef ADA_URL_SEARCH_PARAMS_H
6891#define ADA_URL_SEARCH_PARAMS_H
6895#include <string_view>
6906template <
typename T, url_search_params_iter_type Type>
6907struct url_search_params_iter;
6909typedef std::pair<std::string_view, std::string_view> key_value_view_pair;
6911using url_search_params_keys_iter =
6912 url_search_params_iter<std::string_view, url_search_params_iter_type::KEYS>;
6913using url_search_params_values_iter =
6914 url_search_params_iter<std::string_view,
6915 url_search_params_iter_type::VALUES>;
6916using url_search_params_entries_iter =
6917 url_search_params_iter<key_value_view_pair,
6918 url_search_params_iter_type::ENTRIES>;
6923struct url_search_params {
6938 [[nodiscard]]
inline size_t size() const noexcept;
6943 inline
void append(std::string_view key, std::string_view value);
6949 inline
void remove(std::string_view key, std::string_view value);
6954 inline std::optional<std::string_view>
get(std::string_view key);
6959 inline std::vector<std::
string>
get_all(std::string_view key);
6964 inline
bool has(std::string_view key) noexcept;
6965 inline
bool has(std::string_view key, std::string_view value) noexcept;
6970 inline
void set(std::string_view key, std::string_view value);
7012 inline auto
begin()
const {
return params.begin(); }
7013 inline auto end()
const {
return params.end(); }
7014 inline auto front()
const {
return params.front(); }
7015 inline auto back()
const {
return params.back(); }
7016 inline auto operator[](
size_t index)
const {
return params[index]; }
7024 void reset(std::string_view input);
7027 typedef std::pair<std::string, std::string> key_value_pair;
7028 std::vector<key_value_pair> params{};
7033 void initialize(std::string_view init);
7035 template <
typename T, url_search_params_iter_type Type>
7045template <
typename T, url_search_params_iter_type Type>
7080#ifndef ADA_URL_SEARCH_PARAMS_INL_H
7081#define ADA_URL_SEARCH_PARAMS_INL_H
7087#include <string_view>
7093template <
typename T, ada::url_search_params_iter_type Type>
7094url_search_params url_search_params_iter<T, Type>::EMPTY;
7096inline void url_search_params::reset(std::string_view input) {
7101inline void url_search_params::initialize(std::string_view input) {
7102 if (!input.empty() && input.front() ==
'?') {
7103 input.remove_prefix(1);
7106 auto process_key_value = [&](
const std::string_view current) {
7107 auto equal = current.find(
'=');
7109 if (equal == std::string_view::npos) {
7110 std::string name(current);
7111 std::replace(name.begin(), name.end(),
'+',
' ');
7112 params.emplace_back(unicode::percent_decode(name, name.find(
'%')),
"");
7114 std::string name(current.substr(0, equal));
7115 std::string value(current.substr(equal + 1));
7117 std::replace(name.begin(), name.end(),
'+',
' ');
7118 std::replace(value.begin(), value.end(),
'+',
' ');
7120 params.emplace_back(unicode::percent_decode(name, name.find(
'%')),
7121 unicode::percent_decode(value, value.find(
'%')));
7125 while (!input.empty()) {
7126 auto ampersand_index = input.find(
'&');
7128 if (ampersand_index == std::string_view::npos) {
7129 if (!input.empty()) {
7130 process_key_value(input);
7133 }
else if (ampersand_index != 0) {
7134 process_key_value(input.substr(0, ampersand_index));
7137 input.remove_prefix(ampersand_index + 1);
7142 const std::string_view value) {
7143 params.emplace_back(key, value);
7149 const std::string_view key) {
7150 auto entry = std::find_if(params.begin(), params.end(),
7151 [&key](
auto ¶m) { return param.first == key; });
7153 if (entry == params.end()) {
7154 return std::nullopt;
7157 return entry->second;
7161 const std::string_view key) {
7162 std::vector<std::string> out{};
7164 for (
auto ¶m : params) {
7165 if (param.first == key) {
7166 out.emplace_back(param.second);
7174 auto entry = std::find_if(params.begin(), params.end(),
7175 [&key](
auto ¶m) { return param.first == key; });
7176 return entry != params.end();
7180 std::string_view value)
noexcept {
7182 std::find_if(params.begin(), params.end(), [&key, &value](
auto ¶m) {
7183 return param.first == key && param.second == value;
7185 return entry != params.end();
7191 for (
size_t i = 0; i < params.size(); i++) {
7192 auto key = ada::unicode::percent_encode(params[i].first, character_set);
7193 auto value = ada::unicode::percent_encode(params[i].second, character_set);
7196 std::replace(key.begin(), key.end(),
' ',
'+');
7197 std::replace(value.begin(), value.end(),
' ',
'+');
7210 const std::string_view value) {
7211 const auto find = [&key](
auto ¶m) {
return param.first == key; };
7213 auto it = std::find_if(params.begin(), params.end(), find);
7215 if (it == params.end()) {
7216 params.emplace_back(key, value);
7219 params.erase(std::remove_if(std::next(it), params.end(), find),
7226 std::remove_if(params.begin(), params.end(),
7227 [&key](
auto ¶m) { return param.first == key; }),
7232 const std::string_view value) {
7233 params.erase(std::remove_if(params.begin(), params.end(),
7234 [&key, &value](
auto ¶m) {
7235 return param.first == key &&
7236 param.second == value;
7242 std::stable_sort(params.begin(), params.end(),
7243 [](
const key_value_pair &lhs,
const key_value_pair &rhs) {
7244 return lhs.first < rhs.first;
7266template <
typename T, url_search_params_iter_type Type>
7268 return pos < params.params.size();
7274 return std::nullopt;
7276 return params.params[pos++].first;
7282 return std::nullopt;
7284 return params.params[pos++].second;
7288inline std::optional<key_value_view_pair>
7291 return std::nullopt;
7293 return params.params[pos++];
7307#ifndef ADA_ADA_VERSION_H
7308#define ADA_ADA_VERSION_H
7310#define ADA_VERSION "2.9.2"
7330#ifndef ADA_IMPLEMENTATION_H
7331#define ADA_IMPLEMENTATION_H
7340template <
class result_type = ada::url_aggregator>
7352template <
class result_type = ada::url_aggregator>
7354 std::string_view input,
const result_type* base_url =
nullptr);
7357 const url* base_url);
7359 std::string_view input,
const url_aggregator* base_url);
7368 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) &&
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)
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)
void emplace(Args &&...args)
expected & operator=(U &&v)
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< ada::errors > 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_lifetime_bound
#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 uses_std(...)
std::false_type can_swap(...) noexcept(false)
static constexpr no_init_t no_init
typename std::remove_reference< T >::type remove_reference_t
invoke_result_impl< F, void, Us... > invoke_result
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
is_expected_impl< decay_t< T > > is_expected
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)
expected< Ret, err_t< Exp > > ret_t
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)
void swap(expected< T, E > &lhs, expected< T, E > &rhs) noexcept(noexcept(lhs.swap(rhs)))
url_aggregator & operator=(const url_aggregator &u)=default
url_aggregator & operator=(url_aggregator &&u) noexcept=default
bool has_non_empty_username() const noexcept
ada_really_inline const ada::url_components & get_components() const noexcept
void set_hash(std::string_view input)
void clear_search() override
bool has_hostname() const noexcept
std::string_view get_hostname() const noexcept ada_lifetime_bound
bool has_non_empty_password() const noexcept
friend void ada::helpers::strip_trailing_spaces_from_opaque_path(ada::url_aggregator &url) noexcept
ada_really_inline bool has_credentials() const noexcept
friend ada::url_aggregator ada::parser::parse_url(std::string_view, const ada::url_aggregator *)
std::string to_string() const override
std::string_view get_pathname() const noexcept ada_lifetime_bound
std::string_view get_hash() const noexcept ada_lifetime_bound
bool has_empty_hostname() const noexcept
bool has_search() const noexcept override
std::string to_diagram() const
bool set_protocol(std::string_view input)
std::string get_origin() const noexcept override
bool validate() const noexcept
bool has_password() const noexcept
std::string_view get_search() const noexcept ada_lifetime_bound
ada_really_inline uint32_t get_pathname_length() const noexcept
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 has_hash() const noexcept override
std::string_view get_protocol() const noexcept ada_lifetime_bound
std::string_view get_password() const noexcept ada_lifetime_bound
bool set_href(std::string_view input)
void set_search(std::string_view input)
std::string_view get_port() const noexcept ada_lifetime_bound
bool has_port() const noexcept
url_aggregator(url_aggregator &&u) noexcept=default
std::string_view get_href() const noexcept ada_lifetime_bound
friend ada::url_aggregator ada::parser::parse_url_impl(std::string_view, const ada::url_aggregator *)
bool set_host(std::string_view input)
std::string_view get_host() const noexcept ada_lifetime_bound
bool set_port(std::string_view input)
url_aggregator(const url_aggregator &u)=default
std::string_view get_username() const noexcept ada_lifetime_bound
bool set_username(std::string_view input)
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
friend struct url_search_params
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()
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
friend struct url_search_params_iter
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.
void set_hash(std::string_view input)
std::string get_search() const noexcept
bool set_hostname(std::string_view input)
bool set_host(std::string_view input)
ada_really_inline ada::url_components get_components() const noexcept
url(url &&u) noexcept=default
bool has_empty_hostname() const noexcept
bool has_port() const noexcept
ada_really_inline bool has_credentials() const noexcept
friend ada::url ada::parser::parse_url(std::string_view, const ada::url *)
bool set_password(std::string_view input)
std::string_view get_pathname() const noexcept
url & operator=(url &&u) noexcept=default
bool has_hash() const noexcept override
url & operator=(const url &u)=default
void set_search(std::string_view input)
ada_really_inline size_t get_pathname_length() const noexcept
bool set_href(std::string_view input)
ada_really_inline std::string get_href() const noexcept
bool has_hostname() const noexcept
bool set_username(std::string_view input)
url(const url &u)=default
std::string get_host() const noexcept
std::string get_hash() const noexcept
bool set_pathname(std::string_view input)
std::string get_origin() const noexcept override
friend void ada::helpers::strip_trailing_spaces_from_opaque_path(ada::url &url) noexcept
std::string get_hostname() const noexcept
friend ada::url ada::parser::parse_url_impl(std::string_view, const ada::url *)
const std::string & get_password() const noexcept
bool set_protocol(std::string_view input)
std::string get_port() const noexcept
const std::string & get_username() const noexcept
bool set_port(std::string_view input)
std::string to_string() const override
std::string get_protocol() const noexcept
bool has_valid_domain() const noexcept override
bool has_search() const noexcept 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