namespace axl::enc

namespace enc {

// typedefs

typedef EscapeEncodingUtf<char> EscapeEncoding;
typedef EscapeEncodingUtf<wchar_t> EscapeEncoding_w;
typedef EscapeEncodingUtf<utf8_t> EscapeEncoding_utf8;
typedef EscapeEncodingUtf<utf16_t> EscapeEncoding_utf16;
typedef EscapeEncodingUtf<utf32_t> EscapeEncoding_utf32;

// enums

enum Base32EncodingFlag;
enum Base64EncodingFlag;
enum CharCodecKind;
enum EscapeEncodingFlag;
enum HexEncodingFlag;
enum UtfKind;

// classes

class AsciiCodec;

template <
    typename DstEncoding0,
    typename CaseOp = sl::NoOp<utf32_t>
    >
class AsciiToUtfConvert;

class Base32Encoding;
class Base32Encoding_nj;
class Base64Encoding;
class CharCodec;
class CodePointDecoder;
class EscapeEncodingDynamic;
class EscapeEncodingRoot;

template <typename T>
class EscapeEncodingUtf;

class GetBase32Char;
class GetBase64Char;
class GetBase64UrlChar;
class GetHexChar_l;
class GetHexChar_u;
class HexEncoding;
class Utf16;
class Utf16_be;
class Utf32;
class Utf32_be;
class Utf8;

template <typename T>
class UtfCodec;

template <
    typename DstEncoding0,
    typename SrcEncoding0,
    typename CaseOp = sl::NoOp<utf32_t>
    >
class UtfConvert;

template <
    typename SrcEncoding0,
    typename CaseOp = sl::NoOp<utf32_t>
    >
class UtfToAsciiConvert;

class UtfToCaseFolded;
class UtfToLowerCase;
class UtfToUpperCase;

// global functions

CharCodec*
getCharCodec(CharCodecKind codecKind);

size_t
uleb128(
    const void* p,
    size_t size,
    uint64_t* result = NULL
    );

size_t
sleb128(
    const void* p,
    size_t size,
    int64_t* result = NULL
    );

const char*
getUtfKindString(UtfKind utfKind);

bool
utfIsPrintable(utf32_t c);

bool
utfIsPrintableNonMark(utf32_t c);

bool
utfIsSpace(utf32_t c);

bool
utfIsPunctuation(utf32_t c);

bool
utfIsLetter(utf32_t c);

bool
utfIsDigit(utf32_t c);

bool
utfIsNumber(utf32_t c);

bool
utfIsLetterOrDigit(utf32_t c);

bool
utfIsLetterOrNumber(utf32_t c);

bool
utfIsLowerCase(utf32_t c);

bool
utfIsUpperCase(utf32_t c);

utf32_t
utfToLowerCase(utf32_t c);

utf32_t
utfToUpperCase(utf32_t c);

utf32_t
utfToCaseFolded(utf32_t c);

template <typename T>
size_t
calcUtfCodePointCount(
    const typename T::C* p,
    size_t length
    );

} // namespace enc