Files
freebsd/contrib/libc++/include/__string
T
Dimitry Andric e8948c9522 Merge clang, llvm, lld, lldb, compiler-rt and libc++ 5.0.0 release.
MFC r309126 (by emaste):

  Correct lld llvm-tblgen dependency file name

MFC r309169:

  Get rid of separate Subversion mergeinfo properties for llvm-dwarfdump
  and llvm-lto.  The mergeinfo confuses Subversion enormously, and these
  directories will just use the mergeinfo for llvm itself.

MFC r312765:

  Pull in r276136 from upstream llvm trunk (by Wei Mi):

    Use ValueOffsetPair to enhance value reuse during SCEV expansion.

    In D12090, the ExprValueMap was added to reuse existing value during
    SCEV expansion. However, const folding and sext/zext distribution can
    make the reuse still difficult.

    A simplified case is: suppose we know S1 expands to V1 in
    ExprValueMap, and
      S1 = S2 + C_a
      S3 = S2 + C_b
    where C_a and C_b are different SCEVConstants. Then we'd like to
    expand S3 as V1 - C_a + C_b instead of expanding S2 literally. It is
    helpful when S2 is a complex SCEV expr and S2 has no entry in
    ExprValueMap, which is usually caused by the fact that S3 is
    generated from S1 after const folding.

    In order to do that, we represent ExprValueMap as a mapping from SCEV
    to ValueOffsetPair. We will save both S1->{V1, 0} and S2->{V1, C_a}
    into the ExprValueMap when we create SCEV for V1. When S3 is
    expanded, it will first expand S2 to V1 - C_a because of S2->{V1,
    C_a} in the map, then expand S3 to V1 - C_a + C_b.

    Differential Revision: https://reviews.llvm.org/D21313

  This should fix assertion failures when building OpenCV >= 3.1.

  PR:		215649

MFC r312831:

  Revert r312765 for now, since it causes assertions when building
  lang/spidermonkey24.

  Reported by:	antoine
  PR:		215649

MFC r316511 (by jhb):

  Add an implementation of __ffssi2() derived from __ffsdi2().

  Newer versions of GCC include an __ffssi2() symbol in libgcc and the
  compiler can emit calls to it in generated code.  This is true for at
  least GCC 6.2 when compiling world for mips and mips64.

  Reviewed by:	jmallett, dim
  Sponsored by:	DARPA / AFRL
  Differential Revision:	https://reviews.freebsd.org/D10086

MFC r318601 (by adrian):

  [libcompiler-rt] add bswapdi2/bswapsi2

  This is required for mips gcc 6.3 userland to build/run.

  Reviewed by:	emaste, dim
  Approved by:	emaste
  Differential Revision:	https://reviews.freebsd.org/D10838

MFC r318884 (by emaste):

  lldb: map TRAP_CAP to a trace trap

  In the absense of a more specific handler for TRAP_CAP (generated by
  ENOTCAPABLE or ECAPMODE while in capability mode) treat it as a trace
  trap.

  Example usage (testing the bug in PR219173):

  % proccontrol -m trapcap lldb usr.bin/hexdump/obj/hexdump -- -Cv -s 1 /bin/ls
  ...
  (lldb) run
  Process 12980 launching
  Process 12980 launched: '.../usr.bin/hexdump/obj/hexdump' (x86_64)
  Process 12980 stopped
  * thread #1, stop reason = trace
      frame #0: 0x0000004b80c65f1a libc.so.7`__sys_lseek + 10
  ...

  In the future we should have LLDB control the trapcap procctl itself
  (as it does with ASLR), as well as report a specific stop reason.
  This change eliminates an assertion failure from LLDB for now.

MFC r319796:

  Remove a few unneeded files from libllvm, libclang and liblldb.

MFC r319885 (by emaste):

  lld: ELF: Fix ICF crash on absolute symbol relocations.

  If two sections contained relocations to absolute symbols with the same
  value we would crash when trying to access their sections. Add a check that
  both symbols point to sections before accessing their sections, and treat
  absolute symbols as equal if their values are equal.

  Obtained from:	LLD commit r292578

MFC r319918:

  Revert r319796 for now, it can cause undefined references when linking
  in some circumstances.

  Reported by:	Shawn Webb <[email protected]>

MFC r319957 (by emaste):

  lld: Add armelf emulation mode

  Obtained from:	LLD r305375

MFC r321369:

  Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
  5.0.0 (trunk r308421).  Upstream has branched for the 5.0.0 release,
  which should be in about a month.  Please report bugs and regressions,
  so we can get them into the release.

  Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
  support to build; see UPDATING for more information.

MFC r321420:

  Add a few more object files to liblldb, which should solve errors when
  linking the lldb executable in some cases.  In particular, when the
  -ffunction-sections -fdata-sections options are turned off, or
  ineffective.

  Reported by:	Shawn Webb, Mark Millard

MFC r321433:

  Cleanup stale Options.inc files from the previous libllvm build for
  clang 4.0.0.  Otherwise, these can get included before the two newly
  generated ones (which are different) for clang 5.0.0.

  Reported by:	Mark Millard

MFC r321439 (by bdrewery):

  Move llvm Options.inc hack from r321433 for NO_CLEAN to lib/clang/libllvm.

  The files are only ever generated to .OBJDIR, not to WORLDTMP (as a
  sysroot) and are only ever included from a compilation.  So using
  a beforebuild target here removes the file before the compilation
  tries to include it.

MFC r321664:

  Pull in r308891 from upstream llvm trunk (by Benjamin Kramer):

    [CodeGenPrepare] Cut off FindAllMemoryUses if there are too many uses.

    This avoids excessive compile time. The case I'm looking at is
    Function.cpp from an old version of LLVM that still had the giant
    memcmp string matcher in it. Before r308322 this compiled in about 2
    minutes, after it, clang takes infinite* time to compile it. With
    this patch we're at 5 min, which is still bad but this is a
    pathological case.

    The cut off at 20 uses was chosen by looking at other cut-offs in LLVM
    for user scanning. It's probably too high, but does the job and is
    very unlikely to regress anything.

    Fixes PR33900.

    * I'm impatient and aborted after 15 minutes, on the bug report it was
      killed after 2h.

  Pull in r308986 from upstream llvm trunk (by Simon Pilgrim):

    [X86][CGP] Reduce memcmp() expansion to 2 load pairs (PR33914)

    D35067/rL308322 attempted to support up to 4 load pairs for memcmp
    inlining which resulted in regressions for some optimized libc memcmp
    implementations (PR33914).

    Until we can match these more optimal cases, this patch reduces the
    memcmp expansion to a maximum of 2 load pairs (which matches what we
    do for -Os).

    This patch should be considered for the 5.0.0 release branch as well

    Differential Revision: https://reviews.llvm.org/D35830

  These fix a hang (or extremely long compile time) when building older
  LLVM ports.

  Reported by:    antoine
  PR:             219139

MFC r321719:

  Pull in r309503 from upstream clang trunk (by Richard Smith):

    PR33902: Invalidate line number cache when adding more text to
    existing buffer.

    This led to crashes as the line number cache would report a bogus
    line number for a line of code, and we'd try to find a nonexistent
    column within the line when printing diagnostics.

  This fixes an assertion when building the graphics/champlain port.

  Reported by:	antoine, kwm
  PR:		219139

MFC r321723:

  Upgrade our copies of clang, llvm, lld and lldb to r309439 from the
  upstream release_50 branch.  This is just after upstream's 5.0.0-rc1.

MFC r322320:

  Upgrade our copies of clang, llvm and libc++ to r310316 from the
  upstream release_50 branch.

MFC r322326 (by emaste):

  lldb: Make i386-*-freebsd expression work on JIT path

  * Enable i386 ABI creation for freebsd
  * Added an extra argument in ABISysV_i386::PrepareTrivialCall for mmap
    syscall
  * Unlike linux, the last argument of mmap is actually 64-bit(off_t).
    This requires us to push an additional word for the higher order bits.
  * Prior to this change, ktrace dump will show mmap failures due to
    invalid argument coming from the 6th mmap argument.

  Submitted by:	Karnajit Wangkhem
  Differential Revision:	https://reviews.llvm.org/D34776

MFC r322360 (by emaste):

  lldb: Report inferior signals as signals, not exceptions, on FreeBSD

  This is the FreeBSD equivalent of LLVM r238549.

  This serves 2 purposes:

  * LLDB should handle inferior process signals SIGSEGV/SIGILL/SIGBUS/
    SIGFPE the way it is suppose to be handled. Prior to this fix these
    signals will neither create a coredump, nor exit from the debugger
    or work for signal handling scenario.
  * eInvalidCrashReason need not report "unknown crash reason" if we have
    a valid si_signo

  llvm.org/pr23699

  Patch by Karnajit Wangkhem

  Differential Revision:  https://reviews.llvm.org/D35223

  Submitted by:	Karnajit Wangkhem
  Obtained from:	LLVM r310591

MFC r322474 (by emaste):

  lld: Add `-z muldefs` option.

  Obtained from:	LLVM r310757

MFC r322740:

  Upgrade our copies of clang, llvm, lld and libc++ to r311219 from the
  upstream release_50 branch.

MFC r322855:

  Upgrade our copies of clang, llvm, lldb and compiler-rt to r311606 from
  the upstream release_50 branch.

  As of this version, lib/msun's trig test should also work correctly
  again (see bug 220989 for more information).

  PR:		220989

MFC r323112:

  Upgrade our copies of clang, llvm, lldb and compiler-rt to r312293 from
  the upstream release_50 branch.  This corresponds to 5.0.0 rc4.

  As of this version, the cad/stepcode port should now compile in a more
  reasonable time on i386 (see bug 221836 for more information).

  PR:		221836

MFC r323245:

  Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
  5.0.0 release (upstream r312559).

  Release notes for llvm, clang and lld will be available here soon:
  <http://releases.llvm.org/5.0.0/docs/ReleaseNotes.html>
  <http://releases.llvm.org/5.0.0/tools/clang/docs/ReleaseNotes.html>
  <http://releases.llvm.org/5.0.0/tools/lld/docs/ReleaseNotes.html>

  Relnotes:	yes
2017-09-26 19:56:36 +00:00

878 lines
27 KiB
C++

