Skip to content

Instantly share code, notes, and snippets.

@ufcpp
Created August 16, 2019 06:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ufcpp/85f67108cf81119c9c2d69109183d1f9 to your computer and use it in GitHub Desktop.
Save ufcpp/85f67108cf81119c9c2d69109183d1f9 to your computer and use it in GitHub Desktop.
コンパイル時動的メモリ確保(non transient)が欲しい気持ちわからなくもない感じのだいぶやらかしたコード
using System;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
var s = "a àαаאاああ゙한亜ก\n";
foreach (var c in s)
{
Console.WriteLine($"{(int)c:X4} {GetBidiClass(c)} ({c})");
}
}
public static BidiClass GetBidiClass(int c)
{
var ascii = _asciiData;
if ((uint)c < (uint)ascii.Length) return (BidiClass)ascii[c];
if (c >= 0x10000) return BidiClass.L;
var segments = Items;
uint lower = 0;
uint upper = (uint)(segments.Length - 1);
while (lower <= unchecked((int)upper))
{
uint middle = (upper + lower) >> 1;
var r = segments[(int)middle];
if (c < r.Start) upper = middle - 1;
else
{
var end = segments[(int)middle + 1].Start;
if (c >= end) lower = middle + 1;
else return r.Class;
}
}
return BidiClass.ON;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private readonly struct Item
{
public readonly char Start;
public readonly BidiClass Class;
}
public enum BidiClass : byte
{
L = 0,
R = 1,
EN = 2,
ES = 3,
ET = 4,
AN = 5,
CS = 6,
B = 7,
S = 8,
WS = 9,
ON = 10,
LRE = 11,
LRO = 12,
AL = 13,
RLE = 14,
RLO = 15,
PDF = 16,
NSM = 17,
BN = 18,
FSI = 19,
LRI = 20,
RLI = 21,
PDI = 22,
}
#region UnicodeData.txt から生成してる
// ReadOnlySpan なプロパティにしておけば、
// https://ufcpp.net/blog/2018/12/staticdatareadonlyspan/
// この最適化が掛かるんで、動的なメモリ確保は発生しない。
private static ReadOnlySpan<byte> _asciiData => new byte[] { 18, 18, 18, 18, 18, 18, 18, 18, 18, 8, 7, 8, 9, 7, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 7, 7, 7, 8, 9, 10, 10, 4, 4, 4, 10, 10, 10, 10, 10, 3, 6, 3, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 18, };
// Item を静的データとして持つために byte 化。
// big endian? 知らない子ですね?
private static ReadOnlySpan<byte> _rawData => new byte[] {
0x7F, 0x00, 18,
0x85, 0x00, 7,
0x86, 0x00, 18,
0xA0, 0x00, 6,
0xA1, 0x00, 10,
0xA2, 0x00, 4,
0xA6, 0x00, 10,
0xAA, 0x00, 0,
0xAB, 0x00, 10,
0xAD, 0x00, 18,
0xAE, 0x00, 10,
0xB0, 0x00, 4,
0xB2, 0x00, 2,
0xB4, 0x00, 10,
0xB5, 0x00, 0,
0xB6, 0x00, 10,
0xB9, 0x00, 2,
0xBA, 0x00, 0,
0xBB, 0x00, 10,
0xC0, 0x00, 0,
0xD7, 0x00, 10,
0xD8, 0x00, 0,
0xF7, 0x00, 10,
0xF8, 0x00, 0,
0xB9, 0x02, 10,
0xBB, 0x02, 0,
0xC2, 0x02, 10,
0xD0, 0x02, 0,
0xD2, 0x02, 10,
0xE0, 0x02, 0,
0xE5, 0x02, 10,
0xEE, 0x02, 0,
0xEF, 0x02, 10,
0x70, 0x03, 0,
0x74, 0x03, 10,
0x76, 0x03, 0,
0x7E, 0x03, 10,
0x7F, 0x03, 0,
0x84, 0x03, 10,
0x86, 0x03, 0,
0x87, 0x03, 10,
0x88, 0x03, 0,
0xF6, 0x03, 10,
0xF7, 0x03, 0,
0x8A, 0x05, 10,
0x8F, 0x05, 4,
0xBE, 0x05, 1,
0x00, 0x06, 5,
0x06, 0x06, 10,
0x08, 0x06, 13,
0x09, 0x06, 4,
0x0B, 0x06, 13,
0x0C, 0x06, 6,
0x0D, 0x06, 13,
0x0E, 0x06, 10,
0x1B, 0x06, 13,
0x60, 0x06, 5,
0x6A, 0x06, 4,
0x6B, 0x06, 5,
0x6D, 0x06, 13,
0xDD, 0x06, 5,
0xDE, 0x06, 10,
0xE5, 0x06, 13,
0xE9, 0x06, 10,
0xEE, 0x06, 13,
0xF0, 0x06, 2,
0xFA, 0x06, 13,
0xC0, 0x07, 1,
0xF6, 0x07, 10,
0xFA, 0x07, 1,
0x60, 0x08, 13,
0xE2, 0x08, 5,
0x04, 0x09, 0,
0xF2, 0x09, 4,
0xF4, 0x09, 0,
0xFB, 0x09, 4,
0xFC, 0x09, 0,
0xF1, 0x0A, 4,
0xF9, 0x0A, 0,
0xF3, 0x0B, 10,
0xF9, 0x0B, 4,
0xFA, 0x0B, 10,
0x05, 0x0C, 0,
0x78, 0x0C, 10,
0x7F, 0x0C, 0,
0x3F, 0x0E, 4,
0x40, 0x0E, 0,
0xBA, 0x0E, 17,
0xBD, 0x0E, 0,
0x3A, 0x0F, 10,
0x40, 0x0F, 0,
0x90, 0x13, 10,
0xA0, 0x13, 0,
0x00, 0x14, 10,
0x01, 0x14, 0,
0x80, 0x16, 9,
0x81, 0x16, 0,
0x9B, 0x16, 10,
0xA0, 0x16, 0,
0xDB, 0x17, 4,
0xDC, 0x17, 0,
0xF0, 0x17, 10,
0x0E, 0x18, 18,
0x10, 0x18, 0,
0x40, 0x19, 10,
0x46, 0x19, 0,
0xDE, 0x19, 10,
0x00, 0x1A, 0,
0xBD, 0x1F, 10,
0xBE, 0x1F, 0,
0xBF, 0x1F, 10,
0xC2, 0x1F, 0,
0xCD, 0x1F, 10,
0xD0, 0x1F, 0,
0xDD, 0x1F, 10,
0xE0, 0x1F, 0,
0xED, 0x1F, 10,
0xF2, 0x1F, 0,
0xFD, 0x1F, 10,
0x00, 0x20, 9,
0x0B, 0x20, 18,
0x0E, 0x20, 0,
0x0F, 0x20, 1,
0x10, 0x20, 10,
0x28, 0x20, 9,
0x29, 0x20, 7,
0x2A, 0x20, 11,
0x2B, 0x20, 14,
0x2C, 0x20, 16,
0x2D, 0x20, 12,
0x2E, 0x20, 15,
0x2F, 0x20, 6,
0x30, 0x20, 4,
0x35, 0x20, 10,
0x44, 0x20, 6,
0x45, 0x20, 10,
0x5F, 0x20, 9,
0x60, 0x20, 18,
0x66, 0x20, 20,
0x67, 0x20, 21,
0x68, 0x20, 19,
0x69, 0x20, 22,
0x6A, 0x20, 18,
0x70, 0x20, 2,
0x71, 0x20, 0,
0x74, 0x20, 2,
0x7A, 0x20, 3,
0x7C, 0x20, 10,
0x7F, 0x20, 0,
0x80, 0x20, 2,
0x8A, 0x20, 3,
0x8C, 0x20, 10,
0x90, 0x20, 0,
0xA0, 0x20, 4,
0x00, 0x21, 10,
0x02, 0x21, 0,
0x03, 0x21, 10,
0x07, 0x21, 0,
0x08, 0x21, 10,
0x0A, 0x21, 0,
0x14, 0x21, 10,
0x15, 0x21, 0,
0x16, 0x21, 10,
0x19, 0x21, 0,
0x1E, 0x21, 10,
0x24, 0x21, 0,
0x25, 0x21, 10,
0x26, 0x21, 0,
0x27, 0x21, 10,
0x28, 0x21, 0,
0x29, 0x21, 10,
0x2A, 0x21, 0,
0x2E, 0x21, 4,
0x2F, 0x21, 0,
0x3A, 0x21, 10,
0x3C, 0x21, 0,
0x40, 0x21, 10,
0x45, 0x21, 0,
0x4A, 0x21, 10,
0x4E, 0x21, 0,
0x50, 0x21, 10,
0x60, 0x21, 0,
0x89, 0x21, 10,
0x12, 0x22, 3,
0x13, 0x22, 4,
0x14, 0x22, 10,
0x36, 0x23, 0,
0x7B, 0x23, 10,
0x95, 0x23, 0,
0x96, 0x23, 10,
0x88, 0x24, 2,
0x9C, 0x24, 0,
0xEA, 0x24, 10,
0xAC, 0x26, 0,
0xAD, 0x26, 10,
0x00, 0x28, 0,
0x00, 0x29, 10,
0x00, 0x2C, 0,
0xE5, 0x2C, 10,
0xEB, 0x2C, 0,
0xF9, 0x2C, 10,
0x00, 0x2D, 0,
0x00, 0x2E, 10,
0x00, 0x30, 9,
0x01, 0x30, 10,
0x05, 0x30, 0,
0x08, 0x30, 10,
0x21, 0x30, 0,
0x30, 0x30, 10,
0x31, 0x30, 0,
0x36, 0x30, 10,
0x38, 0x30, 0,
0x3D, 0x30, 10,
0x41, 0x30, 0,
0x9B, 0x30, 10,
0x9D, 0x30, 0,
0xA0, 0x30, 10,
0xA1, 0x30, 0,
0xFB, 0x30, 10,
0xFC, 0x30, 0,
0xC0, 0x31, 10,
0xF0, 0x31, 0,
0x1D, 0x32, 10,
0x20, 0x32, 0,
0x50, 0x32, 10,
0x60, 0x32, 0,
0x7C, 0x32, 10,
0x7F, 0x32, 0,
0xB1, 0x32, 10,
0xC0, 0x32, 0,
0xCC, 0x32, 10,
0xD0, 0x32, 0,
0x77, 0x33, 10,
0x7B, 0x33, 0,
0xDE, 0x33, 10,
0xE0, 0x33, 0,
0xFF, 0x33, 10,
0x00, 0x34, 0,
0xC0, 0x4D, 10,
0x00, 0x4E, 0,
0x90, 0xA4, 10,
0xD0, 0xA4, 0,
0x0D, 0xA6, 10,
0x10, 0xA6, 0,
0x73, 0xA6, 10,
0x80, 0xA6, 0,
0x00, 0xA7, 10,
0x22, 0xA7, 0,
0x88, 0xA7, 10,
0x89, 0xA7, 0,
0x28, 0xA8, 10,
0x30, 0xA8, 0,
0x38, 0xA8, 4,
0x40, 0xA8, 0,
0x74, 0xA8, 10,
0x82, 0xA8, 0,
0x1D, 0xFB, 1,
0x29, 0xFB, 3,
0x2A, 0xFB, 1,
0x50, 0xFB, 13,
0x3E, 0xFD, 10,
0x50, 0xFD, 13,
0xFD, 0xFD, 10,
0x50, 0xFE, 6,
0x51, 0xFE, 10,
0x52, 0xFE, 6,
0x54, 0xFE, 10,
0x55, 0xFE, 6,
0x56, 0xFE, 10,
0x5F, 0xFE, 4,
0x60, 0xFE, 10,
0x62, 0xFE, 3,
0x64, 0xFE, 10,
0x69, 0xFE, 4,
0x6B, 0xFE, 10,
0x70, 0xFE, 13,
0xFF, 0xFE, 18,
0x01, 0xFF, 10,
0x03, 0xFF, 4,
0x06, 0xFF, 10,
0x0B, 0xFF, 3,
0x0C, 0xFF, 6,
0x0D, 0xFF, 3,
0x0E, 0xFF, 6,
0x10, 0xFF, 2,
0x1A, 0xFF, 6,
0x1B, 0xFF, 10,
0x21, 0xFF, 0,
0x3B, 0xFF, 10,
0x41, 0xFF, 0,
0x5B, 0xFF, 10,
0x66, 0xFF, 0,
0xE0, 0xFF, 4,
0xE2, 0xFF, 10,
0xE5, 0xFF, 4,
0xE8, 0xFF, 10,
0xFF, 0xFF, 0 };
#endregion
private static ReadOnlySpan<Item> Items => MemoryMarshal.Cast<byte, Item>(_rawData);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment