Skip to content

Commit

Permalink
Making matching tables compile-time constants
Browse files Browse the repository at this point in the history
  • Loading branch information
gershnik committed Jan 4, 2024
1 parent f2e671b commit 0b5440e
Show file tree
Hide file tree
Showing 20 changed files with 1,065 additions and 755 deletions.
30 changes: 16 additions & 14 deletions Translit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@
445D1E5F2AFE35AA00FA1C07 /* InputController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 445D1E5E2AFE35AA00FA1C07 /* InputController.mm */; };
445D1E622AFE364900FA1C07 /* Transliterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 445D1E602AFE364900FA1C07 /* Transliterator.cpp */; };
445D1E662AFFA1F700FA1C07 /* InputMethodKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 445D1E652AFFA1F700FA1C07 /* InputMethodKit.framework */; };
4475AD322B11F97F008DA122 /* TestStateMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4475AD312B11F97F008DA122 /* TestStateMachine.mm */; };
44C675812B021410003A5BDE /* TransliteratorRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 44C6757F2B021410003A5BDE /* TransliteratorRegistry.cpp */; };
44C675822B021410003A5BDE /* TransliteratorRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 44C6757F2B021410003A5BDE /* TransliteratorRegistry.cpp */; };
4475AD322B11F97F008DA122 /* TestPrefixMapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4475AD312B11F97F008DA122 /* TestPrefixMapper.mm */; };
44B947CF2B4698E500B68C7E /* TestPerf.mm in Sources */ = {isa = PBXBuildFile; fileRef = 44B947CE2B4698E500B68C7E /* TestPerf.mm */; };
44B947D12B469B4C00B68C7E /* TestMapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 44B947D02B469B4C00B68C7E /* TestMapper.mm */; };
44C675842B02153F003A5BDE /* TestRu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 44C675832B02153F003A5BDE /* TestRu.mm */; };
44C675922B0219E9003A5BDE /* unicode_mappings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 44C675902B0219DA003A5BDE /* unicode_mappings.cpp */; };
44C675B32B021AE9003A5BDE /* libsys_string.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 44C675892B0218E1003A5BDE /* libsys_string.a */; };
Expand Down Expand Up @@ -128,13 +128,14 @@
445D1E712AFFFAB800FA1C07 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
445D1E732AFFFAE600FA1C07 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/InfoPlist.strings; sourceTree = "<group>"; };
446DBB8E2B00BD53000B76EC /* TranslitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TranslitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4475AD302B11EEE4008DA122 /* StateMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = StateMachine.hpp; sourceTree = "<group>"; };
4475AD312B11F97F008DA122 /* TestStateMachine.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestStateMachine.mm; sourceTree = "<group>"; };
4475AD302B11EEE4008DA122 /* Mapper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Mapper.hpp; sourceTree = "<group>"; };
4475AD312B11F97F008DA122 /* TestPrefixMapper.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestPrefixMapper.mm; sourceTree = "<group>"; };
4475AD332B131F80008DA122 /* Main.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Main.xctestplan; sourceTree = "<group>"; };
4475AD342B132242008DA122 /* Perf.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Perf.xctestplan; sourceTree = "<group>"; };
449738F62B44FA4300C7FAA9 /* MultiMatch.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MultiMatch.hpp; sourceTree = "<group>"; };
44B947CE2B4698E500B68C7E /* TestPerf.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestPerf.mm; sourceTree = "<group>"; };
44B947D02B469B4C00B68C7E /* TestMapper.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestMapper.mm; sourceTree = "<group>"; };
44C6757E2B01B4FD003A5BDE /* TableRU.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TableRU.hpp; sourceTree = "<group>"; };
44C6757F2B021410003A5BDE /* TransliteratorRegistry.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TransliteratorRegistry.cpp; sourceTree = "<group>"; };
44C675802B021410003A5BDE /* TransliteratorRegistry.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TransliteratorRegistry.hpp; sourceTree = "<group>"; };
44C675832B02153F003A5BDE /* TestRu.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TestRu.mm; sourceTree = "<group>"; };
44C675892B0218E1003A5BDE /* libsys_string.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsys_string.a; sourceTree = BUILT_PRODUCTS_DIR; };
44C675902B0219DA003A5BDE /* unicode_mappings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unicode_mappings.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -337,11 +338,10 @@
445D1E4B2AFE2C6C00FA1C07 /* AppDelegate.mm */,
44C675C62B034E17003A5BDE /* MenuProtocol.hpp */,
445D1E5E2AFE35AA00FA1C07 /* InputController.mm */,
4475AD302B11EEE4008DA122 /* StateMachine.hpp */,
4475AD302B11EEE4008DA122 /* Mapper.hpp */,
449738F62B44FA4300C7FAA9 /* MultiMatch.hpp */,
445D1E602AFE364900FA1C07 /* Transliterator.cpp */,
445D1E612AFE364900FA1C07 /* Transliterator.hpp */,
44C6757F2B021410003A5BDE /* TransliteratorRegistry.cpp */,
44C675802B021410003A5BDE /* TransliteratorRegistry.hpp */,
44C6757E2B01B4FD003A5BDE /* TableRU.hpp */,
44C675B92B02635A003A5BDE /* TableHE.hpp */,
442D25802B044EE000204800 /* MappingsWindowController.hpp */,
Expand All @@ -356,8 +356,10 @@
446DBB8F2B00BD53000B76EC /* tests */ = {
isa = PBXGroup;
children = (
4475AD312B11F97F008DA122 /* TestStateMachine.mm */,
4475AD312B11F97F008DA122 /* TestPrefixMapper.mm */,
44B947D02B469B4C00B68C7E /* TestMapper.mm */,
44C675832B02153F003A5BDE /* TestRu.mm */,
44B947CE2B4698E500B68C7E /* TestPerf.mm */,
442D25BD2B0B2D2C00204800 /* TestCommon.hpp */,
442D25BE2B0B2D6600204800 /* TestCommon.mm */,
4475AD332B131F80008DA122 /* Main.xctestplan */,
Expand Down Expand Up @@ -683,7 +685,6 @@
files = (
442D25CC2B0CC97100204800 /* Uninstall.mm in Sources */,
442D25AC2B08339F00204800 /* AboutWindowController.mm in Sources */,
44C675812B021410003A5BDE /* TransliteratorRegistry.cpp in Sources */,
445D1E532AFE2C6F00FA1C07 /* main.mm in Sources */,
442D25822B044EE000204800 /* MappingsWindowController.mm in Sources */,
445D1E622AFE364900FA1C07 /* Transliterator.cpp in Sources */,
Expand All @@ -696,9 +697,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
44C675822B021410003A5BDE /* TransliteratorRegistry.cpp in Sources */,
4475AD322B11F97F008DA122 /* TestStateMachine.mm in Sources */,
4475AD322B11F97F008DA122 /* TestPrefixMapper.mm in Sources */,
442D25B42B0A2E1B00204800 /* Transliterator.cpp in Sources */,
44B947D12B469B4C00B68C7E /* TestMapper.mm in Sources */,
44B947CF2B4698E500B68C7E /* TestPerf.mm in Sources */,
44C675842B02153F003A5BDE /* TestRu.mm in Sources */,
442D25BF2B0B2D6600204800 /* TestCommon.mm in Sources */,
);
Expand Down
9 changes: 3 additions & 6 deletions Translit/src/InputController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#include "Transliterator.hpp"
#include "TransliteratorRegistry.hpp"
#include "AppDelegate.hpp"
#include "MenuProtocol.hpp"
#include "MappingsWindowController.hpp"
Expand All @@ -14,7 +13,7 @@ @interface InputController : IMKInputController<MenuProtocol>


@interface InputController() {
Transliterator * _transliterator;
std::unique_ptr<Transliterator> _transliterator;
MappingsWindowController * _mappingsController;
NSString * _currentLanguage;
}
Expand All @@ -29,8 +28,7 @@ -(id) initWithServer:(IMKServer*)server delegate:(id)delegate client:(id<IMKText
if (self)
{
_currentLanguage = @"ru";
_transliterator = &getTransliterator(_currentLanguage);
_transliterator->clear();
_transliterator = std::make_unique<Transliterator>(_currentLanguage);
}

return self;
Expand Down Expand Up @@ -98,8 +96,7 @@ -(void) setValue:(id)value forTag:(long)tag client:(id)sender
sys_string prefix = sys_string(NSBundle.mainBundle.bundleIdentifier) + S(".");
_currentLanguage = val.remove_prefix(prefix).ns_str();
os_log_info(OS_LOG_DEFAULT, "Setting language to %{public}@", _currentLanguage);
_transliterator = &getTransliterator(_currentLanguage);
_transliterator->clear();
_transliterator = std::make_unique<Transliterator>(_currentLanguage);
if (_mappingsController)
_mappingsController.language = _currentLanguage;
}
Expand Down
101 changes: 101 additions & 0 deletions Translit/src/Mapper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright (c) 2023, Eugene Gershnik
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef TRANSLIT_HEADER_MAPPER_HPP_INCLUDED
#define TRANSLIT_HEADER_MAPPER_HPP_INCLUDED

#include "MultiMatch.hpp"

template<class T, class Char, size_t N>
struct Mapping {
const T dst;
const CTString<Char, N> src;

constexpr Mapping(T c, const Char (&arr)[N + 1]) noexcept:
dst(c),
src(arr)
{}
};

template<class T, class Char, size_t N>
Mapping(T c, const Char (&arr)[N]) -> Mapping<T, Char, N - 1>;

template<class T>
struct Value {
const T value;

constexpr Value(T v) noexcept:
value(v)
{}
};


template<class Payload, class It>
struct PrefixMappingResult {
/**
End of match
If !payload always stays at the start of input
*/
It next;
/** The mapping of the match, if successful */
std::optional<Payload> payload;
/** Whether the answer is definite and won't change with larger input */
bool definite;
};

template<class Payload, std::ranges::forward_range Range>
constexpr auto nullPrefixMapper(const Range & range) {
return PrefixMappingResult<Payload, std::ranges::iterator_t<const Range>>{std::ranges::begin(range), std::nullopt, true};
}

template<std::ranges::forward_range Range, Mapping First, Mapping... Rest>
requires(SameCharType<First.src, Rest.src...> &&
(std::is_same_v<decltype(First.dst), decltype(Rest.dst)> && ...) &&
std::is_same_v<typename std::ranges::range_value_t<Range>, CharTypeOf<First.src>>)
constexpr auto makePrefixMapper() {

using Payload = std::remove_const_t<decltype(First.dst)>;
using Char = CharTypeOf<First.src>;

auto func = [](const Range & range) {
using Iterator = std::ranges::iterator_t<const Range>;

static constexpr auto multiMatch = makeMultiMatch<First.src, Rest.src...>();
static constexpr Payload mappings[1 + sizeof...(Rest)] = {First.dst, Rest.dst...};

auto res = prefixMatch(multiMatch, range);
if (res.index != multiMatch.noMatch)
return PrefixMappingResult<Payload, Iterator>{res.next, mappings[res.index], res.definite};
return PrefixMappingResult<Payload, Iterator>{res.next, std::nullopt, res.definite};
};

return func;
}

template<std::ranges::forward_range Range, Value Default, Mapping First, Mapping... Rest>
requires(SameCharType<First.src, Rest.src...> &&
std::is_same_v<decltype(Default.value), decltype(First.dst)> &&
(std::is_same_v<decltype(First.dst), decltype(Rest.dst)> && ...) &&
std::is_same_v<typename std::ranges::range_value_t<Range>, CharTypeOf<First.src>>)
constexpr auto makeMapper() {

using Payload = std::remove_const_t<decltype(First.dst)>;
using Char = CharTypeOf<First.src>;

auto func = [](const Range & range) {
using Iterator = std::ranges::iterator_t<const Range>;

static constexpr auto multiMatch = makeMultiMatch<First.src, Rest.src...>();
static constexpr Payload mappings[2 + sizeof...(Rest)] = {First.dst, Rest.dst..., Default.value};

auto res = match(multiMatch, range);
return mappings[res];
};

return func;
}


#endif


Loading

0 comments on commit 0b5440e

Please sign in to comment.