// -*- C++ -*-
//===-------------------------- __string ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___STRING
#define _LIBCPP___STRING
/*
string synopsis
namespace std
{
template <class charT>
struct char_traits
{
typedef charT char_type;
typedef ... int_type;
typedef streamoff off_type;
typedef streampos pos_type;
typedef mbstate_t state_type;
static constexpr void assign(char_type& c1, const char_type& c2) noexcept;
static constexpr bool eq(char_type c1, char_type c2) noexcept;
static constexpr bool lt(char_type c1, char_type c2) noexcept;
static constexpr int compare(const char_type* s1, const char_type* s2, size_t n);
static constexpr size_t length(const char_type* s);
static constexpr const char_type*
find(const char_type* s, size_t n, const char_type& a);
static char_type* move(char_type* s1, const char_type* s2, size_t n);
static char_type* copy(char_type* s1, const char_type* s2, size_t n);
static char_type* assign(char_type* s, size_t n, char_type a);
static constexpr int_type not_eof(int_type c) noexcept;
static constexpr char_type to_char_type(int_type c) noexcept;
static constexpr int_type to_int_type(char_type c) noexcept;
static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept;
static constexpr int_type eof() noexcept;
};
template <> struct char_traits<char>;
template <> struct char_traits<wchar_t>;
} // std
*/
#include <__config>
#include <algorithm> // for search and min
#include <cstdio> // For EOF.
#include <memory> // for __murmur2_or_cityhash
#include <__debug>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_PUSH_MACROS
#include <__undef_macros>
_LIBCPP_BEGIN_NAMESPACE_STD
// char_traits
template <class _CharT>
struct _LIBCPP_TEMPLATE_VIS char_traits
{
typedef _CharT char_type;
typedef int int_type;
typedef streamoff off_type;
typedef streampos pos_type;
typedef mbstate_t state_type;
static inline void _LIBCPP_CONSTEXPR_AFTER_CXX14
assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
{return __c1 < __c2;}
static _LIBCPP_CONSTEXPR_AFTER_CXX14
int compare(const char_type* __s1, const char_type* __s2, size_t __n);
_LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
size_t length(const char_type* __s);
_LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
const char_type* find(const char_type* __s, size_t __n, const char_type& __a);
static char_type* move(char_type* __s1, const char_type* __s2, size_t __n);
_LIBCPP_INLINE_VISIBILITY
static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n);
_LIBCPP_INLINE_VISIBILITY
static char_type* assign(char_type* __s, size_t __n, char_type __a);
static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
{return char_type(__c);}
static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
{return int_type(__c);}
static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
{return int_type(EOF);}
};
template <class _CharT>
_LIBCPP_CONSTEXPR_AFTER_CXX14 int
char_traits<_CharT>::compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
for (; __n; --__n, ++__s1, ++__s2)
{
if (lt(*__s1, *__s2))
return -1;
if (lt(*__s2, *__s1))
return 1;
}
return 0;
}
template <class _CharT>
inline
_LIBCPP_CONSTEXPR_AFTER_CXX14 size_t
char_traits<_CharT>::length(const char_type* __s)
{
size_t __len = 0;
for (; !eq(*__s, char_type(0)); ++__s)
++__len;
return __len;
}
template <class _CharT>
inline
_LIBCPP_CONSTEXPR_AFTER_CXX14 const _CharT*
char_traits<_CharT>::find(const char_type* __s, size_t __n, const char_type& __a)
{
for (; __n; --__n)
{
if (eq(*__s, __a))
return __s;
++__s;
}
return 0;
}
template <class _CharT>
_CharT*
char_traits<_CharT>::move(char_type* __s1, const char_type* __s2, size_t __n)
{
char_type* __r = __s1;
if (__s1 < __s2)
{
for (; __n; --__n, ++__s1, ++__s2)
assign(*__s1, *__s2);
}
else if (__s2 < __s1)
{
__s1 += __n;
__s2 += __n;
for (; __n; --__n)
assign(*--__s1, *--__s2);
}
return __r;
}
template <class _CharT>
inline
_CharT*
char_traits<_CharT>::copy(char_type* __s1, const char_type* __s2, size_t __n)
{
_LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
char_type* __r = __s1;
for (; __n; --__n, ++__s1, ++__s2)
assign(*__s1, *__s2);
return __r;
}
template <class _CharT>
inline
_CharT*
char_traits<_CharT>::assign(char_type* __s, size_t __n, char_type __a)
{
char_type* __r = __s;
for (; __n; --__n, ++__s)
assign(*__s, __a);
return __r;
}
// char_traits<char>
template <>
struct _LIBCPP_TEMPLATE_VIS char_traits<char>
{
typedef char char_type;
typedef int int_type;
typedef streamoff off_type;
typedef streampos pos_type;
typedef mbstate_t state_type;
static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
{return (unsigned char)__c1 < (unsigned char)__c2;}
static _LIBCPP_CONSTEXPR_AFTER_CXX14
int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
static inline size_t _LIBCPP_CONSTEXPR_AFTER_CXX14
length(const char_type* __s) _NOEXCEPT {return __builtin_strlen(__s);}
static _LIBCPP_CONSTEXPR_AFTER_CXX14
const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{return __n == 0 ? __s1 : (char_type*) memmove(__s1, __s2, __n);}
static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
_LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
return __n == 0 ? __s1 : (char_type*)memcpy(__s1, __s2, __n);
}
static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
{return __n == 0 ? __s : (char_type*)memset(__s, to_int_type(__a), __n);}
static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
{return char_type(__c);}
static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
{return int_type((unsigned char)__c);}
static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
{return int_type(EOF);}
};
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
int
char_traits<char>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
if (__n == 0)
return 0;
#if __has_feature(cxx_constexpr_string_builtins)
return __builtin_memcmp(__s1, __s2, __n);
#elif _LIBCPP_STD_VER <= 14
return memcmp(__s1, __s2, __n);
#else
for (; __n; --__n, ++__s1, ++__s2)
{
if (lt(*__s1, *__s2))
return -1;
if (lt(*__s2, *__s1))
return 1;
}
return 0;
#endif
}
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
const char*
char_traits<char>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
{
if (__n == 0)
return NULL;
#if __has_feature(cxx_constexpr_string_builtins)
return __builtin_char_memchr(__s, to_int_type(__a), __n);
#elif _LIBCPP_STD_VER <= 14
return (const char_type*) memchr(__s, to_int_type(__a), __n);
#else
for (; __n; --__n)
{
if (eq(*__s, __a))
return __s;
++__s;
}
return NULL;
#endif
}
// char_traits<wchar_t>
template <>
struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t>
{
typedef wchar_t char_type;
typedef wint_t int_type;
typedef streamoff off_type;
typedef streampos pos_type;
typedef mbstate_t state_type;
static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
{return __c1 < __c2;}
static _LIBCPP_CONSTEXPR_AFTER_CXX14
int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
static _LIBCPP_CONSTEXPR_AFTER_CXX14
size_t length(const char_type* __s) _NOEXCEPT;
static _LIBCPP_CONSTEXPR_AFTER_CXX14
const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
static inline char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{return __n == 0 ? __s1 : (char_type*)wmemmove(__s1, __s2, __n);}
static inline char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
_LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
return __n == 0 ? __s1 : (char_type*)wmemcpy(__s1, __s2, __n);
}
static inline char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
{return __n == 0 ? __s : (char_type*)wmemset(__s, __a, __n);}
static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
{return char_type(__c);}
static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
{return int_type(__c);}
static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
{return int_type(WEOF);}
};
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
int
char_traits<wchar_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
if (__n == 0)
return 0;
#if __has_feature(cxx_constexpr_string_builtins)
return __builtin_wmemcmp(__s1, __s2, __n);
#elif _LIBCPP_STD_VER <= 14
return wmemcmp(__s1, __s2, __n);
#else
for (; __n; --__n, ++__s1, ++__s2)
{
if (lt(*__s1, *__s2))
return -1;
if (lt(*__s2, *__s1))
return 1;
}
return 0;
#endif
}
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
size_t
char_traits<wchar_t>::length(const char_type* __s) _NOEXCEPT
{
#if __has_feature(cxx_constexpr_string_builtins)
return __builtin_wcslen(__s);
#elif _LIBCPP_STD_VER <= 14
return wcslen(__s);
#else
size_t __len = 0;
for (; !eq(*__s, char_type(0)); ++__s)
++__len;
return __len;
#endif
}
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
const wchar_t*
char_traits<wchar_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
{
if (__n == 0)
return NULL;
#if __has_feature(cxx_constexpr_string_builtins)
return __builtin_wmemchr(__s, __a, __n);
#elif _LIBCPP_STD_VER <= 14
return wmemchr(__s, __a, __n);
#else
for (; __n; --__n)
{
if (eq(*__s, __a))
return __s;
++__s;
}
return NULL;
#endif
}
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
template <>
struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t>
{
typedef char16_t char_type;
typedef uint_least16_t int_type;
typedef streamoff off_type;
typedef u16streampos pos_type;
typedef mbstate_t state_type;
static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
{return __c1 < __c2;}
_LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
size_t length(const char_type* __s) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
{return char_type(__c);}
static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
{return int_type(__c);}
static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
{return int_type(0xFFFF);}
};
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
int
char_traits<char16_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
for (; __n; --__n, ++__s1, ++__s2)
{
if (lt(*__s1, *__s2))
return -1;
if (lt(*__s2, *__s1))
return 1;
}
return 0;
}
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
size_t
char_traits<char16_t>::length(const char_type* __s) _NOEXCEPT
{
size_t __len = 0;
for (; !eq(*__s, char_type(0)); ++__s)
++__len;
return __len;
}
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
const char16_t*
char_traits<char16_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
{
for (; __n; --__n)
{
if (eq(*__s, __a))
return __s;
++__s;
}
return 0;
}
inline
char16_t*
char_traits<char16_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
char_type* __r = __s1;
if (__s1 < __s2)
{
for (; __n; --__n, ++__s1, ++__s2)
assign(*__s1, *__s2);
}
else if (__s2 < __s1)
{
__s1 += __n;
__s2 += __n;
for (; __n; --__n)
assign(*--__s1, *--__s2);
}
return __r;
}
inline
char16_t*
char_traits<char16_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
_LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
char_type* __r = __s1;
for (; __n; --__n, ++__s1, ++__s2)
assign(*__s1, *__s2);
return __r;
}
inline
char16_t*
char_traits<char16_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
{
char_type* __r = __s;
for (; __n; --__n, ++__s)
assign(*__s, __a);
return __r;
}
template <>
struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t>
{
typedef char32_t char_type;
typedef uint_least32_t int_type;
typedef streamoff off_type;
typedef u32streampos pos_type;
typedef mbstate_t state_type;
static inline _LIBCPP_CONSTEXPR_AFTER_CXX14
void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;}
static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT
{return __c1 < __c2;}
_LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
size_t length(const char_type* __s) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_AFTER_CXX14
const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
static char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT;
static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT
{return eq_int_type(__c, eof()) ? ~eof() : __c;}
static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT
{return char_type(__c);}
static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT
{return int_type(__c);}
static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT
{return __c1 == __c2;}
static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT
{return int_type(0xFFFFFFFF);}
};
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
int
char_traits<char32_t>::compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
for (; __n; --__n, ++__s1, ++__s2)
{
if (lt(*__s1, *__s2))
return -1;
if (lt(*__s2, *__s1))
return 1;
}
return 0;
}
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
size_t
char_traits<char32_t>::length(const char_type* __s) _NOEXCEPT
{
size_t __len = 0;
for (; !eq(*__s, char_type(0)); ++__s)
++__len;
return __len;
}
inline _LIBCPP_CONSTEXPR_AFTER_CXX14
const char32_t*
char_traits<char32_t>::find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT
{
for (; __n; --__n)
{
if (eq(*__s, __a))
return __s;
++__s;
}
return 0;
}
inline
char32_t*
char_traits<char32_t>::move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
char_type* __r = __s1;
if (__s1 < __s2)
{
for (; __n; --__n, ++__s1, ++__s2)
assign(*__s1, *__s2);
}
else if (__s2 < __s1)
{
__s1 += __n;
__s2 += __n;
for (; __n; --__n)
assign(*--__s1, *--__s2);
}
return __r;
}
inline
char32_t*
char_traits<char32_t>::copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT
{
_LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range");
char_type* __r = __s1;
for (; __n; --__n, ++__s1, ++__s2)
assign(*__s1, *__s2);
return __r;
}
inline
char32_t*
char_traits<char32_t>::assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT
{
char_type* __r = __s;
for (; __n; --__n, ++__s)
assign(*__s, __a);
return __r;
}
#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
// helper fns for basic_string and string_view
// __str_find
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_find(const _CharT *__p, _SizeT __sz,
_CharT __c, _SizeT __pos) _NOEXCEPT
{
if (__pos >= __sz)
return __npos;
const _CharT* __r = _Traits::find(__p + __pos, __sz - __pos, __c);
if (__r == 0)
return __npos;
return static_cast<_SizeT>(__r - __p);
}
template <class _CharT, class _Traits>
inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _CharT *
__search_substring(const _CharT *__first1, const _CharT *__last1,
const _CharT *__first2, const _CharT *__last2) {
// Take advantage of knowing source and pattern lengths.
// Stop short when source is smaller than pattern.
const ptrdiff_t __len2 = __last2 - __first2;
if (__len2 == 0)
return __first1;
ptrdiff_t __len1 = __last1 - __first1;
if (__len1 < __len2)
return __last1;
// First element of __first2 is loop invariant.
_CharT __f2 = *__first2;
while (true) {
__len1 = __last1 - __first1;
// Check whether __first1 still has at least __len2 bytes.
if (__len1 < __len2)
return __last1;
// Find __f2 the first byte matching in __first1.
__first1 = _Traits::find(__first1, __len1 - __len2 + 1, __f2);
if (__first1 == 0)
return __last1;
// It is faster to compare from the first byte of __first1 even if we
// already know that it matches the first byte of __first2: this is because
// __first2 is most likely aligned, as it is user's "pattern" string, and
// __first1 + 1 is most likely not aligned, as the match is in the middle of
// the string.
if (_Traits::compare(__first1, __first2, __len2) == 0)
return __first1;
++__first1;
}
}
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_find(const _CharT *__p, _SizeT __sz,
const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
{
if (__pos > __sz)
return __npos;
if (__n == 0) // There is nothing to search, just return __pos.
return __pos;
const _CharT *__r = __search_substring<_CharT, _Traits>(
__p + __pos, __p + __sz, __s, __s + __n);
if (__r == __p + __sz)
return __npos;
return static_cast<_SizeT>(__r - __p);
}
// __str_rfind
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_rfind(const _CharT *__p, _SizeT __sz,
_CharT __c, _SizeT __pos) _NOEXCEPT
{
if (__sz < 1)
return __npos;
if (__pos < __sz)
++__pos;
else
__pos = __sz;
for (const _CharT* __ps = __p + __pos; __ps != __p;)
{
if (_Traits::eq(*--__ps, __c))
return static_cast<_SizeT>(__ps - __p);
}
return __npos;
}
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_rfind(const _CharT *__p, _SizeT __sz,
const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
{
__pos = _VSTD::min(__pos, __sz);
if (__n < __sz - __pos)
__pos += __n;
else
__pos = __sz;
const _CharT* __r = _VSTD::__find_end(
__p, __p + __pos, __s, __s + __n, _Traits::eq,
random_access_iterator_tag(), random_access_iterator_tag());
if (__n > 0 && __r == __p + __pos)
return __npos;
return static_cast<_SizeT>(__r - __p);
}
// __str_find_first_of
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_find_first_of(const _CharT *__p, _SizeT __sz,
const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
{
if (__pos >= __sz || __n == 0)
return __npos;
const _CharT* __r = _VSTD::__find_first_of_ce
(__p + __pos, __p + __sz, __s, __s + __n, _Traits::eq );
if (__r == __p + __sz)
return __npos;
return static_cast<_SizeT>(__r - __p);
}
// __str_find_last_of
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_find_last_of(const _CharT *__p, _SizeT __sz,
const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
{
if (__n != 0)
{
if (__pos < __sz)
++__pos;
else
__pos = __sz;
for (const _CharT* __ps = __p + __pos; __ps != __p;)
{
const _CharT* __r = _Traits::find(__s, __n, *--__ps);
if (__r)
return static_cast<_SizeT>(__ps - __p);
}
}
return __npos;
}
// __str_find_first_not_of
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
{
if (__pos < __sz)
{
const _CharT* __pe = __p + __sz;
for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
if (_Traits::find(__s, __n, *__ps) == 0)
return static_cast<_SizeT>(__ps - __p);
}
return __npos;
}
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_find_first_not_of(const _CharT *__p, _SizeT __sz,
_CharT __c, _SizeT __pos) _NOEXCEPT
{
if (__pos < __sz)
{
const _CharT* __pe = __p + __sz;
for (const _CharT* __ps = __p + __pos; __ps != __pe; ++__ps)
if (!_Traits::eq(*__ps, __c))
return static_cast<_SizeT>(__ps - __p);
}
return __npos;
}
// __str_find_last_not_of
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
const _CharT* __s, _SizeT __pos, _SizeT __n) _NOEXCEPT
{
if (__pos < __sz)
++__pos;
else
__pos = __sz;
for (const _CharT* __ps = __p + __pos; __ps != __p;)
if (_Traits::find(__s, __n, *--__ps) == 0)
return static_cast<_SizeT>(__ps - __p);
return __npos;
}
template<class _CharT, class _SizeT, class _Traits, _SizeT __npos>
inline _SizeT _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY
__str_find_last_not_of(const _CharT *__p, _SizeT __sz,
_CharT __c, _SizeT __pos) _NOEXCEPT
{
if (__pos < __sz)
++__pos;
else
__pos = __sz;
for (const _CharT* __ps = __p + __pos; __ps != __p;)
if (!_Traits::eq(*--__ps, __c))
return static_cast<_SizeT>(__ps - __p);
return __npos;
}
template<class _Ptr>
inline _LIBCPP_INLINE_VISIBILITY
size_t __do_string_hash(_Ptr __p, _Ptr __e)
{
typedef typename iterator_traits<_Ptr>::value_type value_type;
return __murmur2_or_cityhash<size_t>()(__p, (__e-__p)*sizeof(value_type));
}
template <class _CharT, class _Iter, class _Traits=char_traits<_CharT> >
struct __quoted_output_proxy
{
_Iter __first;
_Iter __last;
_CharT __delim;
_CharT __escape;
__quoted_output_proxy(_Iter __f, _Iter __l, _CharT __d, _CharT __e)
: __first(__f), __last(__l), __delim(__d), __escape(__e) {}
// This would be a nice place for a string_ref
};
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
#endif // _LIBCPP___STRING