├── .clang-format ├── .editorconfig ├── .gitignore ├── .gitmodules ├── .markdownlint.json ├── .vscode ├── .gitignore └── settings.json ├── LICENSE.md ├── Makefile ├── README.md ├── cgeventtap-example ├── .gitignore ├── CMakeLists.txt ├── Makefile ├── README.md ├── Resources │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ └── MainMenu.xib └── src │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── CGEventTapExample.h │ ├── CGEventTapExample.m │ └── main.m ├── dist └── osx-event-observer-examples.dmg ├── docs └── images │ ├── accessibility.png │ ├── cgeventtap-example.png │ ├── input-monitoring.png │ ├── iokit-hid-report-example.png │ ├── iokit-hid-value-example.png │ ├── nsapplication-example.png │ ├── nsevent-example.png │ └── nsview-example.png ├── iokit-hid-report-example ├── .gitignore ├── CMakeLists.txt ├── Makefile ├── Resources │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ └── MainMenu.xib └── src │ ├── AppDelegate.h │ ├── AppDelegate.mm │ ├── IOKitHIDReportExample.h │ ├── IOKitHIDReportExample.mm │ └── main.m ├── iokit-hid-value-example ├── .gitignore ├── CMakeLists.txt ├── Makefile ├── Resources │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ └── MainMenu.xib └── src │ ├── AppDelegate.h │ ├── AppDelegate.mm │ ├── IOKitHIDValueExample.h │ ├── IOKitHIDValueExample.mm │ └── main.m ├── nsapplication-example ├── .gitignore ├── CMakeLists.txt ├── Makefile ├── Resources │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ └── MainMenu.xib └── src │ ├── AppDelegate.swift │ └── ExampleApplication.swift ├── nsevent-example ├── .gitignore ├── CMakeLists.txt ├── Makefile ├── Resources │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ └── MainMenu.xib └── src │ └── AppDelegate.swift ├── nsview-example ├── .gitignore ├── CMakeLists.txt ├── Makefile ├── Resources │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Info.plist │ └── MainMenu.xib └── src │ ├── AppDelegate.swift │ └── ExampleView.swift ├── scripts ├── codesign.sh └── get-codesign-identity.sh └── vendor ├── .gitignore ├── CMakeLists.txt ├── Makefile └── vendor └── include ├── debug_assert.hpp ├── nlohmann ├── adl_serializer.hpp ├── byte_container_with_subtype.hpp ├── detail │ ├── abi_macros.hpp │ ├── conversions │ │ ├── from_json.hpp │ │ ├── to_chars.hpp │ │ └── to_json.hpp │ ├── exceptions.hpp │ ├── hash.hpp │ ├── input │ │ ├── binary_reader.hpp │ │ ├── input_adapters.hpp │ │ ├── json_sax.hpp │ │ ├── lexer.hpp │ │ ├── parser.hpp │ │ └── position_t.hpp │ ├── iterators │ │ ├── internal_iterator.hpp │ │ ├── iter_impl.hpp │ │ ├── iteration_proxy.hpp │ │ ├── iterator_traits.hpp │ │ ├── json_reverse_iterator.hpp │ │ └── primitive_iterator.hpp │ ├── json_custom_base_class.hpp │ ├── json_pointer.hpp │ ├── json_ref.hpp │ ├── macro_scope.hpp │ ├── macro_unscope.hpp │ ├── meta │ │ ├── call_std │ │ │ ├── begin.hpp │ │ │ └── end.hpp │ │ ├── cpp_future.hpp │ │ ├── detected.hpp │ │ ├── identity_tag.hpp │ │ ├── is_sax.hpp │ │ ├── std_fs.hpp │ │ ├── type_traits.hpp │ │ └── void_t.hpp │ ├── output │ │ ├── binary_writer.hpp │ │ ├── output_adapters.hpp │ │ └── serializer.hpp │ ├── string_concat.hpp │ ├── string_escape.hpp │ ├── string_utils.hpp │ └── value_t.hpp ├── json.hpp ├── json_fwd.hpp ├── ordered_map.hpp └── thirdparty │ └── hedley │ ├── hedley.hpp │ └── hedley_undef.hpp ├── nod └── nod.hpp ├── pqrs ├── cf │ ├── array.hpp │ ├── cf_ptr.hpp │ ├── number.hpp │ ├── number │ │ └── impl.hpp │ ├── run_loop_thread.hpp │ ├── run_loop_thread │ │ └── extra │ │ │ └── shared_run_loop_thread.hpp │ └── string.hpp ├── dispatcher.hpp ├── dispatcher │ ├── dispatcher.hpp │ ├── extra │ │ ├── dispatcher_client.hpp │ │ ├── shared_dispatcher.hpp │ │ └── timer.hpp │ ├── object_id.hpp │ ├── time_source.hpp │ └── types.hpp ├── hash.hpp ├── hid.hpp ├── hid │ ├── country_code.hpp │ ├── extra │ │ ├── boost.hpp │ │ └── nlohmann_json.hpp │ ├── hash.hpp │ ├── manufacturer_string.hpp │ ├── product_id.hpp │ ├── product_string.hpp │ ├── report_id.hpp │ ├── usage.hpp │ ├── usage_page.hpp │ ├── usage_pair.hpp │ └── vendor_id.hpp ├── json.hpp ├── json │ ├── formatter.hpp │ ├── marshal_error.hpp │ ├── pqrs_formatter.hpp │ └── unmarshal_error.hpp ├── osx │ ├── chrono.hpp │ ├── chrono │ │ ├── absolute_time_duration.hpp │ │ ├── absolute_time_point.hpp │ │ ├── chrono.hpp │ │ ├── extra │ │ │ └── nlohmann_json.hpp │ │ └── impl │ │ │ └── chrono.hpp │ ├── iokit_hid_device.hpp │ ├── iokit_hid_device_report_monitor.hpp │ ├── iokit_hid_element.hpp │ ├── iokit_hid_element │ │ └── iokit_hid_element_type.hpp │ ├── iokit_hid_manager.hpp │ ├── iokit_hid_queue_value_monitor.hpp │ ├── iokit_hid_value.hpp │ ├── iokit_hid_value │ │ └── extra │ │ │ └── nlohmann_json.hpp │ ├── iokit_iterator.hpp │ ├── iokit_object_ptr.hpp │ ├── iokit_registry_entry.hpp │ ├── iokit_return.hpp │ ├── iokit_service_monitor.hpp │ ├── iokit_types.hpp │ ├── iokit_types │ │ ├── extra │ │ │ ├── boost.hpp │ │ │ └── nlohmann_json.hpp │ │ ├── hash.hpp │ │ ├── iokit_hid_location_id.hpp │ │ ├── iokit_keyboard_type.hpp │ │ ├── iokit_mach_port.hpp │ │ └── iokit_registry_entry_id.hpp │ └── kern_return.hpp ├── string.hpp ├── string │ ├── predicate.hpp │ ├── trim.hpp │ └── truncate.hpp ├── thread_wait.hpp └── weakify.h ├── type_safe ├── arithmetic_policy.hpp ├── boolean.hpp ├── bounded_type.hpp ├── compact_optional.hpp ├── config.hpp ├── constrained_type.hpp ├── deferred_construction.hpp ├── detail │ ├── aligned_union.hpp │ ├── all_of.hpp │ ├── assert.hpp │ ├── assign_or_construct.hpp │ ├── constant_parser.hpp │ ├── copy_move_control.hpp │ ├── force_inline.hpp │ ├── is_nothrow_swappable.hpp │ ├── map_invoke.hpp │ └── variant_impl.hpp ├── downcast.hpp ├── flag.hpp ├── flag_set.hpp ├── floating_point.hpp ├── index.hpp ├── integer.hpp ├── narrow_cast.hpp ├── optional.hpp ├── optional_ref.hpp ├── output_parameter.hpp ├── reference.hpp ├── strong_typedef.hpp ├── tagged_union.hpp ├── types.hpp ├── variant.hpp └── visitor.hpp └── utf8cpp ├── utf8.h └── utf8 ├── checked.h ├── core.h ├── cpp11.h ├── cpp17.h ├── cpp20.h └── unchecked.h /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | ColumnLimit: 0 3 | DerivePointerBinding: true 4 | AllowShortIfStatementsOnASingleLine: true 5 | AllowShortBlocksOnASingleLine: true 6 | PointerAlignment: Left 7 | IndentCaseLabels: true 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | 11 | [Makefile] 12 | indent_style = tab 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ============================================================ 2 | 3 | # Created by https://www.gitignore.io/api/macos 4 | # Edit at https://www.gitignore.io/?templates=macos 5 | 6 | ### macOS ### 7 | # General 8 | .DS_Store 9 | .AppleDouble 10 | .LSOverride 11 | 12 | # Icon must end with two \r 13 | Icon 14 | 15 | # Thumbnails 16 | ._* 17 | 18 | # Files that might appear in the root of a volume 19 | .DocumentRevisions-V100 20 | .fseventsd 21 | .Spotlight-V100 22 | .TemporaryItems 23 | .Trashes 24 | .VolumeIcon.icns 25 | .com.apple.timemachine.donotpresent 26 | 27 | # Directories potentially created on remote AFP share 28 | .AppleDB 29 | .AppleDesktop 30 | Network Trash Folder 31 | Temporary Items 32 | .apdisk 33 | 34 | # End of https://www.gitignore.io/api/macos 35 | 36 | # ============================================================ 37 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/cpm-cmake-package-lock"] 2 | path = vendor/cpm-cmake-package-lock 3 | url = https://github.com/pqrs-org/cpm-cmake-package-lock.git 4 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD013": false, 3 | "MD030": { 4 | "ol_single": 2, 5 | "ol_multi": 2 6 | }, 7 | "MD033": { 8 | "allowed_elements": ["br"] 9 | }, 10 | "MD041": false 11 | } 12 | -------------------------------------------------------------------------------- /.vscode/.gitignore: -------------------------------------------------------------------------------- 1 | /browse.vc.db* -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | ".vscode/browse.*": true, 4 | "**/.DS_Store": true, 5 | "**/.git": true, 6 | "**/build_xcode/": true, 7 | "**/build/": true, 8 | }, 9 | "search.exclude": { 10 | "**/node_modules": true, 11 | "**/bower_components": true, 12 | "**/vendor": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | make -C cgeventtap-example 3 | make -C iokit-hid-report-example 4 | make -C iokit-hid-value-example 5 | make -C nsapplication-example 6 | make -C nsevent-example 7 | make -C nsview-example 8 | 9 | clean: 10 | make -C cgeventtap-example clean 11 | make -C iokit-hid-report-example clean 12 | make -C iokit-hid-value-example clean 13 | make -C nsapplication-example clean 14 | make -C nsevent-example clean 15 | make -C nsview-example clean 16 | 17 | dist: clean all 18 | rm -rf osx-event-observer-examples 19 | mkdir -p osx-event-observer-examples 20 | rsync -aH \ 21 | cgeventtap-example/build_xcode/Release/cgeventtap-example.app \ 22 | osx-event-observer-examples 23 | rsync -aH \ 24 | iokit-hid-report-example/build_xcode/Release/iokit-hid-report-example.app \ 25 | osx-event-observer-examples 26 | rsync -aH \ 27 | iokit-hid-value-example/build_xcode/Release/iokit-hid-value-example.app \ 28 | osx-event-observer-examples 29 | rsync -aH \ 30 | nsapplication-example/build_xcode/Release/nsapplication-example.app \ 31 | osx-event-observer-examples 32 | rsync -aH \ 33 | nsevent-example/build_xcode/Release/nsevent-example.app \ 34 | osx-event-observer-examples 35 | rsync -aH \ 36 | nsview-example/build_xcode/Release/nsview-example.app \ 37 | osx-event-observer-examples 38 | bash ./scripts/codesign.sh osx-event-observer-examples 39 | hdiutil create -nospotlight osx-event-observer-examples.dmg -srcfolder osx-event-observer-examples -fs 'Journaled HFS+' 40 | rm -rf osx-event-observer-examples 41 | mkdir -p dist 42 | mv osx-event-observer-examples.dmg dist 43 | 44 | notarize: 45 | xcrun notarytool \ 46 | submit dist/osx-event-observer-examples.dmg \ 47 | --keychain-profile "pqrs.org notarization" \ 48 | --wait 49 | $(MAKE) staple 50 | say "notarization completed" 51 | 52 | staple: 53 | xcrun stapler staple dist/osx-event-observer-examples.dmg 54 | 55 | check-staple: 56 | xcrun stapler validate dist/osx-event-observer-examples.dmg 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![License](https://img.shields.io/badge/license-Public%20Domain-blue.svg)](https://github.com/pqrs-org/osx-event-observer-examples/blob/main/LICENSE.md) 2 | 3 | # osx-event-observer-examples 4 | 5 | - cgeventtap-example 6 | - `CGEventTapCreate` 7 | - ![cgeventtap-example](docs/images/cgeventtap-example.png) 8 | - iokit-hid-report-example 9 | - `IOHIDDeviceRegisterInputReportCallback` 10 | - ![iokit-hid-report-example](docs/images/iokit-hid-report-example.png) 11 | - iokit-hid-value-example 12 | - `IOHIDQueueRegisterValueAvailableCallback` 13 | - ![iokit-hid-value-example](docs/images/iokit-hid-value-example.png) 14 | - nsapplication-example 15 | - `[NSApplication sendEvent]` 16 | - ![cgeventtap-example](docs/images/nsapplication-example.png) 17 | - nsevent-example 18 | - `[NSEvent addGlobalMonitorForEvents]` 19 | - (Equivalent to `CGEventTapCreate` but cannot modify received events) 20 | - ![nsevent-example](docs/images/nsevent-example.png) 21 | - nsview-example 22 | - `[NSView keyDown]` 23 | - ![nsview-example](docs/images/nsview-example.png) 24 | 25 | --- 26 | 27 | ## Related documentation 28 | 29 | [All about macOS event observation](https://docs.google.com/presentation/d/1nEaiPUduh1vjks0rDVRTcJaEULbSWWh1tVdG2HF_XSU/edit#slide=id.p) 30 | 31 | --- 32 | 33 | ## System requirements 34 | 35 | - macOS 10.13 or later 36 | 37 | --- 38 | 39 | ## Building example apps 40 | 41 | ### Requirements 42 | 43 | - CMake (`brew install cmake`) 44 | 45 | ### Steps 46 | 47 | 1. Find your codesign identity if you have one.
48 | (Skip this step if you don't have your codesign identity.) 49 | 50 | ```shell 51 | security find-identity -p codesigning -v | grep 'Developer ID Application' 52 | ``` 53 | 54 | The result is as follows. 55 | 56 | ```text 57 | 1) 8D660191481C98F5C56630847A6C39D95C166F22 "Developer ID Application: Fumihiko Takayama (G43BCU2T37)" 58 | ``` 59 | 60 | Your codesign identity is `8D660191481C98F5C56630847A6C39D95C166F22` in the above case. 61 | 62 | 2. Set environment variable to use your codesign identity.
63 | (Skip this step if you don't have your codesign identity.) 64 | 65 | ```shell 66 | export PQRS_ORG_CODE_SIGN_IDENTITY=8D660191481C98F5C56630847A6C39D95C166F22 67 | ``` 68 | 69 | 3. Build `dist/osx-event-observer-examples.dmg` by the following command on terminal. 70 | 71 | ```shell 72 | make dist 73 | ``` 74 | 75 | --- 76 | 77 | ## Note 78 | 79 | User approval of Accessibility is required to use cgeventtap-example and nsevent-example. 80 | (User approval of Input Monitoring is also required since macOS 10.15) 81 | 82 | ![processes](docs/images/accessibility.png) 83 | 84 | User approval of Accessibility and Input Monitoring is required 85 | to use `iokit-hid-value-example` since macOS 10.15. 86 | 87 | ![processes](docs/images/input-monitoring.png) 88 | -------------------------------------------------------------------------------- /cgeventtap-example/.gitignore: -------------------------------------------------------------------------------- 1 | /build_xcode 2 | -------------------------------------------------------------------------------- /cgeventtap-example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.24 FATAL_ERROR) 2 | 3 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment version") 4 | set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for Mac OS X") 5 | 6 | project (cgeventtap-example) 7 | 8 | add_compile_options(-Wall) 9 | add_compile_options(-Werror) 10 | add_compile_options(-O2) 11 | add_compile_options(-fobjc-arc) 12 | add_compile_options(-fmodules) 13 | 14 | add_executable( 15 | cgeventtap-example 16 | MACOSX_BUNDLE 17 | src/AppDelegate.m 18 | src/AppDelegate.h 19 | src/CGEventTapExample.m 20 | src/CGEventTapExample.h 21 | src/main.m 22 | Resources/MainMenu.xib 23 | Resources/Assets.xcassets 24 | ) 25 | 26 | set_source_files_properties( 27 | Resources/MainMenu.xib 28 | Resources/Assets.xcassets 29 | PROPERTIES 30 | MACOSX_PACKAGE_LOCATION 31 | Resources 32 | ) 33 | 34 | set_target_properties( 35 | cgeventtap-example 36 | PROPERTIES 37 | 38 | MACOSX_BUNDLE_INFO_PLIST 39 | ${CMAKE_CURRENT_LIST_DIR}/Resources/Info.plist 40 | 41 | XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME 42 | YES 43 | 44 | XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS 45 | "@loader_path @loader_path/../Frameworks" 46 | ) 47 | -------------------------------------------------------------------------------- /cgeventtap-example/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | mkdir -p build_xcode \ 3 | && cd build_xcode \ 4 | && cmake -G Xcode .. \ 5 | && xcodebuild -configuration Release SYMROOT="$(CURDIR)/build_xcode/build" 6 | 7 | clean: 8 | rm -rf build_xcode 9 | 10 | run: 11 | bash ../scripts/codesign.sh build_xcode/build/Release 12 | open build_xcode/build/Release/cgeventtap-example.app 13 | -------------------------------------------------------------------------------- /cgeventtap-example/README.md: -------------------------------------------------------------------------------- 1 | # cgeventtap-example 2 | 3 | ## Note 4 | 5 | - User must approve of Accessibility. 6 | - If the binary is not code signed, user must approve it anytime the binary is modified. 7 | -------------------------------------------------------------------------------- /cgeventtap-example/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /cgeventtap-example/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /cgeventtap-example/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | org.pqrs.osx-observer-examples.cgeventtap-example 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSMainNibFile 26 | MainMenu 27 | NSPrincipalClass 28 | NSApplication 29 | 30 | 31 | -------------------------------------------------------------------------------- /cgeventtap-example/src/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: objective-c -*- */ 2 | 3 | @import Cocoa; 4 | 5 | @interface AppDelegate : NSObject 6 | @end 7 | -------------------------------------------------------------------------------- /cgeventtap-example/src/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @interface AppDelegate () 4 | 5 | @property(weak) IBOutlet NSWindow* window; 6 | @property NSTimer* timer; 7 | 8 | @end 9 | 10 | @implementation AppDelegate 11 | 12 | - (void)applicationDidFinishLaunching:(NSNotification*)notification { 13 | self.window.level = NSFloatingWindowLevel; 14 | 15 | NSDictionary* options = @{(__bridge NSString*)(kAXTrustedCheckOptionPrompt) : @YES}; 16 | if (!AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)options)) { 17 | self.timer = [NSTimer scheduledTimerWithTimeInterval:3.0 18 | repeats:YES 19 | block:^(NSTimer* timer) { 20 | [self relaunchIfProcessTrusted]; 21 | }]; 22 | } 23 | } 24 | 25 | - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication { 26 | return YES; 27 | } 28 | 29 | - (void)relaunchIfProcessTrusted { 30 | if (AXIsProcessTrusted()) { 31 | [NSTask launchedTaskWithLaunchPath:[[NSBundle mainBundle] executablePath] arguments:@[]]; 32 | [NSApp terminate:nil]; 33 | } 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /cgeventtap-example/src/CGEventTapExample.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: objective-c -*- */ 2 | 3 | @import Cocoa; 4 | 5 | @interface CGEventTapExample : NSObject 6 | @end 7 | -------------------------------------------------------------------------------- /cgeventtap-example/src/CGEventTapExample.m: -------------------------------------------------------------------------------- 1 | #import "CGEventTapExample.h" 2 | @import CoreGraphics; 3 | 4 | @interface CGEventTapExample () 5 | 6 | @property(weak) IBOutlet NSTextField* text; 7 | @property NSMutableArray* eventStrings; 8 | @property NSUInteger counter; 9 | @property CFMachPortRef eventTap; 10 | 11 | - (CGEventRef)callback:(CGEventTapProxy)proxy 12 | type:(CGEventType)type 13 | event:(CGEventRef)event; 14 | 15 | @end 16 | 17 | static CGEventRef callback(CGEventTapProxy proxy, 18 | CGEventType type, 19 | CGEventRef event, 20 | void* refcon) { 21 | CGEventTapExample* p = (__bridge CGEventTapExample*)(refcon); 22 | 23 | if (p) { 24 | return [p callback:proxy 25 | type:type 26 | event:event]; 27 | } 28 | return NULL; 29 | } 30 | 31 | @implementation CGEventTapExample 32 | 33 | - (void)awakeFromNib { 34 | [super awakeFromNib]; 35 | 36 | self.eventStrings = [NSMutableArray new]; 37 | 38 | #if 1 39 | CGEventTapLocation location = kCGHIDEventTap; 40 | #else 41 | CGEventTapLocation location = kCGSessionEventTap; 42 | #endif 43 | 44 | CGEventMask mask = CGEventMaskBit(kCGEventKeyDown) | 45 | CGEventMaskBit(kCGEventKeyUp) | 46 | CGEventMaskBit(kCGEventFlagsChanged); 47 | 48 | self.eventTap = CGEventTapCreate(location, 49 | kCGTailAppendEventTap, 50 | kCGEventTapOptionListenOnly, 51 | mask, 52 | callback, 53 | (__bridge void*)(self)); 54 | 55 | CFRunLoopSourceRef source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, self.eventTap, 0); 56 | CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes); 57 | CFRelease(source); 58 | 59 | CGEventTapEnable(self.eventTap, true); 60 | } 61 | 62 | - (void)dealloc { 63 | if (self.eventTap) { 64 | CFRelease(self.eventTap); 65 | } 66 | } 67 | 68 | - (CGEventRef)callback:(CGEventTapProxy)proxy 69 | type:(CGEventType)type 70 | event:(CGEventRef)event { 71 | switch (type) { 72 | case kCGEventTapDisabledByTimeout: 73 | CGEventTapEnable(self.eventTap, true); 74 | break; 75 | 76 | case kCGEventKeyDown: 77 | [self updateEventStrings:[NSString stringWithFormat:@"keyDown %lld", 78 | CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode)]]; 79 | break; 80 | case kCGEventKeyUp: 81 | [self updateEventStrings:[NSString stringWithFormat:@"keyUp %lld", 82 | CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode)]]; 83 | break; 84 | 85 | case kCGEventFlagsChanged: 86 | [self updateEventStrings:[NSString stringWithFormat:@"flagsChanged 0x%llx", CGEventGetFlags(event)]]; 87 | break; 88 | 89 | default: 90 | break; 91 | } 92 | 93 | return event; 94 | } 95 | 96 | - (void)updateEventStrings:(NSString*)string { 97 | self.counter += 1; 98 | 99 | [self.eventStrings addObject:[NSString stringWithFormat:@"%06ld %@", self.counter, string]]; 100 | 101 | while (self.eventStrings.count > 16) { 102 | [self.eventStrings removeObjectAtIndex:0]; 103 | } 104 | 105 | self.text.stringValue = [self.eventStrings componentsJoinedByString:@"\n"]; 106 | } 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /cgeventtap-example/src/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | int main(int argc, const char* argv[]) { 4 | return NSApplicationMain(argc, (const char**)argv); 5 | } 6 | -------------------------------------------------------------------------------- /dist/osx-event-observer-examples.dmg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pqrs-org/osx-event-observer-examples/30419fa2bdd2cce09d1b03c2dacb829883869853/dist/osx-event-observer-examples.dmg -------------------------------------------------------------------------------- /docs/images/accessibility.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pqrs-org/osx-event-observer-examples/30419fa2bdd2cce09d1b03c2dacb829883869853/docs/images/accessibility.png -------------------------------------------------------------------------------- /docs/images/cgeventtap-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pqrs-org/osx-event-observer-examples/30419fa2bdd2cce09d1b03c2dacb829883869853/docs/images/cgeventtap-example.png -------------------------------------------------------------------------------- /docs/images/input-monitoring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pqrs-org/osx-event-observer-examples/30419fa2bdd2cce09d1b03c2dacb829883869853/docs/images/input-monitoring.png -------------------------------------------------------------------------------- /docs/images/iokit-hid-report-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pqrs-org/osx-event-observer-examples/30419fa2bdd2cce09d1b03c2dacb829883869853/docs/images/iokit-hid-report-example.png -------------------------------------------------------------------------------- /docs/images/iokit-hid-value-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pqrs-org/osx-event-observer-examples/30419fa2bdd2cce09d1b03c2dacb829883869853/docs/images/iokit-hid-value-example.png -------------------------------------------------------------------------------- /docs/images/nsapplication-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pqrs-org/osx-event-observer-examples/30419fa2bdd2cce09d1b03c2dacb829883869853/docs/images/nsapplication-example.png -------------------------------------------------------------------------------- /docs/images/nsevent-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pqrs-org/osx-event-observer-examples/30419fa2bdd2cce09d1b03c2dacb829883869853/docs/images/nsevent-example.png -------------------------------------------------------------------------------- /docs/images/nsview-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pqrs-org/osx-event-observer-examples/30419fa2bdd2cce09d1b03c2dacb829883869853/docs/images/nsview-example.png -------------------------------------------------------------------------------- /iokit-hid-report-example/.gitignore: -------------------------------------------------------------------------------- 1 | /build_xcode 2 | -------------------------------------------------------------------------------- /iokit-hid-report-example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.24 FATAL_ERROR) 2 | 3 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment version") 4 | set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for Mac OS X") 5 | 6 | project(iokit-hid-report-example) 7 | 8 | set(CMAKE_CXX_STANDARD 20) 9 | 10 | add_compile_options(-Wall) 11 | add_compile_options(-Werror) 12 | add_compile_options(-O2) 13 | add_compile_options(-fobjc-arc) 14 | 15 | include_directories(SYSTEM ${CMAKE_CURRENT_LIST_DIR}/../vendor/vendor/include) 16 | 17 | add_executable( 18 | iokit-hid-report-example 19 | MACOSX_BUNDLE 20 | src/AppDelegate.mm 21 | src/AppDelegate.h 22 | src/IOKitHIDReportExample.mm 23 | src/IOKitHIDReportExample.h 24 | src/main.m 25 | Resources/MainMenu.xib 26 | Resources/Assets.xcassets 27 | ) 28 | 29 | set_source_files_properties( 30 | Resources/MainMenu.xib 31 | Resources/Assets.xcassets 32 | PROPERTIES 33 | MACOSX_PACKAGE_LOCATION 34 | Resources 35 | ) 36 | 37 | set_target_properties( 38 | iokit-hid-report-example 39 | PROPERTIES 40 | 41 | MACOSX_BUNDLE_INFO_PLIST 42 | ${CMAKE_CURRENT_LIST_DIR}/Resources/Info.plist 43 | 44 | XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME 45 | YES 46 | 47 | XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS 48 | "@loader_path @loader_path/../Frameworks" 49 | ) 50 | 51 | target_link_libraries( 52 | iokit-hid-report-example 53 | "-framework Cocoa" 54 | "-framework IOKit" 55 | ) 56 | -------------------------------------------------------------------------------- /iokit-hid-report-example/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | mkdir -p build_xcode \ 3 | && cd build_xcode \ 4 | && cmake -G Xcode .. \ 5 | && xcodebuild -configuration Release SYMROOT="$(CURDIR)/build_xcode" 6 | 7 | clean: 8 | rm -rf build_xcode 9 | 10 | run: 11 | bash ../scripts/codesign.sh build_xcode/Release 12 | open build_xcode/Release/iokit-hid-report-example.app 13 | -------------------------------------------------------------------------------- /iokit-hid-report-example/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /iokit-hid-report-example/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iokit-hid-report-example/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | org.pqrs.osx-observer-examples.iokit-hid-report-example 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSMainNibFile 26 | MainMenu 27 | NSPrincipalClass 28 | NSApplication 29 | 30 | 31 | -------------------------------------------------------------------------------- /iokit-hid-report-example/src/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: objective-c -*- */ 2 | 3 | #import 4 | 5 | @interface AppDelegate : NSObject 6 | @end 7 | -------------------------------------------------------------------------------- /iokit-hid-report-example/src/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "IOKitHIDReportExample.h" 3 | #include 4 | #include 5 | 6 | @interface AppDelegate () 7 | 8 | @property(weak) IBOutlet NSWindow* window; 9 | @property(weak) IBOutlet IOKitHIDReportExample* iokitHIDReportExample; 10 | 11 | @end 12 | 13 | @implementation AppDelegate 14 | 15 | - (void)applicationDidFinishLaunching:(NSNotification*)notification { 16 | self.window.level = NSFloatingWindowLevel; 17 | 18 | pqrs::dispatcher::extra::initialize_shared_dispatcher(); 19 | pqrs::cf::run_loop_thread::extra::initialize_shared_run_loop_thread(); 20 | 21 | [self.iokitHIDReportExample initializeIOKitHIDReportExample]; 22 | } 23 | 24 | - (void)applicationWillTerminate:(NSNotification*)notification { 25 | [self.iokitHIDReportExample terminateIOKitHIDReportExample]; 26 | 27 | pqrs::cf::run_loop_thread::extra::terminate_shared_run_loop_thread(); 28 | pqrs::dispatcher::extra::terminate_shared_dispatcher(); 29 | } 30 | 31 | - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication { 32 | return YES; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /iokit-hid-report-example/src/IOKitHIDReportExample.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: objective-c -*- */ 2 | 3 | #import 4 | 5 | @interface IOKitHIDReportExample : NSObject 6 | 7 | - (void)initializeIOKitHIDReportExample; 8 | - (void)terminateIOKitHIDReportExample; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /iokit-hid-report-example/src/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | int main(int argc, const char* argv[]) { 4 | return NSApplicationMain(argc, (const char**)argv); 5 | } 6 | -------------------------------------------------------------------------------- /iokit-hid-value-example/.gitignore: -------------------------------------------------------------------------------- 1 | /build_xcode 2 | -------------------------------------------------------------------------------- /iokit-hid-value-example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.24 FATAL_ERROR) 2 | 3 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment version") 4 | set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for Mac OS X") 5 | 6 | project (iokit-hid-value-example) 7 | 8 | set(CMAKE_CXX_STANDARD 20) 9 | 10 | add_compile_options(-Wall) 11 | add_compile_options(-Werror) 12 | add_compile_options(-O2) 13 | add_compile_options(-fobjc-arc) 14 | 15 | include_directories(SYSTEM ${CMAKE_CURRENT_LIST_DIR}/../vendor/vendor/include) 16 | 17 | add_executable( 18 | iokit-hid-value-example 19 | MACOSX_BUNDLE 20 | src/AppDelegate.mm 21 | src/AppDelegate.h 22 | src/IOKitHIDValueExample.mm 23 | src/IOKitHIDValueExample.h 24 | src/main.m 25 | Resources/MainMenu.xib 26 | Resources/Assets.xcassets 27 | ) 28 | 29 | set_source_files_properties( 30 | Resources/MainMenu.xib 31 | Resources/Assets.xcassets 32 | PROPERTIES 33 | MACOSX_PACKAGE_LOCATION 34 | Resources 35 | ) 36 | 37 | set_target_properties( 38 | iokit-hid-value-example 39 | PROPERTIES 40 | 41 | MACOSX_BUNDLE_INFO_PLIST 42 | ${CMAKE_CURRENT_LIST_DIR}/Resources/Info.plist 43 | 44 | XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME 45 | YES 46 | 47 | XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS 48 | "@loader_path @loader_path/../Frameworks" 49 | ) 50 | 51 | target_link_libraries( 52 | iokit-hid-value-example 53 | "-framework Cocoa" 54 | "-framework IOKit" 55 | ) 56 | -------------------------------------------------------------------------------- /iokit-hid-value-example/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | mkdir -p build_xcode \ 3 | && cd build_xcode \ 4 | && cmake -G Xcode .. \ 5 | && xcodebuild -configuration Release SYMROOT="$(CURDIR)/build_xcode" 6 | 7 | clean: 8 | rm -rf build_xcode 9 | 10 | run: 11 | bash ../scripts/codesign.sh build_xcode/Release 12 | open build_xcode/Release/iokit-hid-value-example.app 13 | -------------------------------------------------------------------------------- /iokit-hid-value-example/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /iokit-hid-value-example/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /iokit-hid-value-example/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | org.pqrs.osx-observer-examples.iokit-hid-value-example 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSMainNibFile 26 | MainMenu 27 | NSPrincipalClass 28 | NSApplication 29 | 30 | 31 | -------------------------------------------------------------------------------- /iokit-hid-value-example/src/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: objective-c -*- */ 2 | 3 | #import 4 | 5 | @interface AppDelegate : NSObject 6 | @end 7 | -------------------------------------------------------------------------------- /iokit-hid-value-example/src/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "IOKitHIDValueExample.h" 3 | #include 4 | #include 5 | 6 | @interface AppDelegate () 7 | 8 | @property(weak) IBOutlet NSWindow* window; 9 | @property(weak) IBOutlet IOKitHIDValueExample* iokitHIDValueExample; 10 | 11 | @end 12 | 13 | @implementation AppDelegate 14 | 15 | - (void)applicationDidFinishLaunching:(NSNotification*)notification { 16 | self.window.level = NSFloatingWindowLevel; 17 | 18 | pqrs::dispatcher::extra::initialize_shared_dispatcher(); 19 | pqrs::cf::run_loop_thread::extra::initialize_shared_run_loop_thread(); 20 | 21 | [self.iokitHIDValueExample initializeIOKitHIDValueExample]; 22 | } 23 | 24 | - (void)applicationWillTerminate:(NSNotification*)notification { 25 | [self.iokitHIDValueExample terminateIOKitHIDValueExample]; 26 | 27 | pqrs::cf::run_loop_thread::extra::terminate_shared_run_loop_thread(); 28 | pqrs::dispatcher::extra::terminate_shared_dispatcher(); 29 | } 30 | 31 | - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication { 32 | return YES; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /iokit-hid-value-example/src/IOKitHIDValueExample.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: objective-c -*- */ 2 | 3 | #import 4 | 5 | @interface IOKitHIDValueExample : NSObject 6 | 7 | - (void)initializeIOKitHIDValueExample; 8 | - (void)terminateIOKitHIDValueExample; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /iokit-hid-value-example/src/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | int main(int argc, const char* argv[]) { 4 | return NSApplicationMain(argc, (const char**)argv); 5 | } 6 | -------------------------------------------------------------------------------- /nsapplication-example/.gitignore: -------------------------------------------------------------------------------- 1 | /build_xcode 2 | -------------------------------------------------------------------------------- /nsapplication-example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.24 FATAL_ERROR) 2 | 3 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment version") 4 | set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for Mac OS X") 5 | 6 | project(nsapplication-example) 7 | enable_language(Swift) 8 | 9 | add_compile_options(-O2) 10 | 11 | add_executable( 12 | nsapplication-example 13 | MACOSX_BUNDLE 14 | src/AppDelegate.swift 15 | src/ExampleApplication.swift 16 | Resources/MainMenu.xib 17 | Resources/Assets.xcassets 18 | ) 19 | 20 | set_source_files_properties( 21 | Resources/MainMenu.xib 22 | Resources/Assets.xcassets 23 | PROPERTIES 24 | MACOSX_PACKAGE_LOCATION 25 | Resources 26 | ) 27 | 28 | set_target_properties( 29 | nsapplication-example 30 | PROPERTIES 31 | 32 | MACOSX_BUNDLE_INFO_PLIST 33 | ${CMAKE_CURRENT_LIST_DIR}/Resources/Info.plist 34 | 35 | XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME 36 | YES 37 | 38 | XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS 39 | "@loader_path @loader_path/../Frameworks" 40 | ) 41 | -------------------------------------------------------------------------------- /nsapplication-example/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | mkdir -p build_xcode \ 3 | && cd build_xcode \ 4 | && cmake -G Xcode .. \ 5 | && xcodebuild -configuration Release SYMROOT="$(CURDIR)/build_xcode/build" 6 | 7 | clean: 8 | rm -rf build_xcode 9 | 10 | run: 11 | bash ../scripts/codesign.sh build_xcode/build/Release 12 | open build_xcode/build/Release/nsapplication-example.app 13 | -------------------------------------------------------------------------------- /nsapplication-example/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /nsapplication-example/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /nsapplication-example/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | org.pqrs.osx-observer-examples.nsapplication-example 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSMainNibFile 26 | MainMenu 27 | NSPrincipalClass 28 | ExampleApplication 29 | 30 | 31 | -------------------------------------------------------------------------------- /nsapplication-example/src/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | @NSApplicationMain 4 | class AppDelegate: NSObject, NSApplicationDelegate { 5 | @IBOutlet var window: NSWindow! 6 | 7 | func applicationDidFinishLaunching(_: Notification) { 8 | window.level = NSWindow.Level.floating 9 | } 10 | 11 | func applicationWillTerminate(_: Notification) {} 12 | 13 | func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool { 14 | return true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /nsapplication-example/src/ExampleApplication.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | @objc(ExampleApplication) 4 | class ExampleApplication: NSApplication { 5 | @IBOutlet private var text: NSTextField! 6 | private var eventStrings: [String] = [] 7 | private var counter: UInt64 = 0 8 | 9 | override func sendEvent(_ event: NSEvent) { 10 | switch event.type { 11 | case .keyDown: 12 | updateEventStrings(String(format: "keyDown %d", event.keyCode)) 13 | case .keyUp: 14 | updateEventStrings(String(format: "keyUp %d", event.keyCode)) 15 | case .flagsChanged: 16 | updateEventStrings(String(format: "flagsChanged %d", event.keyCode)) 17 | default: 18 | break 19 | } 20 | 21 | super.sendEvent(event) 22 | } 23 | 24 | private func updateEventStrings(_ string: String) { 25 | counter += 1 26 | eventStrings.append(String(format: "%06d %@", counter, string)) 27 | 28 | while eventStrings.count > 16 { 29 | eventStrings.remove(at: 0) 30 | } 31 | 32 | text.stringValue = eventStrings.joined(separator: "\n") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /nsevent-example/.gitignore: -------------------------------------------------------------------------------- 1 | /build_xcode 2 | -------------------------------------------------------------------------------- /nsevent-example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.24 FATAL_ERROR) 2 | 3 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment version") 4 | set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for Mac OS X") 5 | 6 | project(nsevent-example) 7 | enable_language(Swift) 8 | 9 | add_compile_options(-O2) 10 | 11 | add_executable( 12 | nsevent-example 13 | MACOSX_BUNDLE 14 | src/AppDelegate.swift 15 | Resources/MainMenu.xib 16 | Resources/Assets.xcassets 17 | ) 18 | 19 | set_source_files_properties( 20 | Resources/MainMenu.xib 21 | Resources/Assets.xcassets 22 | PROPERTIES 23 | MACOSX_PACKAGE_LOCATION 24 | Resources 25 | ) 26 | 27 | set_target_properties( 28 | nsevent-example 29 | PROPERTIES 30 | 31 | MACOSX_BUNDLE_INFO_PLIST 32 | ${CMAKE_CURRENT_LIST_DIR}/Resources/Info.plist 33 | 34 | XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME 35 | YES 36 | 37 | XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS 38 | "@loader_path @loader_path/../Frameworks" 39 | ) 40 | -------------------------------------------------------------------------------- /nsevent-example/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | mkdir -p build_xcode \ 3 | && cd build_xcode \ 4 | && cmake -G Xcode .. \ 5 | && xcodebuild -configuration Release SYMROOT="$(CURDIR)/build_xcode/build" 6 | 7 | clean: 8 | rm -rf build_xcode 9 | 10 | run: 11 | bash ../scripts/codesign.sh build_xcode/build/Release 12 | open build_xcode/build/Release/nsevent-example.app 13 | -------------------------------------------------------------------------------- /nsevent-example/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /nsevent-example/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /nsevent-example/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | org.pqrs.osx-observer-examples.nsevent-example 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSMainNibFile 26 | MainMenu 27 | NSPrincipalClass 28 | NSApplication 29 | 30 | 31 | -------------------------------------------------------------------------------- /nsevent-example/src/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | @NSApplicationMain 4 | class AppDelegate: NSObject, NSApplicationDelegate { 5 | @IBOutlet var window: NSWindow! 6 | @IBOutlet private var text: NSTextField! 7 | private var timer: Timer? 8 | private var eventStrings: [String] = [] 9 | private var counter: UInt64 = 0 10 | 11 | func applicationDidFinishLaunching(_: Notification) { 12 | window.level = NSWindow.Level.floating 13 | 14 | let options: NSDictionary = [kAXTrustedCheckOptionPrompt.takeRetainedValue() as NSString: true] 15 | if !AXIsProcessTrustedWithOptions(options) { 16 | timer = Timer.scheduledTimer( 17 | withTimeInterval: 3.0, 18 | repeats: true 19 | ) { _ in self.relaunchIfProcessTrusted() } 20 | } 21 | 22 | NSEvent.addGlobalMonitorForEvents( 23 | matching: [NSEvent.EventTypeMask.keyDown, NSEvent.EventTypeMask.keyUp, NSEvent.EventTypeMask.flagsChanged], 24 | handler: { (event: NSEvent) in 25 | switch event.type { 26 | case .keyDown: 27 | self.updateEventStrings(String(format: "keyDown %d", event.keyCode)) 28 | case .keyUp: 29 | self.updateEventStrings(String(format: "keyUp %d", event.keyCode)) 30 | case .flagsChanged: 31 | self.updateEventStrings(String(format: "flagsChanged %d", event.keyCode)) 32 | default: 33 | break 34 | } 35 | } 36 | ) 37 | } 38 | 39 | func applicationWillTerminate(_: Notification) {} 40 | 41 | func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool { 42 | return true 43 | } 44 | 45 | private func relaunchIfProcessTrusted() { 46 | if AXIsProcessTrusted() { 47 | let task = Process() 48 | task.executableURL = URL(fileURLWithPath: Bundle.main.executablePath!) 49 | try! task.run() 50 | NSApplication.shared.terminate(self) 51 | } 52 | } 53 | 54 | private func updateEventStrings(_ string: String) { 55 | counter += 1 56 | eventStrings.append(String(format: "%06d %@", counter, string)) 57 | 58 | while eventStrings.count > 16 { 59 | eventStrings.remove(at: 0) 60 | } 61 | 62 | text.stringValue = eventStrings.joined(separator: "\n") 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /nsview-example/.gitignore: -------------------------------------------------------------------------------- 1 | /build_xcode 2 | -------------------------------------------------------------------------------- /nsview-example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.24 FATAL_ERROR) 2 | 3 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment version") 4 | set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for Mac OS X") 5 | 6 | project(nsview-example) 7 | enable_language(Swift) 8 | 9 | add_compile_options(-O2) 10 | 11 | add_executable( 12 | nsview-example 13 | MACOSX_BUNDLE 14 | src/AppDelegate.swift 15 | src/ExampleView.swift 16 | Resources/MainMenu.xib 17 | Resources/Assets.xcassets 18 | ) 19 | 20 | set_source_files_properties( 21 | Resources/MainMenu.xib 22 | Resources/Assets.xcassets 23 | PROPERTIES 24 | MACOSX_PACKAGE_LOCATION 25 | Resources 26 | ) 27 | 28 | set_target_properties( 29 | nsview-example 30 | PROPERTIES 31 | 32 | MACOSX_BUNDLE_INFO_PLIST 33 | ${CMAKE_CURRENT_LIST_DIR}/Resources/Info.plist 34 | 35 | XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME 36 | YES 37 | 38 | XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS 39 | "@loader_path @loader_path/../Frameworks" 40 | ) 41 | -------------------------------------------------------------------------------- /nsview-example/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | mkdir -p build_xcode \ 3 | && cd build_xcode \ 4 | && cmake -G Xcode .. \ 5 | && xcodebuild -configuration Release SYMROOT="$(CURDIR)/build_xcode/build" 6 | 7 | clean: 8 | rm -rf build_xcode 9 | 10 | run: 11 | bash ../scripts/codesign.sh build_xcode/build/Release 12 | open build_xcode/build/Release/nsview-example.app 13 | -------------------------------------------------------------------------------- /nsview-example/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /nsview-example/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /nsview-example/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | org.pqrs.osx-observer-examples.nsview-example 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSMainNibFile 26 | MainMenu 27 | NSPrincipalClass 28 | NSApplication 29 | 30 | 31 | -------------------------------------------------------------------------------- /nsview-example/src/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | @NSApplicationMain 4 | class AppDelegate: NSObject, NSApplicationDelegate { 5 | @IBOutlet var window: NSWindow! 6 | 7 | func applicationDidFinishLaunching(_: Notification) { 8 | window.level = NSWindow.Level.floating 9 | } 10 | 11 | func applicationWillTerminate(_: Notification) {} 12 | 13 | func applicationShouldTerminateAfterLastWindowClosed(_: NSApplication) -> Bool { 14 | return true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /nsview-example/src/ExampleView.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | 3 | class ExampleView: NSView { 4 | @IBOutlet private var text: NSTextField! 5 | private var eventStrings: [String] = [] 6 | private var counter: UInt64 = 0 7 | 8 | override var acceptsFirstResponder: Bool { return true } 9 | 10 | override func keyDown(with event: NSEvent) { 11 | updateEventStrings(String(format: "keyDown %d", event.keyCode)) 12 | } 13 | 14 | override func keyUp(with event: NSEvent) { 15 | updateEventStrings(String(format: "keyUp %d", event.keyCode)) 16 | } 17 | 18 | override func flagsChanged(with event: NSEvent) { 19 | updateEventStrings(String(format: "flagsChanged %d", event.keyCode)) 20 | } 21 | 22 | private func updateEventStrings(_ string: String) { 23 | counter += 1 24 | eventStrings.append(String(format: "%06d %@", counter, string)) 25 | 26 | while eventStrings.count > 16 { 27 | eventStrings.remove(at: 0) 28 | } 29 | 30 | text.stringValue = eventStrings.joined(separator: "\n") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /scripts/codesign.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -u # forbid undefined variables 4 | set -e # forbid command failure 5 | 6 | readonly PATH=/bin:/sbin:/usr/bin:/usr/sbin 7 | export PATH 8 | 9 | readonly CODE_SIGN_IDENTITY=$(bash $(dirname $0)/get-codesign-identity.sh) 10 | 11 | if [[ -z $CODE_SIGN_IDENTITY ]]; then 12 | echo "Skip codesign" 13 | exit 0 14 | fi 15 | 16 | # 17 | # Define err() 18 | # 19 | 20 | err() { 21 | echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@" >&2 22 | } 23 | 24 | # 25 | # Define main() 26 | # 27 | 28 | main() { 29 | if [[ ! -e "$1" ]]; then 30 | err "Invalid argument: '$1'" 31 | exit 1 32 | fi 33 | 34 | # 35 | # Sign with codesign 36 | # 37 | 38 | cd "$1" 39 | find * -name '*.app' -or -path '*/bin/*' | sort -r | while read f; do 40 | # 41 | # output message 42 | # 43 | 44 | echo -ne '\033[33;40m' 45 | echo "code sign $f" 46 | echo -ne '\033[0m' 47 | 48 | # 49 | # codesign 50 | # 51 | 52 | echo -ne '\033[31;40m' 53 | 54 | set +e # allow command failure 55 | 56 | codesign \ 57 | --force \ 58 | --deep \ 59 | --options runtime \ 60 | --sign "$CODE_SIGN_IDENTITY" \ 61 | "$f" 2>&1 | 62 | grep -v ': replacing existing signature' 63 | 64 | set -e # forbid command failure 65 | 66 | echo -ne '\033[0m' 67 | done 68 | 69 | # 70 | # Verify codesign 71 | # 72 | 73 | find * -name '*.app' -or -path '*/bin/*' | sort -r | while read f; do 74 | echo -ne '\033[31;40m' 75 | codesign --verify --deep "$f" 76 | echo -ne '\033[0m' 77 | done 78 | } 79 | 80 | # 81 | # Run 82 | # 83 | 84 | main "$1" 85 | -------------------------------------------------------------------------------- /scripts/get-codesign-identity.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -u # forbid undefined variables 4 | set -e # forbid command failure 5 | 6 | readonly PATH=/bin:/sbin:/usr/bin:/usr/sbin 7 | export PATH 8 | 9 | if [[ -n "${PQRS_ORG_CODE_SIGN_IDENTITY:-}" ]]; then 10 | if security find-identity -p codesigning -v | grep -q ") $PQRS_ORG_CODE_SIGN_IDENTITY \""; then 11 | echo $PQRS_ORG_CODE_SIGN_IDENTITY 12 | exit 0 13 | fi 14 | fi 15 | 16 | echo 17 | -------------------------------------------------------------------------------- /vendor/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | -------------------------------------------------------------------------------- /vendor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.24 FATAL_ERROR) 2 | project(vendor NONE) 3 | 4 | include("${CMAKE_CURRENT_LIST_DIR}/cpm-cmake-package-lock/vendor/CPM.cmake") 5 | 6 | CPMUsePackageLock("${CMAKE_CURRENT_LIST_DIR}/cpm-cmake-package-lock/cmake/package-lock.cmake") 7 | 8 | set(VENDOR_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/vendor") 9 | file(MAKE_DIRECTORY "${VENDOR_INCLUDE_DIR}") 10 | 11 | include("${CMAKE_CURRENT_LIST_DIR}/cpm-cmake-package-lock/cmake/common.cmake") 12 | include("${CMAKE_CURRENT_LIST_DIR}/cpm-cmake-package-lock/cmake/dependency.cmake") 13 | 14 | copy_vendor_package(pqrs_osx_iokit_hid_device_report_monitor) 15 | copy_vendor_package(pqrs_osx_iokit_hid_manager) 16 | copy_vendor_package(pqrs_osx_iokit_hid_manager) 17 | copy_vendor_package(pqrs_osx_iokit_hid_queue_value_monitor) 18 | copy_vendor_package(pqrs_osx_iokit_hid_value) 19 | copy_vendor_package(pqrs_weakify) 20 | -------------------------------------------------------------------------------- /vendor/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | rm -fr vendor 3 | cmake -S . -B build 4 | cmake --build build 5 | 6 | clean: 7 | rm -fr build vendor 8 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/adl_serializer.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | NLOHMANN_JSON_NAMESPACE_BEGIN 19 | 20 | /// @sa https://json.nlohmann.me/api/adl_serializer/ 21 | template 22 | struct adl_serializer 23 | { 24 | /// @brief convert a JSON value to any value type 25 | /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/ 26 | template 27 | static auto from_json(BasicJsonType && j, TargetType& val) noexcept( 28 | noexcept(::nlohmann::from_json(std::forward(j), val))) 29 | -> decltype(::nlohmann::from_json(std::forward(j), val), void()) 30 | { 31 | ::nlohmann::from_json(std::forward(j), val); 32 | } 33 | 34 | /// @brief convert a JSON value to any value type 35 | /// @sa https://json.nlohmann.me/api/adl_serializer/from_json/ 36 | template 37 | static auto from_json(BasicJsonType && j) noexcept( 38 | noexcept(::nlohmann::from_json(std::forward(j), detail::identity_tag {}))) 39 | -> decltype(::nlohmann::from_json(std::forward(j), detail::identity_tag {})) 40 | { 41 | return ::nlohmann::from_json(std::forward(j), detail::identity_tag {}); 42 | } 43 | 44 | /// @brief convert any value type to a JSON value 45 | /// @sa https://json.nlohmann.me/api/adl_serializer/to_json/ 46 | template 47 | static auto to_json(BasicJsonType& j, TargetType && val) noexcept( 48 | noexcept(::nlohmann::to_json(j, std::forward(val)))) 49 | -> decltype(::nlohmann::to_json(j, std::forward(val)), void()) 50 | { 51 | ::nlohmann::to_json(j, std::forward(val)); 52 | } 53 | }; 54 | 55 | NLOHMANN_JSON_NAMESPACE_END 56 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/byte_container_with_subtype.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include // uint8_t, uint64_t 12 | #include // tie 13 | #include // move 14 | 15 | #include 16 | 17 | NLOHMANN_JSON_NAMESPACE_BEGIN 18 | 19 | /// @brief an internal type for a backed binary type 20 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/ 21 | template 22 | class byte_container_with_subtype : public BinaryType 23 | { 24 | public: 25 | using container_type = BinaryType; 26 | using subtype_type = std::uint64_t; 27 | 28 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ 29 | byte_container_with_subtype() noexcept(noexcept(container_type())) 30 | : container_type() 31 | {} 32 | 33 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ 34 | byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b))) 35 | : container_type(b) 36 | {} 37 | 38 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ 39 | byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b)))) 40 | : container_type(std::move(b)) 41 | {} 42 | 43 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ 44 | byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b))) 45 | : container_type(b) 46 | , m_subtype(subtype_) 47 | , m_has_subtype(true) 48 | {} 49 | 50 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/byte_container_with_subtype/ 51 | byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b)))) 52 | : container_type(std::move(b)) 53 | , m_subtype(subtype_) 54 | , m_has_subtype(true) 55 | {} 56 | 57 | bool operator==(const byte_container_with_subtype& rhs) const 58 | { 59 | return std::tie(static_cast(*this), m_subtype, m_has_subtype) == 60 | std::tie(static_cast(rhs), rhs.m_subtype, rhs.m_has_subtype); 61 | } 62 | 63 | bool operator!=(const byte_container_with_subtype& rhs) const 64 | { 65 | return !(rhs == *this); 66 | } 67 | 68 | /// @brief sets the binary subtype 69 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/set_subtype/ 70 | void set_subtype(subtype_type subtype_) noexcept 71 | { 72 | m_subtype = subtype_; 73 | m_has_subtype = true; 74 | } 75 | 76 | /// @brief return the binary subtype 77 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/subtype/ 78 | constexpr subtype_type subtype() const noexcept 79 | { 80 | return m_has_subtype ? m_subtype : static_cast(-1); 81 | } 82 | 83 | /// @brief return whether the value has a subtype 84 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/has_subtype/ 85 | constexpr bool has_subtype() const noexcept 86 | { 87 | return m_has_subtype; 88 | } 89 | 90 | /// @brief clears the binary subtype 91 | /// @sa https://json.nlohmann.me/api/byte_container_with_subtype/clear_subtype/ 92 | void clear_subtype() noexcept 93 | { 94 | m_subtype = 0; 95 | m_has_subtype = false; 96 | } 97 | 98 | private: 99 | subtype_type m_subtype = 0; 100 | bool m_has_subtype = false; 101 | }; 102 | 103 | NLOHMANN_JSON_NAMESPACE_END 104 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/input/position_t.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include // size_t 12 | 13 | #include 14 | 15 | NLOHMANN_JSON_NAMESPACE_BEGIN 16 | namespace detail 17 | { 18 | 19 | /// struct to capture the start position of the current token 20 | struct position_t 21 | { 22 | /// the total number of characters read 23 | std::size_t chars_read_total = 0; 24 | /// the number of characters read in the current line 25 | std::size_t chars_read_current_line = 0; 26 | /// the number of lines read 27 | std::size_t lines_read = 0; 28 | 29 | /// conversion to size_t to preserve SAX interface 30 | constexpr operator size_t() const 31 | { 32 | return chars_read_total; 33 | } 34 | }; 35 | 36 | } // namespace detail 37 | NLOHMANN_JSON_NAMESPACE_END 38 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/iterators/internal_iterator.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | NLOHMANN_JSON_NAMESPACE_BEGIN 15 | namespace detail 16 | { 17 | 18 | /*! 19 | @brief an iterator value 20 | 21 | @note This structure could easily be a union, but MSVC currently does not allow 22 | unions members with complex constructors, see https://github.com/nlohmann/json/pull/105. 23 | */ 24 | template struct internal_iterator 25 | { 26 | /// iterator for JSON objects 27 | typename BasicJsonType::object_t::iterator object_iterator {}; 28 | /// iterator for JSON arrays 29 | typename BasicJsonType::array_t::iterator array_iterator {}; 30 | /// generic iterator for all other types 31 | primitive_iterator_t primitive_iterator {}; 32 | }; 33 | 34 | } // namespace detail 35 | NLOHMANN_JSON_NAMESPACE_END 36 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/iterators/iterator_traits.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include // random_access_iterator_tag 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | NLOHMANN_JSON_NAMESPACE_BEGIN 18 | namespace detail 19 | { 20 | 21 | template 22 | struct iterator_types {}; 23 | 24 | template 25 | struct iterator_types < 26 | It, 27 | void_t> 29 | { 30 | using difference_type = typename It::difference_type; 31 | using value_type = typename It::value_type; 32 | using pointer = typename It::pointer; 33 | using reference = typename It::reference; 34 | using iterator_category = typename It::iterator_category; 35 | }; 36 | 37 | // This is required as some compilers implement std::iterator_traits in a way that 38 | // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. 39 | template 40 | struct iterator_traits 41 | { 42 | }; 43 | 44 | template 45 | struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> 46 | : iterator_types 47 | { 48 | }; 49 | 50 | template 51 | struct iterator_traits::value>> 52 | { 53 | using iterator_category = std::random_access_iterator_tag; 54 | using value_type = T; 55 | using difference_type = ptrdiff_t; 56 | using pointer = T*; 57 | using reference = T&; 58 | }; 59 | 60 | } // namespace detail 61 | NLOHMANN_JSON_NAMESPACE_END 62 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/iterators/json_reverse_iterator.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include // ptrdiff_t 12 | #include // reverse_iterator 13 | #include // declval 14 | 15 | #include 16 | 17 | NLOHMANN_JSON_NAMESPACE_BEGIN 18 | namespace detail 19 | { 20 | 21 | ////////////////////// 22 | // reverse_iterator // 23 | ////////////////////// 24 | 25 | /*! 26 | @brief a template for a reverse iterator class 27 | 28 | @tparam Base the base iterator type to reverse. Valid types are @ref 29 | iterator (to create @ref reverse_iterator) and @ref const_iterator (to 30 | create @ref const_reverse_iterator). 31 | 32 | @requirement The class satisfies the following concept requirements: 33 | - 34 | [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): 35 | The iterator that can be moved can be moved in both directions (i.e. 36 | incremented and decremented). 37 | - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator): 38 | It is possible to write to the pointed-to element (only if @a Base is 39 | @ref iterator). 40 | 41 | @since version 1.0.0 42 | */ 43 | template 44 | class json_reverse_iterator : public std::reverse_iterator 45 | { 46 | public: 47 | using difference_type = std::ptrdiff_t; 48 | /// shortcut to the reverse iterator adapter 49 | using base_iterator = std::reverse_iterator; 50 | /// the reference type for the pointed-to element 51 | using reference = typename Base::reference; 52 | 53 | /// create reverse iterator from iterator 54 | explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept 55 | : base_iterator(it) {} 56 | 57 | /// create reverse iterator from base class 58 | explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {} 59 | 60 | /// post-increment (it++) 61 | json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp) 62 | { 63 | return static_cast(base_iterator::operator++(1)); 64 | } 65 | 66 | /// pre-increment (++it) 67 | json_reverse_iterator& operator++() 68 | { 69 | return static_cast(base_iterator::operator++()); 70 | } 71 | 72 | /// post-decrement (it--) 73 | json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp) 74 | { 75 | return static_cast(base_iterator::operator--(1)); 76 | } 77 | 78 | /// pre-decrement (--it) 79 | json_reverse_iterator& operator--() 80 | { 81 | return static_cast(base_iterator::operator--()); 82 | } 83 | 84 | /// add to iterator 85 | json_reverse_iterator& operator+=(difference_type i) 86 | { 87 | return static_cast(base_iterator::operator+=(i)); 88 | } 89 | 90 | /// add to iterator 91 | json_reverse_iterator operator+(difference_type i) const 92 | { 93 | return static_cast(base_iterator::operator+(i)); 94 | } 95 | 96 | /// subtract from iterator 97 | json_reverse_iterator operator-(difference_type i) const 98 | { 99 | return static_cast(base_iterator::operator-(i)); 100 | } 101 | 102 | /// return difference 103 | difference_type operator-(const json_reverse_iterator& other) const 104 | { 105 | return base_iterator(*this) - base_iterator(other); 106 | } 107 | 108 | /// access to successor 109 | reference operator[](difference_type n) const 110 | { 111 | return *(this->operator+(n)); 112 | } 113 | 114 | /// return the key of an object iterator 115 | auto key() const -> decltype(std::declval().key()) 116 | { 117 | auto it = --this->base(); 118 | return it.key(); 119 | } 120 | 121 | /// return the value of an iterator 122 | reference value() const 123 | { 124 | auto it = --this->base(); 125 | return it.operator * (); 126 | } 127 | }; 128 | 129 | } // namespace detail 130 | NLOHMANN_JSON_NAMESPACE_END 131 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/iterators/primitive_iterator.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include // ptrdiff_t 12 | #include // numeric_limits 13 | 14 | #include 15 | 16 | NLOHMANN_JSON_NAMESPACE_BEGIN 17 | namespace detail 18 | { 19 | 20 | /* 21 | @brief an iterator for primitive JSON types 22 | 23 | This class models an iterator for primitive JSON types (boolean, number, 24 | string). It's only purpose is to allow the iterator/const_iterator classes 25 | to "iterate" over primitive values. Internally, the iterator is modeled by 26 | a `difference_type` variable. Value begin_value (`0`) models the begin, 27 | end_value (`1`) models past the end. 28 | */ 29 | class primitive_iterator_t 30 | { 31 | private: 32 | using difference_type = std::ptrdiff_t; 33 | static constexpr difference_type begin_value = 0; 34 | static constexpr difference_type end_value = begin_value + 1; 35 | 36 | JSON_PRIVATE_UNLESS_TESTED: 37 | /// iterator as signed integer type 38 | difference_type m_it = (std::numeric_limits::min)(); 39 | 40 | public: 41 | constexpr difference_type get_value() const noexcept 42 | { 43 | return m_it; 44 | } 45 | 46 | /// set iterator to a defined beginning 47 | void set_begin() noexcept 48 | { 49 | m_it = begin_value; 50 | } 51 | 52 | /// set iterator to a defined past the end 53 | void set_end() noexcept 54 | { 55 | m_it = end_value; 56 | } 57 | 58 | /// return whether the iterator can be dereferenced 59 | constexpr bool is_begin() const noexcept 60 | { 61 | return m_it == begin_value; 62 | } 63 | 64 | /// return whether the iterator is at end 65 | constexpr bool is_end() const noexcept 66 | { 67 | return m_it == end_value; 68 | } 69 | 70 | friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept 71 | { 72 | return lhs.m_it == rhs.m_it; 73 | } 74 | 75 | friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept 76 | { 77 | return lhs.m_it < rhs.m_it; 78 | } 79 | 80 | primitive_iterator_t operator+(difference_type n) noexcept 81 | { 82 | auto result = *this; 83 | result += n; 84 | return result; 85 | } 86 | 87 | friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept 88 | { 89 | return lhs.m_it - rhs.m_it; 90 | } 91 | 92 | primitive_iterator_t& operator++() noexcept 93 | { 94 | ++m_it; 95 | return *this; 96 | } 97 | 98 | primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp) 99 | { 100 | auto result = *this; 101 | ++m_it; 102 | return result; 103 | } 104 | 105 | primitive_iterator_t& operator--() noexcept 106 | { 107 | --m_it; 108 | return *this; 109 | } 110 | 111 | primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp) 112 | { 113 | auto result = *this; 114 | --m_it; 115 | return result; 116 | } 117 | 118 | primitive_iterator_t& operator+=(difference_type n) noexcept 119 | { 120 | m_it += n; 121 | return *this; 122 | } 123 | 124 | primitive_iterator_t& operator-=(difference_type n) noexcept 125 | { 126 | m_it -= n; 127 | return *this; 128 | } 129 | }; 130 | 131 | } // namespace detail 132 | NLOHMANN_JSON_NAMESPACE_END 133 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/json_custom_base_class.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include // conditional, is_same 12 | 13 | #include 14 | 15 | NLOHMANN_JSON_NAMESPACE_BEGIN 16 | namespace detail 17 | { 18 | 19 | /*! 20 | @brief Default base class of the @ref basic_json class. 21 | 22 | So that the correct implementations of the copy / move ctors / assign operators 23 | of @ref basic_json do not require complex case distinctions 24 | (no base class / custom base class used as customization point), 25 | @ref basic_json always has a base class. 26 | By default, this class is used because it is empty and thus has no effect 27 | on the behavior of @ref basic_json. 28 | */ 29 | struct json_default_base {}; 30 | 31 | template 32 | using json_base_class = typename std::conditional < 33 | std::is_same::value, 34 | json_default_base, 35 | T 36 | >::type; 37 | 38 | } // namespace detail 39 | NLOHMANN_JSON_NAMESPACE_END 40 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/json_ref.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | NLOHMANN_JSON_NAMESPACE_BEGIN 18 | namespace detail 19 | { 20 | 21 | template 22 | class json_ref 23 | { 24 | public: 25 | using value_type = BasicJsonType; 26 | 27 | json_ref(value_type&& value) 28 | : owned_value(std::move(value)) 29 | {} 30 | 31 | json_ref(const value_type& value) 32 | : value_ref(&value) 33 | {} 34 | 35 | json_ref(std::initializer_list init) 36 | : owned_value(init) 37 | {} 38 | 39 | template < 40 | class... Args, 41 | enable_if_t::value, int> = 0 > 42 | json_ref(Args && ... args) 43 | : owned_value(std::forward(args)...) 44 | {} 45 | 46 | // class should be movable only 47 | json_ref(json_ref&&) noexcept = default; 48 | json_ref(const json_ref&) = delete; 49 | json_ref& operator=(const json_ref&) = delete; 50 | json_ref& operator=(json_ref&&) = delete; 51 | ~json_ref() = default; 52 | 53 | value_type moved_or_copied() const 54 | { 55 | if (value_ref == nullptr) 56 | { 57 | return std::move(owned_value); 58 | } 59 | return *value_ref; 60 | } 61 | 62 | value_type const& operator*() const 63 | { 64 | return value_ref ? *value_ref : owned_value; 65 | } 66 | 67 | value_type const* operator->() const 68 | { 69 | return &** this; 70 | } 71 | 72 | private: 73 | mutable value_type owned_value = nullptr; 74 | value_type const* value_ref = nullptr; 75 | }; 76 | 77 | } // namespace detail 78 | NLOHMANN_JSON_NAMESPACE_END 79 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/macro_unscope.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | // restore clang diagnostic settings 12 | #if defined(__clang__) 13 | #pragma clang diagnostic pop 14 | #endif 15 | 16 | // clean up 17 | #undef JSON_ASSERT 18 | #undef JSON_INTERNAL_CATCH 19 | #undef JSON_THROW 20 | #undef JSON_PRIVATE_UNLESS_TESTED 21 | #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION 22 | #undef NLOHMANN_BASIC_JSON_TPL 23 | #undef JSON_EXPLICIT 24 | #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL 25 | #undef JSON_INLINE_VARIABLE 26 | #undef JSON_NO_UNIQUE_ADDRESS 27 | #undef JSON_DISABLE_ENUM_SERIALIZATION 28 | #undef JSON_USE_GLOBAL_UDLS 29 | 30 | #ifndef JSON_TEST_KEEP_MACROS 31 | #undef JSON_CATCH 32 | #undef JSON_TRY 33 | #undef JSON_HAS_CPP_11 34 | #undef JSON_HAS_CPP_14 35 | #undef JSON_HAS_CPP_17 36 | #undef JSON_HAS_CPP_20 37 | #undef JSON_HAS_CPP_23 38 | #undef JSON_HAS_FILESYSTEM 39 | #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM 40 | #undef JSON_HAS_THREE_WAY_COMPARISON 41 | #undef JSON_HAS_RANGES 42 | #undef JSON_HAS_STATIC_RTTI 43 | #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 44 | #endif 45 | 46 | #include 47 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/meta/call_std/begin.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | NLOHMANN_JSON_NAMESPACE_BEGIN 14 | 15 | NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); 16 | 17 | NLOHMANN_JSON_NAMESPACE_END 18 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/meta/call_std/end.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | NLOHMANN_JSON_NAMESPACE_BEGIN 14 | 15 | NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); 16 | 17 | NLOHMANN_JSON_NAMESPACE_END 18 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/meta/detected.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #include 14 | 15 | NLOHMANN_JSON_NAMESPACE_BEGIN 16 | namespace detail 17 | { 18 | 19 | // https://en.cppreference.com/w/cpp/experimental/is_detected 20 | struct nonesuch 21 | { 22 | nonesuch() = delete; 23 | ~nonesuch() = delete; 24 | nonesuch(nonesuch const&) = delete; 25 | nonesuch(nonesuch const&&) = delete; 26 | void operator=(nonesuch const&) = delete; 27 | void operator=(nonesuch&&) = delete; 28 | }; 29 | 30 | template class Op, 33 | class... Args> 34 | struct detector 35 | { 36 | using value_t = std::false_type; 37 | using type = Default; 38 | }; 39 | 40 | template class Op, class... Args> 41 | struct detector>, Op, Args...> 42 | { 43 | using value_t = std::true_type; 44 | using type = Op; 45 | }; 46 | 47 | template class Op, class... Args> 48 | using is_detected = typename detector::value_t; 49 | 50 | template class Op, class... Args> 51 | struct is_detected_lazy : is_detected { }; 52 | 53 | template class Op, class... Args> 54 | using detected_t = typename detector::type; 55 | 56 | template class Op, class... Args> 57 | using detected_or = detector; 58 | 59 | template class Op, class... Args> 60 | using detected_or_t = typename detected_or::type; 61 | 62 | template class Op, class... Args> 63 | using is_detected_exact = std::is_same>; 64 | 65 | template class Op, class... Args> 66 | using is_detected_convertible = 67 | std::is_convertible, To>; 68 | 69 | } // namespace detail 70 | NLOHMANN_JSON_NAMESPACE_END 71 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/meta/identity_tag.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | NLOHMANN_JSON_NAMESPACE_BEGIN 14 | namespace detail 15 | { 16 | 17 | // dispatching helper struct 18 | template struct identity_tag {}; 19 | 20 | } // namespace detail 21 | NLOHMANN_JSON_NAMESPACE_END 22 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/meta/std_fs.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | #if JSON_HAS_EXPERIMENTAL_FILESYSTEM 14 | #include 15 | NLOHMANN_JSON_NAMESPACE_BEGIN 16 | namespace detail 17 | { 18 | namespace std_fs = std::experimental::filesystem; 19 | } // namespace detail 20 | NLOHMANN_JSON_NAMESPACE_END 21 | #elif JSON_HAS_FILESYSTEM 22 | #include // NOLINT(build/c++17) 23 | NLOHMANN_JSON_NAMESPACE_BEGIN 24 | namespace detail 25 | { 26 | namespace std_fs = std::filesystem; 27 | } // namespace detail 28 | NLOHMANN_JSON_NAMESPACE_END 29 | #endif 30 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/meta/void_t.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | NLOHMANN_JSON_NAMESPACE_BEGIN 14 | namespace detail 15 | { 16 | 17 | template struct make_void 18 | { 19 | using type = void; 20 | }; 21 | template using void_t = typename make_void::type; 22 | 23 | } // namespace detail 24 | NLOHMANN_JSON_NAMESPACE_END 25 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/string_escape.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include 12 | 13 | NLOHMANN_JSON_NAMESPACE_BEGIN 14 | namespace detail 15 | { 16 | 17 | /*! 18 | @brief replace all occurrences of a substring by another string 19 | 20 | @param[in,out] s the string to manipulate; changed so that all 21 | occurrences of @a f are replaced with @a t 22 | @param[in] f the substring to replace with @a t 23 | @param[in] t the string to replace @a f 24 | 25 | @pre The search string @a f must not be empty. **This precondition is 26 | enforced with an assertion.** 27 | 28 | @since version 2.0.0 29 | */ 30 | template 31 | inline void replace_substring(StringType& s, const StringType& f, 32 | const StringType& t) 33 | { 34 | JSON_ASSERT(!f.empty()); 35 | for (auto pos = s.find(f); // find first occurrence of f 36 | pos != StringType::npos; // make sure f was found 37 | s.replace(pos, f.size(), t), // replace with t, and 38 | pos = s.find(f, pos + t.size())) // find next occurrence of f 39 | {} 40 | } 41 | 42 | /*! 43 | * @brief string escaping as described in RFC 6901 (Sect. 4) 44 | * @param[in] s string to escape 45 | * @return escaped string 46 | * 47 | * Note the order of escaping "~" to "~0" and "/" to "~1" is important. 48 | */ 49 | template 50 | inline StringType escape(StringType s) 51 | { 52 | replace_substring(s, StringType{"~"}, StringType{"~0"}); 53 | replace_substring(s, StringType{"/"}, StringType{"~1"}); 54 | return s; 55 | } 56 | 57 | /*! 58 | * @brief string unescaping as described in RFC 6901 (Sect. 4) 59 | * @param[in] s string to unescape 60 | * @return unescaped string 61 | * 62 | * Note the order of escaping "~1" to "/" and "~0" to "~" is important. 63 | */ 64 | template 65 | static void unescape(StringType& s) 66 | { 67 | replace_substring(s, StringType{"~1"}, StringType{"/"}); 68 | replace_substring(s, StringType{"~0"}, StringType{"~"}); 69 | } 70 | 71 | } // namespace detail 72 | NLOHMANN_JSON_NAMESPACE_END 73 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/detail/string_utils.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #pragma once 10 | 11 | #include // size_t 12 | #include // string, to_string 13 | 14 | #include 15 | 16 | NLOHMANN_JSON_NAMESPACE_BEGIN 17 | namespace detail 18 | { 19 | 20 | template 21 | void int_to_string(StringType& target, std::size_t value) 22 | { 23 | // For ADL 24 | using std::to_string; 25 | target = to_string(value); 26 | } 27 | 28 | template 29 | StringType to_string(std::size_t value) 30 | { 31 | StringType result; 32 | int_to_string(result, value); 33 | return result; 34 | } 35 | 36 | } // namespace detail 37 | NLOHMANN_JSON_NAMESPACE_END 38 | -------------------------------------------------------------------------------- /vendor/vendor/include/nlohmann/json_fwd.hpp: -------------------------------------------------------------------------------- 1 | // __ _____ _____ _____ 2 | // __| | __| | | | JSON for Modern C++ 3 | // | | |__ | | | | | | version 3.12.0 4 | // |_____|_____|_____|_|___| https://github.com/nlohmann/json 5 | // 6 | // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann 7 | // SPDX-License-Identifier: MIT 8 | 9 | #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ 10 | #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ 11 | 12 | #include // int64_t, uint64_t 13 | #include // map 14 | #include // allocator 15 | #include // string 16 | #include // vector 17 | 18 | #include 19 | 20 | /*! 21 | @brief namespace for Niels Lohmann 22 | @see https://github.com/nlohmann 23 | @since version 1.0.0 24 | */ 25 | NLOHMANN_JSON_NAMESPACE_BEGIN 26 | 27 | /*! 28 | @brief default JSONSerializer template argument 29 | 30 | This serializer ignores the template arguments and uses ADL 31 | ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) 32 | for serialization. 33 | */ 34 | template 35 | struct adl_serializer; 36 | 37 | /// a class to store JSON values 38 | /// @sa https://json.nlohmann.me/api/basic_json/ 39 | template class ObjectType = 40 | std::map, 41 | template class ArrayType = std::vector, 42 | class StringType = std::string, class BooleanType = bool, 43 | class NumberIntegerType = std::int64_t, 44 | class NumberUnsignedType = std::uint64_t, 45 | class NumberFloatType = double, 46 | template class AllocatorType = std::allocator, 47 | template class JSONSerializer = 48 | adl_serializer, 49 | class BinaryType = std::vector, // cppcheck-suppress syntaxError 50 | class CustomBaseClass = void> 51 | class basic_json; 52 | 53 | /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document 54 | /// @sa https://json.nlohmann.me/api/json_pointer/ 55 | template 56 | class json_pointer; 57 | 58 | /*! 59 | @brief default specialization 60 | @sa https://json.nlohmann.me/api/json/ 61 | */ 62 | using json = basic_json<>; 63 | 64 | /// @brief a minimal map-like container that preserves insertion order 65 | /// @sa https://json.nlohmann.me/api/ordered_map/ 66 | template 67 | struct ordered_map; 68 | 69 | /// @brief specialization that maintains the insertion order of object keys 70 | /// @sa https://json.nlohmann.me/api/ordered_json/ 71 | using ordered_json = basic_json; 72 | 73 | NLOHMANN_JSON_NAMESPACE_END 74 | 75 | #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ 76 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/cf/array.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::cf::array v2.0 4 | 5 | // (C) Copyright Takayama Fumihiko 2018. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include 10 | 11 | namespace pqrs { 12 | namespace cf { 13 | inline cf_ptr make_empty_cf_array(void) { 14 | cf_ptr result; 15 | 16 | if (auto cf_array = CFArrayCreate(kCFAllocatorDefault, 17 | nullptr, 18 | 0, 19 | &kCFTypeArrayCallBacks)) { 20 | result = cf_array; 21 | CFRelease(cf_array); 22 | } 23 | 24 | return result; 25 | } 26 | 27 | inline cf_ptr make_cf_mutable_array(CFIndex capacity = 0) { 28 | cf_ptr result; 29 | 30 | if (auto cf_mutable_array = CFArrayCreateMutable(kCFAllocatorDefault, 31 | capacity, 32 | &kCFTypeArrayCallBacks)) { 33 | result = cf_mutable_array; 34 | CFRelease(cf_mutable_array); 35 | } 36 | 37 | return result; 38 | } 39 | 40 | template 41 | inline T get_cf_array_value(CFArrayRef array, CFIndex index) { 42 | if (array && index < CFArrayGetCount(array)) { 43 | return static_cast(const_cast(CFArrayGetValueAtIndex(array, index))); 44 | } 45 | return nullptr; 46 | } 47 | } // namespace cf 48 | } // namespace pqrs 49 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/cf/cf_ptr.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::cf::cf_ptr v2.0 4 | 5 | // (C) Copyright Takayama Fumihiko 2018. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include 10 | 11 | namespace pqrs { 12 | namespace cf { 13 | template 14 | class cf_ptr final { 15 | public: 16 | cf_ptr(void) : cf_ptr(nullptr) { 17 | } 18 | 19 | cf_ptr(T _Nullable p) : p_(p) { 20 | if (p_) { 21 | CFRetain(p_); 22 | } 23 | } 24 | 25 | cf_ptr(const cf_ptr& other) : p_(nullptr) { 26 | *this = other; 27 | } 28 | 29 | cf_ptr& operator=(const cf_ptr& other) { 30 | auto old = p_; 31 | 32 | p_ = other.p_; 33 | if (p_) { 34 | CFRetain(p_); 35 | } 36 | 37 | if (old) { 38 | CFRelease(old); 39 | } 40 | 41 | return *this; 42 | } 43 | 44 | ~cf_ptr(void) { 45 | reset(); 46 | } 47 | 48 | const T& get(void) const { 49 | return p_; 50 | } 51 | 52 | T& get(void) { 53 | return const_cast((static_cast(*this)).get()); 54 | } 55 | 56 | void reset(void) { 57 | if (p_) { 58 | CFRelease(p_); 59 | p_ = nullptr; 60 | } 61 | } 62 | 63 | operator bool(void) const { 64 | return p_ != nullptr; 65 | } 66 | 67 | const T& operator*(void)const { 68 | return p_; 69 | } 70 | 71 | T& operator*(void) { 72 | return const_cast(*(static_cast(*this))); 73 | } 74 | 75 | private: 76 | T _Nullable p_; 77 | }; 78 | } // namespace cf 79 | } // namespace pqrs 80 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/cf/number.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::cf::number v2.1 4 | 5 | // (C) Copyright Takayama Fumihiko 2018. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include "number/impl.hpp" 10 | #include 11 | 12 | namespace pqrs { 13 | namespace cf { 14 | inline cf_ptr make_cf_number(int8_t value) { 15 | return impl::make_cf_number(value, kCFNumberSInt8Type); 16 | } 17 | 18 | inline cf_ptr make_cf_number(int16_t value) { 19 | return impl::make_cf_number(value, kCFNumberSInt16Type); 20 | } 21 | 22 | inline cf_ptr make_cf_number(int32_t value) { 23 | return impl::make_cf_number(value, kCFNumberSInt32Type); 24 | } 25 | 26 | inline cf_ptr make_cf_number(int64_t value) { 27 | return impl::make_cf_number(value, kCFNumberSInt64Type); 28 | } 29 | 30 | inline cf_ptr make_cf_number(float value) { 31 | return impl::make_cf_number(value, kCFNumberFloat32Type); 32 | } 33 | 34 | inline cf_ptr make_cf_number(double value) { 35 | return impl::make_cf_number(value, kCFNumberFloat64Type); 36 | } 37 | 38 | template 39 | std::optional make_number(CFTypeRef value) = delete; 40 | 41 | template <> 42 | inline std::optional make_number(CFTypeRef value) { 43 | return impl::make_number(value, kCFNumberSInt8Type); 44 | } 45 | 46 | template <> 47 | inline std::optional make_number(CFTypeRef value) { 48 | return impl::make_number(value, kCFNumberSInt16Type); 49 | } 50 | 51 | template <> 52 | inline std::optional make_number(CFTypeRef value) { 53 | return impl::make_number(value, kCFNumberSInt32Type); 54 | } 55 | 56 | template <> 57 | inline std::optional make_number(CFTypeRef value) { 58 | return impl::make_number(value, kCFNumberSInt64Type); 59 | } 60 | 61 | template <> 62 | inline std::optional make_number(CFTypeRef value) { 63 | return impl::make_number(value, kCFNumberFloat32Type); 64 | } 65 | 66 | template <> 67 | inline std::optional make_number(CFTypeRef value) { 68 | return impl::make_number(value, kCFNumberFloat64Type); 69 | } 70 | } // namespace cf 71 | } // namespace pqrs 72 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/cf/number/impl.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | namespace pqrs { 11 | namespace cf { 12 | namespace impl { 13 | template 14 | inline cf_ptr make_cf_number(T value, CFNumberType type) { 15 | cf_ptr result; 16 | 17 | if (auto number = CFNumberCreate(kCFAllocatorDefault, type, &value)) { 18 | result = number; 19 | CFRelease(number); 20 | } 21 | 22 | return result; 23 | } 24 | 25 | template 26 | inline std::optional make_number(CFTypeRef value, CFNumberType type) { 27 | if (!value) { 28 | return std::nullopt; 29 | } 30 | 31 | if (CFNumberGetTypeID() != CFGetTypeID(value)) { 32 | return std::nullopt; 33 | } 34 | 35 | T result; 36 | if (CFNumberGetValue(static_cast(value), type, &result)) { 37 | return result; 38 | } 39 | 40 | return std::nullopt; 41 | } 42 | } // namespace impl 43 | } // namespace cf 44 | } // namespace pqrs 45 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/cf/run_loop_thread/extra/shared_run_loop_thread.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2023. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // `pqrs::cf::run_loop_thread::extra::shared_run_loop_thread` can be used safely in a multi-threaded environment. 8 | 9 | // namespace pqrs { 10 | // namespace cf { 11 | // class run_loop_thread { 12 | // class extra { 13 | 14 | class shared_run_loop_thread final { 15 | public: 16 | void initialize(void) { 17 | std::lock_guard lock(mutex_); 18 | 19 | if (!run_loop_thread_) { 20 | run_loop_thread_ = std::make_shared(); 21 | } 22 | } 23 | 24 | void terminate(void) { 25 | std::lock_guard lock(mutex_); 26 | 27 | if (run_loop_thread_) { 28 | run_loop_thread_->terminate(); 29 | run_loop_thread_ = nullptr; 30 | } 31 | } 32 | 33 | std::shared_ptr get_run_loop_thread(void) const { 34 | return run_loop_thread_; 35 | } 36 | 37 | static std::shared_ptr get_shared_run_loop_thread(void) { 38 | static std::mutex mutex; 39 | std::lock_guard lock(mutex); 40 | 41 | static std::shared_ptr p; 42 | if (!p) { 43 | p = std::make_shared(); 44 | } 45 | 46 | return p; 47 | } 48 | 49 | private: 50 | std::shared_ptr run_loop_thread_; 51 | mutable std::mutex mutex_; 52 | }; 53 | 54 | static void initialize_shared_run_loop_thread(void) { 55 | auto p = shared_run_loop_thread::get_shared_run_loop_thread(); 56 | p->initialize(); 57 | } 58 | 59 | static void terminate_shared_run_loop_thread(void) { 60 | auto p = shared_run_loop_thread::get_shared_run_loop_thread(); 61 | p->terminate(); 62 | } 63 | 64 | static std::shared_ptr get_shared_run_loop_thread(void) { 65 | auto p = shared_run_loop_thread::get_shared_run_loop_thread(); 66 | return p->get_run_loop_thread(); 67 | } 68 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/cf/string.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::cf::string v2.1 4 | 5 | // (C) Copyright Takayama Fumihiko 2018. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace pqrs { 15 | namespace cf { 16 | inline std::optional make_string(CFStringRef value) { 17 | if (value) { 18 | if (auto p = CFStringGetCStringPtr(value, kCFStringEncodingUTF8)) { 19 | return p; 20 | } else { 21 | // When cf_string contains unicode character such as `こんにちは`. 22 | auto length = CFStringGetLength(value); 23 | auto max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; 24 | std::vector buffer(max_size); 25 | if (CFStringGetCString(value, &(buffer[0]), max_size, kCFStringEncodingUTF8)) { 26 | return &(buffer[0]); 27 | } 28 | } 29 | } 30 | 31 | return std::nullopt; 32 | } 33 | 34 | inline std::optional make_string(CFTypeRef value) { 35 | if (value) { 36 | if (CFGetTypeID(value) == CFStringGetTypeID()) { 37 | return make_string(static_cast(value)); 38 | } 39 | } 40 | 41 | return std::nullopt; 42 | } 43 | 44 | inline cf_ptr make_cf_string(const std::string& string) { 45 | cf_ptr result; 46 | 47 | if (auto cf_string = CFStringCreateWithCString(kCFAllocatorDefault, 48 | string.c_str(), 49 | kCFStringEncodingUTF8)) { 50 | result = cf_string; 51 | CFRelease(cf_string); 52 | } 53 | 54 | return result; 55 | } 56 | } // namespace cf 57 | } // namespace pqrs 58 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/dispatcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::dispatcher v2.13 4 | 5 | // (C) Copyright Takayama Fumihiko 2018. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See https://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include "dispatcher/dispatcher.hpp" 10 | #include "dispatcher/object_id.hpp" 11 | #include "dispatcher/time_source.hpp" 12 | 13 | #include "dispatcher/extra/dispatcher_client.hpp" 14 | #include "dispatcher/extra/shared_dispatcher.hpp" 15 | #include "dispatcher/extra/timer.hpp" 16 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/dispatcher/extra/dispatcher_client.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // `pqrs::dispatcher::extra::dispatcher_client` can be used safely in a multi-threaded environment. 8 | 9 | #include "../dispatcher.hpp" 10 | #include "shared_dispatcher.hpp" 11 | #include 12 | 13 | namespace pqrs { 14 | namespace dispatcher { 15 | namespace extra { 16 | class dispatcher_client { 17 | public: 18 | dispatcher_client(std::weak_ptr weak_dispatcher = get_shared_dispatcher()) : weak_dispatcher_(weak_dispatcher), 19 | object_id_(make_new_object_id()) { 20 | if (auto d = weak_dispatcher_.lock()) { 21 | d->attach(object_id_); 22 | } 23 | } 24 | 25 | virtual ~dispatcher_client(void) { 26 | if (auto d = weak_dispatcher_.lock()) { 27 | if (d->attached(object_id_)) { 28 | // You must use detach_from_dispatcher explicitly. 29 | abort(); 30 | } 31 | } 32 | } 33 | 34 | void detach_from_dispatcher(void) const { 35 | if (auto d = weak_dispatcher_.lock()) { 36 | d->detach(object_id_); 37 | } 38 | } 39 | 40 | void detach_from_dispatcher(std::function function) const { 41 | if (auto d = weak_dispatcher_.lock()) { 42 | d->detach(object_id_, function); 43 | } 44 | } 45 | 46 | void enqueue_to_dispatcher(std::function function, 47 | time_point when = dispatcher::when_immediately()) const { 48 | if (auto d = weak_dispatcher_.lock()) { 49 | d->enqueue(object_id_, function, when); 50 | } 51 | } 52 | 53 | time_point when_now(void) const { 54 | if (auto d = weak_dispatcher_.lock()) { 55 | if (auto s = d->lock_weak_time_source()) { 56 | return s->now(); 57 | } 58 | } 59 | 60 | return dispatcher::when_immediately(); 61 | } 62 | 63 | bool attached(void) { 64 | if (auto d = weak_dispatcher_.lock()) { 65 | return d->attached(object_id_); 66 | } 67 | return false; 68 | } 69 | 70 | bool dispatcher_thread(void) const { 71 | if (auto d = weak_dispatcher_.lock()) { 72 | return d->dispatcher_thread(); 73 | } 74 | return false; 75 | } 76 | 77 | protected: 78 | std::weak_ptr weak_dispatcher_; 79 | object_id object_id_; 80 | }; 81 | } // namespace extra 82 | } // namespace dispatcher 83 | } // namespace pqrs 84 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/dispatcher/extra/shared_dispatcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // `pqrs::dispatcher::extra::shared_dispatcher` can be used safely in a multi-threaded environment. 8 | 9 | #include "../dispatcher.hpp" 10 | 11 | namespace pqrs { 12 | namespace dispatcher { 13 | namespace extra { 14 | class shared_dispatcher final { 15 | public: 16 | void initialize(void) { 17 | std::lock_guard lock(mutex_); 18 | 19 | if (!time_source_) { 20 | time_source_ = std::make_shared(); 21 | } 22 | 23 | if (!dispatcher_) { 24 | dispatcher_ = std::make_shared(time_source_); 25 | } 26 | } 27 | 28 | void terminate(void) { 29 | std::lock_guard lock(mutex_); 30 | 31 | if (dispatcher_) { 32 | dispatcher_->terminate(); 33 | dispatcher_ = nullptr; 34 | } 35 | 36 | if (time_source_) { 37 | time_source_ = nullptr; 38 | } 39 | } 40 | 41 | std::shared_ptr get_dispatcher(void) const { 42 | return dispatcher_; 43 | } 44 | 45 | static std::shared_ptr get_shared_dispatcher(void) { 46 | static std::mutex mutex; 47 | std::lock_guard lock(mutex); 48 | 49 | static std::shared_ptr p; 50 | if (!p) { 51 | p = std::make_shared(); 52 | } 53 | 54 | return p; 55 | } 56 | 57 | private: 58 | std::shared_ptr time_source_; 59 | std::shared_ptr dispatcher_; 60 | mutable std::mutex mutex_; 61 | }; 62 | 63 | inline void initialize_shared_dispatcher(void) { 64 | auto p = shared_dispatcher::get_shared_dispatcher(); 65 | p->initialize(); 66 | } 67 | 68 | inline void terminate_shared_dispatcher(void) { 69 | auto p = shared_dispatcher::get_shared_dispatcher(); 70 | p->terminate(); 71 | } 72 | 73 | inline std::shared_ptr get_shared_dispatcher(void) { 74 | auto p = shared_dispatcher::get_shared_dispatcher(); 75 | return p->get_dispatcher(); 76 | } 77 | } // namespace extra 78 | } // namespace dispatcher 79 | } // namespace pqrs 80 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/dispatcher/extra/timer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // `pqrs::dispatcher::extra::timer` can be used safely in a multi-threaded environment. 8 | 9 | #include "dispatcher_client.hpp" 10 | #include 11 | 12 | namespace pqrs { 13 | namespace dispatcher { 14 | namespace extra { 15 | 16 | // Usage Note: 17 | // 18 | // We must not destroy a timer before dispatcher_client is detached. 19 | // (It causes that dispatcher might access the released timer.) 20 | // timer calls `abort` if you destroy timer while 21 | // dispatcher_client is attached in order to avoid the above case. 22 | 23 | class timer final { 24 | public: 25 | timer(dispatcher_client& dispatcher_client) : dispatcher_client_(dispatcher_client), 26 | current_function_id_(0), 27 | interval_(0), 28 | enabled_(false) { 29 | } 30 | 31 | ~timer(void) { 32 | if (dispatcher_client_.attached()) { 33 | // Do not release timer before `dispatcher_client_` is detached. 34 | abort(); 35 | } 36 | } 37 | 38 | // First, `function` is called once, and then `function` is called every interval specified by `interval`. 39 | void start(std::function function, 40 | duration interval) { 41 | enabled_ = true; 42 | 43 | dispatcher_client_.enqueue_to_dispatcher([this, function, interval] { 44 | ++current_function_id_; 45 | function_ = function; 46 | interval_ = interval; 47 | 48 | call_function(current_function_id_); 49 | }); 50 | } 51 | 52 | void stop(void) { 53 | enabled_ = false; 54 | 55 | dispatcher_client_.enqueue_to_dispatcher([this] { 56 | ++current_function_id_; 57 | function_ = nullptr; 58 | interval_ = duration(0); 59 | }); 60 | } 61 | 62 | bool enabled(void) const { 63 | return enabled_; 64 | } 65 | 66 | // Update the interval. 67 | // Any `function` call reserved before calling this method will be canceled, and the `function` will be called after `interval` duration. 68 | // 69 | // Special cases:. 70 | // - If `interval` == duration(0), this method works same as `stop`. 71 | // - If `interval` is same as the current interval, this method does nothing. 72 | void set_interval(duration interval) { 73 | if (interval == duration(0)) { 74 | stop(); 75 | } else if (interval != interval_) { 76 | dispatcher_client_.enqueue_to_dispatcher([this, interval] { 77 | ++current_function_id_; 78 | interval_ = interval; 79 | 80 | enqueue(current_function_id_); 81 | }); 82 | } 83 | } 84 | 85 | private: 86 | // This method is executed in the dispatcher thread. 87 | void call_function(int function_id) { 88 | if (current_function_id_ != function_id) { 89 | return; 90 | } 91 | 92 | if (function_) { 93 | // We should capture function_ to call proper function even if function_ is updated in `start` or `stop` method. 94 | auto f = function_; 95 | 96 | // The `function_` call must be wrapped in enqueue_to_dispatcher in order to avoid heap-use-after-free when the timer itself is destroyed in `function_`. 97 | dispatcher_client_.enqueue_to_dispatcher([f] { 98 | f(); 99 | }); 100 | } 101 | 102 | enqueue(function_id); 103 | } 104 | 105 | void enqueue(int function_id) { 106 | dispatcher_client_.enqueue_to_dispatcher( 107 | [this, function_id] { 108 | call_function(function_id); 109 | }, 110 | dispatcher_client_.when_now() + interval_); 111 | } 112 | 113 | dispatcher_client& dispatcher_client_; 114 | int current_function_id_; 115 | std::function function_; 116 | duration interval_; 117 | 118 | std::atomic enabled_; 119 | }; 120 | } // namespace extra 121 | } // namespace dispatcher 122 | } // namespace pqrs 123 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/dispatcher/object_id.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // `pqrs::dispatcher::object_id` can be used safely in a multi-threaded environment. 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace pqrs { 16 | namespace dispatcher { 17 | class object_id final { 18 | public: 19 | object_id(const object_id&) = delete; 20 | object_id(object_id&&) = default; 21 | 22 | ~object_id(void) { 23 | manager::erase(value_); 24 | } 25 | 26 | static object_id make_new_object_id(void) { 27 | return object_id(manager::make()); 28 | } 29 | 30 | static size_t active_object_id_count(void) { 31 | return manager::size(); 32 | } 33 | 34 | uint64_t get(void) const { 35 | return value_; 36 | } 37 | 38 | private: 39 | class manager final { 40 | public: 41 | static uint64_t make(void) { 42 | std::lock_guard lock(mutex()); 43 | 44 | if (set().size() >= std::numeric_limits::max()) { 45 | throw std::runtime_error("pqrs::dispatcher::object_id::manager::make_new_object_id fails to allocate new object_id."); 46 | } 47 | 48 | while (true) { 49 | auto value = ++(last_value()); 50 | auto it = set().find(value); 51 | if (it == std::end(set())) { 52 | set().insert(value); 53 | last_value() = value; 54 | return value; 55 | } 56 | } 57 | } 58 | 59 | static void erase(uint64_t value) { 60 | std::lock_guard lock(mutex()); 61 | 62 | set().erase(value); 63 | } 64 | 65 | static size_t size(void) { 66 | std::lock_guard lock(mutex()); 67 | 68 | return set().size(); 69 | } 70 | 71 | private: 72 | static std::mutex& mutex(void) { 73 | static std::mutex mutex; 74 | return mutex; 75 | } 76 | 77 | static std::unordered_set& set(void) { 78 | static std::unordered_set set; 79 | return set; 80 | } 81 | 82 | static uint64_t& last_value(void) { 83 | static uint64_t value = 0; 84 | return value; 85 | } 86 | }; 87 | 88 | object_id(uint64_t value) : value_(value) { 89 | } 90 | 91 | uint64_t value_; 92 | }; 93 | 94 | inline object_id make_new_object_id(void) { 95 | return object_id::make_new_object_id(); 96 | } 97 | 98 | inline size_t active_object_id_count(void) { 99 | return object_id::active_object_id_count(); 100 | } 101 | 102 | inline std::ostream& operator<<(std::ostream& stream, const object_id& value) { 103 | stream << value.get(); 104 | return stream; 105 | } 106 | } // namespace dispatcher 107 | } // namespace pqrs 108 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/dispatcher/time_source.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // `pqrs::dispatcher::hardware_time_source` can be used safely in a multi-threaded environment. 8 | // `pqrs::dispatcher::pseudo_time_source` can be used safely in a multi-threaded environment. 9 | 10 | #include "types.hpp" 11 | #include 12 | 13 | namespace pqrs { 14 | namespace dispatcher { 15 | class time_source { 16 | public: 17 | virtual time_point now(void) = 0; 18 | }; 19 | 20 | class hardware_time_source final : public time_source { 21 | public: 22 | virtual time_point now(void) { 23 | return std::chrono::time_point_cast(std::chrono::system_clock::now()); 24 | } 25 | }; 26 | 27 | class pseudo_time_source final : public time_source { 28 | public: 29 | pseudo_time_source(void) : now_(duration(0)) { 30 | } 31 | 32 | virtual time_point now(void) { 33 | std::lock_guard lock(mutex_); 34 | 35 | return now_; 36 | } 37 | 38 | void set_now(time_point value) { 39 | std::lock_guard lock(mutex_); 40 | 41 | now_ = value; 42 | } 43 | 44 | private: 45 | time_point now_; 46 | mutable std::mutex mutex_; 47 | }; 48 | } // namespace dispatcher 49 | } // namespace pqrs 50 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/dispatcher/types.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace pqrs { 10 | namespace dispatcher { 11 | typedef std::chrono::milliseconds duration; 12 | typedef std::chrono::time_point time_point; 13 | } // namespace dispatcher 14 | } // namespace pqrs 15 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hash.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::hash v2.0 4 | 5 | // (C) Copyright Takayama Fumihiko 2019. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | namespace pqrs { 10 | namespace hash { 11 | template 12 | inline void combine(std::size_t& seed, const T& value) { 13 | seed ^= std::hash{}(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 14 | } 15 | } // namespace hash 16 | } // namespace pqrs 17 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::hid v2.18 4 | 5 | // (C) Copyright Takayama Fumihiko 2020. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See https://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include "hid/country_code.hpp" 10 | #include "hid/hash.hpp" 11 | #include "hid/manufacturer_string.hpp" 12 | #include "hid/product_id.hpp" 13 | #include "hid/product_string.hpp" 14 | #include "hid/report_id.hpp" 15 | #include "hid/usage.hpp" 16 | #include "hid/usage_page.hpp" 17 | #include "hid/usage_pair.hpp" 18 | #include "hid/vendor_id.hpp" 19 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/country_code.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2020. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace hid { 14 | namespace country_code { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison, 17 | type_safe::strong_typedef_op::relational_comparison { 18 | using strong_typedef::strong_typedef; 19 | 20 | constexpr auto operator<=>(const value_t& other) const { 21 | return type_safe::get(*this) <=> type_safe::get(other); 22 | } 23 | }; 24 | 25 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 26 | return stream << type_safe::get(value); 27 | } 28 | 29 | // 30 | // Values from Device Class Definition for Human Interface Devices (HID) Version 1.11. 31 | // https://www.usb.org/sites/default/files/documents/hid1_11.pdf 32 | // 33 | 34 | constexpr value_t not_supported(0); 35 | constexpr value_t arabic(1); 36 | constexpr value_t belgian(2); 37 | constexpr value_t canadian_bilingual(3); 38 | constexpr value_t canadian_french(4); 39 | constexpr value_t czech_republic(5); 40 | constexpr value_t danish(6); 41 | constexpr value_t finnish(7); 42 | constexpr value_t french(8); 43 | constexpr value_t german(9); 44 | constexpr value_t greek(10); 45 | constexpr value_t hebrew(11); 46 | constexpr value_t hungary(12); 47 | constexpr value_t international(13); 48 | constexpr value_t italian(14); 49 | constexpr value_t japan(15); 50 | constexpr value_t korean(16); 51 | constexpr value_t latin_american(17); 52 | constexpr value_t netherlands_dutch(18); 53 | constexpr value_t norwegian(19); 54 | constexpr value_t persian(20); 55 | constexpr value_t poland(21); 56 | constexpr value_t portuguese(22); 57 | constexpr value_t russia(23); 58 | constexpr value_t slovakia(24); 59 | constexpr value_t spanish(25); 60 | constexpr value_t swedish(26); 61 | constexpr value_t swiss_french(27); 62 | constexpr value_t swiss_german(28); 63 | constexpr value_t switzerland(29); 64 | constexpr value_t taiwan(30); 65 | constexpr value_t turkish_q(31); 66 | constexpr value_t uk(32); 67 | constexpr value_t us(33); 68 | constexpr value_t yugoslavia(34); 69 | constexpr value_t turkish_f(35); 70 | } // namespace country_code 71 | } // namespace hid 72 | } // namespace pqrs 73 | 74 | namespace std { 75 | template <> 76 | struct hash : type_safe::hashable { 77 | }; 78 | } // namespace std 79 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/extra/boost.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2020. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace pqrs { 10 | namespace hid { 11 | 12 | // 13 | // number values 14 | // 15 | 16 | namespace country_code { 17 | inline std::size_t hash_value(const value_t& value) { 18 | return std::hash{}(value); 19 | } 20 | } // namespace country_code 21 | 22 | namespace product_id { 23 | inline std::size_t hash_value(const value_t& value) { 24 | return std::hash{}(value); 25 | } 26 | } // namespace product_id 27 | 28 | namespace report_id { 29 | inline std::size_t hash_value(const value_t& value) { 30 | return std::hash{}(value); 31 | } 32 | } // namespace report_id 33 | 34 | namespace usage_page { 35 | inline std::size_t hash_value(const value_t& value) { 36 | return std::hash{}(value); 37 | } 38 | } // namespace usage_page 39 | 40 | namespace usage { 41 | inline std::size_t hash_value(const value_t& value) { 42 | return std::hash{}(value); 43 | } 44 | } // namespace usage 45 | 46 | namespace vendor_id { 47 | inline std::size_t hash_value(const value_t& value) { 48 | return std::hash{}(value); 49 | } 50 | } // namespace vendor_id 51 | 52 | // 53 | // string values 54 | // 55 | 56 | namespace manufacturer_string { 57 | inline std::size_t hash_value(const value_t& value) { 58 | return std::hash{}(value); 59 | } 60 | } // namespace manufacturer_string 61 | 62 | namespace product_string { 63 | inline std::size_t hash_value(const value_t& value) { 64 | return std::hash{}(value); 65 | } 66 | } // namespace product_string 67 | 68 | // 69 | // usage_pair 70 | // 71 | 72 | inline std::size_t hash_value(const usage_pair& value) { 73 | return std::hash{}(value); 74 | } 75 | 76 | inline std::size_t hash_value(const std::pair& value) { 77 | return std::hash>{}(value); 78 | } 79 | 80 | inline std::size_t hash_value(const std::pair& value) { 81 | return std::hash>{}(value); 82 | } 83 | } // namespace hid 84 | } // namespace pqrs 85 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/extra/nlohmann_json.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2020. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | namespace pqrs { 11 | namespace hid { 12 | 13 | // 14 | // number values 15 | // 16 | 17 | namespace country_code { 18 | inline void to_json(nlohmann::json& j, const value_t& value) { 19 | j = type_safe::get(value); 20 | } 21 | 22 | inline void from_json(const nlohmann::json& j, value_t& value) { 23 | json::requires_number(j, "json"); 24 | 25 | value = value_t(j.get>()); 26 | } 27 | } // namespace country_code 28 | 29 | namespace product_id { 30 | inline void to_json(nlohmann::json& j, const value_t& value) { 31 | j = type_safe::get(value); 32 | } 33 | 34 | inline void from_json(const nlohmann::json& j, value_t& value) { 35 | json::requires_number(j, "json"); 36 | 37 | value = value_t(j.get>()); 38 | } 39 | } // namespace product_id 40 | 41 | namespace report_id { 42 | inline void to_json(nlohmann::json& j, const value_t& value) { 43 | j = type_safe::get(value); 44 | } 45 | 46 | inline void from_json(const nlohmann::json& j, value_t& value) { 47 | json::requires_number(j, "json"); 48 | 49 | value = value_t(j.get>()); 50 | } 51 | } // namespace report_id 52 | 53 | namespace usage_page { 54 | inline void to_json(nlohmann::json& j, const value_t& value) { 55 | j = type_safe::get(value); 56 | } 57 | 58 | inline void from_json(const nlohmann::json& j, value_t& value) { 59 | json::requires_number(j, "json"); 60 | 61 | value = value_t(j.get>()); 62 | } 63 | } // namespace usage_page 64 | 65 | namespace usage { 66 | inline void to_json(nlohmann::json& j, const value_t& value) { 67 | j = type_safe::get(value); 68 | } 69 | 70 | inline void from_json(const nlohmann::json& j, value_t& value) { 71 | json::requires_number(j, "json"); 72 | 73 | value = value_t(j.get>()); 74 | } 75 | } // namespace usage 76 | 77 | namespace vendor_id { 78 | inline void to_json(nlohmann::json& j, const value_t& value) { 79 | j = type_safe::get(value); 80 | } 81 | 82 | inline void from_json(const nlohmann::json& j, value_t& value) { 83 | json::requires_number(j, "json"); 84 | 85 | value = value_t(j.get>()); 86 | } 87 | } // namespace vendor_id 88 | 89 | // 90 | // string values 91 | // 92 | 93 | namespace manufacturer_string { 94 | inline void to_json(nlohmann::json& j, const value_t& value) { 95 | j = type_safe::get(value); 96 | } 97 | 98 | inline void from_json(const nlohmann::json& j, value_t& value) { 99 | json::requires_string(j, "json"); 100 | 101 | value = value_t(j.get>()); 102 | } 103 | } // namespace manufacturer_string 104 | 105 | namespace product_string { 106 | inline void to_json(nlohmann::json& j, const value_t& value) { 107 | j = type_safe::get(value); 108 | } 109 | 110 | inline void from_json(const nlohmann::json& j, value_t& value) { 111 | json::requires_string(j, "json"); 112 | 113 | value = value_t(j.get>()); 114 | } 115 | } // namespace product_string 116 | 117 | // 118 | // usage_pair 119 | // 120 | 121 | inline void to_json(nlohmann::json& j, const usage_pair& usage_pair) { 122 | j["usage_page"] = usage_pair.get_usage_page(); 123 | j["usage"] = usage_pair.get_usage(); 124 | } 125 | 126 | inline void from_json(const nlohmann::json& j, usage_pair& usage_pair) { 127 | using namespace std::string_literals; 128 | 129 | json::requires_object(j, "json"); 130 | 131 | for (const auto& [key, value] : j.items()) { 132 | if (key == "usage_page") { 133 | usage_pair.set_usage_page(value.get()); 134 | 135 | } else if (key == "usage") { 136 | usage_pair.set_usage(value.get()); 137 | 138 | } else { 139 | throw json::unmarshal_error("unknown key: `"s + key + "`"s); 140 | } 141 | } 142 | } 143 | 144 | } // namespace hid 145 | } // namespace pqrs 146 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/hash.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2020. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "product_id.hpp" 8 | #include "usage.hpp" 9 | #include "usage_page.hpp" 10 | #include "vendor_id.hpp" 11 | #include 12 | #include 13 | #include 14 | 15 | namespace std { 16 | template <> 17 | struct hash> { 18 | size_t operator()(const std::pair& pair) const { 19 | size_t h = 0; 20 | pqrs::hash::combine(h, type_safe::get(pair.first)); 21 | pqrs::hash::combine(h, type_safe::get(pair.second)); 22 | return h; 23 | } 24 | }; 25 | 26 | template <> 27 | struct hash> { 28 | size_t operator()(const std::pair& pair) const { 29 | size_t h = 0; 30 | pqrs::hash::combine(h, type_safe::get(pair.first)); 31 | pqrs::hash::combine(h, type_safe::get(pair.second)); 32 | return h; 33 | } 34 | }; 35 | } // namespace std 36 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/manufacturer_string.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2024. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace hid { 14 | namespace manufacturer_string { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison { 17 | using strong_typedef::strong_typedef; 18 | }; 19 | 20 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 21 | return stream << type_safe::get(value); 22 | } 23 | } // namespace manufacturer_string 24 | } // namespace hid 25 | } // namespace pqrs 26 | 27 | namespace std { 28 | template <> 29 | struct hash : type_safe::hashable { 30 | }; 31 | } // namespace std 32 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/product_id.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2020. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace hid { 14 | namespace product_id { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison, 17 | type_safe::strong_typedef_op::relational_comparison { 18 | using strong_typedef::strong_typedef; 19 | 20 | constexpr auto operator<=>(const value_t& other) const { 21 | return type_safe::get(*this) <=> type_safe::get(other); 22 | } 23 | }; 24 | 25 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 26 | return stream << type_safe::get(value); 27 | } 28 | } // namespace product_id 29 | } // namespace hid 30 | } // namespace pqrs 31 | 32 | namespace std { 33 | template <> 34 | struct hash : type_safe::hashable { 35 | }; 36 | } // namespace std 37 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/product_string.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2024. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace hid { 14 | namespace product_string { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison { 17 | using strong_typedef::strong_typedef; 18 | }; 19 | 20 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 21 | return stream << type_safe::get(value); 22 | } 23 | } // namespace product_string 24 | } // namespace hid 25 | } // namespace pqrs 26 | 27 | namespace std { 28 | template <> 29 | struct hash : type_safe::hashable { 30 | }; 31 | } // namespace std 32 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/report_id.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2023. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace hid { 14 | namespace report_id { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison, 17 | type_safe::strong_typedef_op::relational_comparison { 18 | using strong_typedef::strong_typedef; 19 | 20 | constexpr auto operator<=>(const value_t& other) const { 21 | return type_safe::get(*this) <=> type_safe::get(other); 22 | } 23 | }; 24 | 25 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 26 | return stream << type_safe::get(value); 27 | } 28 | } // namespace report_id 29 | } // namespace hid 30 | } // namespace pqrs 31 | 32 | namespace std { 33 | template <> 34 | struct hash : type_safe::hashable { 35 | }; 36 | } // namespace std 37 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/usage_page.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2020. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace hid { 14 | namespace usage_page { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison, 17 | type_safe::strong_typedef_op::relational_comparison { 18 | using strong_typedef::strong_typedef; 19 | 20 | constexpr auto operator<=>(const value_t& other) const { 21 | return type_safe::get(*this) <=> type_safe::get(other); 22 | } 23 | }; 24 | 25 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 26 | return stream << type_safe::get(value); 27 | } 28 | 29 | // 30 | // Values from HID Usage Tables Version 1.12. 31 | // https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf 32 | // 33 | 34 | constexpr value_t undefined(0x00); 35 | constexpr value_t generic_desktop(0x01); 36 | constexpr value_t simulation(0x02); 37 | constexpr value_t vr(0x03); 38 | constexpr value_t sport(0x04); 39 | constexpr value_t game(0x05); 40 | constexpr value_t generic_device_controls(0x06); 41 | constexpr value_t keyboard_or_keypad(0x07); 42 | constexpr value_t leds(0x08); 43 | constexpr value_t button(0x09); 44 | constexpr value_t ordinal(0x0a); 45 | constexpr value_t telephony(0x0b); 46 | constexpr value_t consumer(0x0c); 47 | constexpr value_t digitizer(0x0d); 48 | // Reserved 0x0e 49 | constexpr value_t pid(0x0f); 50 | constexpr value_t unicode(0x10); 51 | // Reserved 0x11 - 0x13 52 | constexpr value_t alphanumeric_display(0x14); 53 | // Reserved 0x15 - 0x3f 54 | 55 | // 56 | // Values from AppleHIDUsageTables.h 57 | // 58 | 59 | constexpr value_t apple_vendor(0xff00); 60 | constexpr value_t apple_vendor_keyboard(0xff01); 61 | constexpr value_t apple_vendor_mouse(0xff02); 62 | constexpr value_t apple_vendor_accelerometer(0xff03); 63 | constexpr value_t apple_vendor_ambient_light_sensor(0xff04); 64 | constexpr value_t apple_vendor_temperature_sensor(0xff05); 65 | constexpr value_t apple_vendor_headset(0xff07); 66 | constexpr value_t apple_vendor_power_sensor(0xff08); 67 | constexpr value_t apple_vendor_smart_cover(0xff09); 68 | constexpr value_t apple_vendor_platinum(0xff0A); 69 | constexpr value_t apple_vendor_lisa(0xff0B); 70 | constexpr value_t apple_vendor_motion(0xff0C); 71 | constexpr value_t apple_vendor_battery(0xff0D); 72 | constexpr value_t apple_vendor_ir_remote(0xff0E); 73 | constexpr value_t apple_vendor_debug(0xff0F); 74 | constexpr value_t apple_vendor_ir_interface(0xff10); 75 | constexpr value_t apple_vendor_filtered_event(0xff50); 76 | constexpr value_t apple_vendor_multitouch(0xff60); 77 | constexpr value_t apple_vendor_display(0xff92); 78 | constexpr value_t apple_vendor_top_case(0x00ff); 79 | } // namespace usage_page 80 | } // namespace hid 81 | } // namespace pqrs 82 | 83 | namespace std { 84 | template <> 85 | struct hash : type_safe::hashable { 86 | }; 87 | } // namespace std 88 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/usage_pair.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2020. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "usage.hpp" 8 | #include "usage_page.hpp" 9 | 10 | namespace pqrs { 11 | namespace hid { 12 | class usage_pair final { 13 | public: 14 | constexpr usage_pair(void) 15 | : usage_page_(usage_page::undefined), 16 | usage_(usage::undefined) { 17 | } 18 | 19 | constexpr usage_pair(usage_page::value_t usage_page, 20 | usage::value_t usage) 21 | : usage_page_(usage_page), 22 | usage_(usage) { 23 | } 24 | 25 | usage_page::value_t get_usage_page(void) const { 26 | return usage_page_; 27 | } 28 | 29 | usage_pair& set_usage_page(const usage_page::value_t& value) { 30 | usage_page_ = value; 31 | return *this; 32 | } 33 | 34 | usage::value_t get_usage(void) const { 35 | return usage_; 36 | } 37 | 38 | usage_pair& set_usage(const usage::value_t& value) { 39 | usage_ = value; 40 | return *this; 41 | } 42 | 43 | constexpr auto operator<=>(const usage_pair&) const = default; 44 | 45 | private: 46 | usage_page::value_t usage_page_; 47 | usage::value_t usage_; 48 | }; 49 | } // namespace hid 50 | } // namespace pqrs 51 | 52 | // 53 | // hash 54 | // 55 | 56 | namespace std { 57 | template <> 58 | struct hash { 59 | size_t operator()(const pqrs::hid::usage_pair& pair) const { 60 | size_t h = 0; 61 | pqrs::hash::combine(h, type_safe::get(pair.get_usage_page())); 62 | pqrs::hash::combine(h, type_safe::get(pair.get_usage())); 63 | return h; 64 | } 65 | }; 66 | } // namespace std 67 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/hid/vendor_id.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2020. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace hid { 14 | namespace vendor_id { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison, 17 | type_safe::strong_typedef_op::relational_comparison { 18 | using strong_typedef::strong_typedef; 19 | 20 | constexpr auto operator<=>(const value_t& other) const { 21 | return type_safe::get(*this) <=> type_safe::get(other); 22 | } 23 | }; 24 | 25 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 26 | return stream << type_safe::get(value); 27 | } 28 | } // namespace vendor_id 29 | } // namespace hid 30 | } // namespace pqrs 31 | 32 | namespace std { 33 | template <> 34 | struct hash : type_safe::hashable { 35 | }; 36 | } // namespace std 37 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/json.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::json v1.7 4 | 5 | // (C) Copyright Takayama Fumihiko 2019. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See https://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include "json/formatter.hpp" 10 | #include "json/marshal_error.hpp" 11 | #include "json/pqrs_formatter.hpp" 12 | #include "json/unmarshal_error.hpp" 13 | #include 14 | #include 15 | #include 16 | 17 | namespace pqrs { 18 | namespace json { 19 | template 20 | inline std::optional find(const nlohmann::json& json, 21 | const std::string& key) { 22 | auto it = json.find(key); 23 | if (it != std::end(json)) { 24 | try { 25 | return it.value().get(); 26 | } catch (std::exception&) { 27 | } 28 | } 29 | 30 | return std::nullopt; 31 | } 32 | 33 | inline std::optional find_array(const nlohmann::json& json, 34 | const std::string& key) { 35 | auto it = json.find(key); 36 | if (it != std::end(json)) { 37 | if (it->is_array()) { 38 | return it; 39 | } 40 | } 41 | return std::nullopt; 42 | } 43 | 44 | inline std::optional find_object(const nlohmann::json& json, 45 | const std::string& key) { 46 | auto it = json.find(key); 47 | if (it != std::end(json)) { 48 | if (it->is_object()) { 49 | return it; 50 | } 51 | } 52 | return std::nullopt; 53 | } 54 | 55 | inline std::optional find_json(const nlohmann::json& json, 56 | const std::string& key) { 57 | auto it = json.find(key); 58 | if (it != std::end(json)) { 59 | return it; 60 | } 61 | return std::nullopt; 62 | } 63 | 64 | inline nlohmann::json find_copy(const nlohmann::json& json, 65 | const std::string& key, 66 | const nlohmann::json& fallback_value) { 67 | auto it = json.find(key); 68 | if (it != std::end(json)) { 69 | return it.value(); 70 | } 71 | return fallback_value; 72 | } 73 | 74 | // 75 | // type checks 76 | // 77 | 78 | inline std::string dump_for_error_message(const nlohmann::json& json) { 79 | return string::truncate(json.dump(), 256); 80 | } 81 | 82 | inline void requires_array(const nlohmann::json& json, const std::string& error_message_name) { 83 | using namespace std::string_literals; 84 | 85 | if (!json.is_array()) { 86 | throw unmarshal_error(error_message_name + " must be array, but is `"s + dump_for_error_message(json) + "`"s); 87 | } 88 | } 89 | 90 | inline void requires_boolean(const nlohmann::json& json, const std::string& error_message_name) { 91 | using namespace std::string_literals; 92 | 93 | if (!json.is_boolean()) { 94 | throw unmarshal_error(error_message_name + " must be boolean, but is `"s + dump_for_error_message(json) + "`"s); 95 | } 96 | } 97 | 98 | inline void requires_number(const nlohmann::json& json, const std::string& error_message_name) { 99 | using namespace std::string_literals; 100 | 101 | if (!json.is_number()) { 102 | throw unmarshal_error(error_message_name + " must be number, but is `"s + dump_for_error_message(json) + "`"s); 103 | } 104 | } 105 | 106 | inline void requires_object(const nlohmann::json& json, const std::string& error_message_name) { 107 | using namespace std::string_literals; 108 | 109 | if (!json.is_object()) { 110 | throw unmarshal_error(error_message_name + " must be object, but is `"s + dump_for_error_message(json) + "`"s); 111 | } 112 | } 113 | 114 | inline void requires_string(const nlohmann::json& json, const std::string& error_message_name) { 115 | using namespace std::string_literals; 116 | 117 | if (!json.is_string()) { 118 | throw unmarshal_error(error_message_name + " must be string, but is `"s + dump_for_error_message(json) + "`"s); 119 | } 120 | } 121 | } // namespace json 122 | } // namespace pqrs 123 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/json/formatter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2024. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace nlohmann { 10 | inline auto format_as(const json& value) { return value.dump(); } 11 | } // namespace nlohmann 12 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/json/marshal_error.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace pqrs { 10 | namespace json { 11 | class marshal_error : public std::runtime_error { 12 | public: 13 | marshal_error(const std::string& message) : std::runtime_error(message) { 14 | } 15 | }; 16 | } // namespace json 17 | } // namespace pqrs 18 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/json/unmarshal_error.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See https://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace pqrs { 10 | namespace json { 11 | class unmarshal_error : public std::runtime_error { 12 | public: 13 | unmarshal_error(const std::string& message) : std::runtime_error(message) { 14 | } 15 | }; 16 | } // namespace json 17 | } // namespace pqrs 18 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/chrono.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::osx::chrono v2.3 4 | 5 | // (C) Copyright Takayama Fumihiko 2019. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include "chrono/absolute_time_duration.hpp" 10 | #include "chrono/absolute_time_point.hpp" 11 | #include "chrono/chrono.hpp" 12 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/chrono/absolute_time_duration.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace pqrs { 12 | namespace osx { 13 | namespace chrono { 14 | struct absolute_time_duration : type_safe::strong_typedef, 15 | type_safe::strong_typedef_op::equality_comparison, 16 | type_safe::strong_typedef_op::relational_comparison, 17 | type_safe::strong_typedef_op::unary_plus, 18 | type_safe::strong_typedef_op::unary_minus, 19 | type_safe::strong_typedef_op::addition, 20 | type_safe::strong_typedef_op::subtraction, 21 | type_safe::strong_typedef_op::increment, 22 | type_safe::strong_typedef_op::decrement { 23 | using strong_typedef::strong_typedef; 24 | }; 25 | 26 | inline std::ostream& operator<<(std::ostream& stream, const absolute_time_duration& value) { 27 | return stream << type_safe::get(value); 28 | } 29 | } // namespace chrono 30 | } // namespace osx 31 | } // namespace pqrs 32 | 33 | namespace std { 34 | template <> 35 | struct hash : type_safe::hashable { 36 | }; 37 | } // namespace std 38 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/chrono/absolute_time_point.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "absolute_time_duration.hpp" 8 | 9 | namespace pqrs { 10 | namespace osx { 11 | namespace chrono { 12 | struct absolute_time_point : type_safe::strong_typedef, 13 | type_safe::strong_typedef_op::equality_comparison, 14 | type_safe::strong_typedef_op::relational_comparison, 15 | type_safe::strong_typedef_op::increment, 16 | type_safe::strong_typedef_op::decrement { 17 | using strong_typedef::strong_typedef; 18 | }; 19 | 20 | inline absolute_time_duration operator-(const absolute_time_point& a, 21 | const absolute_time_point& b) { 22 | return absolute_time_duration(type_safe::get(a) - type_safe::get(b)); 23 | } 24 | 25 | inline absolute_time_point operator+(const absolute_time_point& a, 26 | const absolute_time_duration& b) { 27 | return absolute_time_point(type_safe::get(a) + type_safe::get(b)); 28 | } 29 | 30 | inline absolute_time_point operator-(const absolute_time_point& a, 31 | const absolute_time_duration& b) { 32 | return absolute_time_point(type_safe::get(a) - type_safe::get(b)); 33 | } 34 | 35 | inline absolute_time_point& operator+=(absolute_time_point& a, 36 | const absolute_time_duration& b) { 37 | a = a + b; 38 | return a; 39 | } 40 | 41 | inline absolute_time_point& operator-=(absolute_time_point& a, 42 | const absolute_time_duration& b) { 43 | a = a - b; 44 | return a; 45 | } 46 | 47 | inline std::ostream& operator<<(std::ostream& stream, const absolute_time_point& value) { 48 | return stream << type_safe::get(value); 49 | } 50 | } // namespace chrono 51 | } // namespace osx 52 | } // namespace pqrs 53 | 54 | namespace std { 55 | template <> 56 | struct hash : type_safe::hashable { 57 | }; 58 | } // namespace std 59 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/chrono/chrono.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "absolute_time_point.hpp" 8 | #include "impl/chrono.hpp" 9 | #include 10 | #include 11 | #include 12 | 13 | namespace pqrs { 14 | namespace osx { 15 | namespace chrono { 16 | inline absolute_time_point mach_absolute_time_point(void) { 17 | return absolute_time_point(mach_absolute_time()); 18 | } 19 | 20 | inline std::chrono::nanoseconds make_nanoseconds(absolute_time_duration time) { 21 | auto& t = impl::get_mach_timebase_info_data(); 22 | if (t.numer != t.denom && t.denom != 0) { 23 | auto f = static_cast(t.numer) / t.denom; 24 | return std::chrono::nanoseconds(static_cast(type_safe::get(time) * f)); 25 | } 26 | return std::chrono::nanoseconds(type_safe::get(time)); 27 | } 28 | 29 | inline std::chrono::milliseconds make_milliseconds(absolute_time_duration time) { 30 | return std::chrono::duration_cast(make_nanoseconds(time)); 31 | } 32 | 33 | inline absolute_time_duration make_absolute_time_duration(std::chrono::nanoseconds time) { 34 | auto& t = impl::get_mach_timebase_info_data(); 35 | if (t.numer != t.denom && t.numer != 0) { 36 | auto f = static_cast(t.denom) / t.numer; 37 | return absolute_time_duration(static_cast(time.count() * f)); 38 | } 39 | return absolute_time_duration(time.count()); 40 | } 41 | } // namespace chrono 42 | } // namespace osx 43 | } // namespace pqrs 44 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/chrono/extra/nlohmann_json.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | namespace pqrs { 11 | namespace osx { 12 | namespace chrono { 13 | inline void to_json(nlohmann::json& j, const absolute_time_duration& p) { 14 | j = type_safe::get(p); 15 | } 16 | 17 | inline void from_json(const nlohmann::json& j, absolute_time_duration& p) { 18 | json::requires_number(j, "json"); 19 | 20 | p = absolute_time_duration(j.get()); 21 | } 22 | 23 | inline void to_json(nlohmann::json& j, const absolute_time_point& p) { 24 | j = type_safe::get(p); 25 | } 26 | 27 | inline void from_json(const nlohmann::json& j, absolute_time_point& p) { 28 | json::requires_number(j, "json"); 29 | 30 | p = absolute_time_point(j.get()); 31 | } 32 | } // namespace chrono 33 | } // namespace osx 34 | } // namespace pqrs 35 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/chrono/impl/chrono.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace pqrs { 12 | namespace osx { 13 | namespace chrono { 14 | namespace impl { 15 | inline const mach_timebase_info_data_t& get_mach_timebase_info_data(void) { 16 | static std::mutex mutex; 17 | std::lock_guard guard(mutex); 18 | 19 | static bool once = false; 20 | static mach_timebase_info_data_t mach_timebase_info_data; 21 | 22 | if (!once) { 23 | once = true; 24 | mach_timebase_info(&mach_timebase_info_data); 25 | } 26 | 27 | return mach_timebase_info_data; 28 | } 29 | } // namespace impl 30 | } // namespace chrono 31 | } // namespace osx 32 | } // namespace pqrs 33 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_hid_element/iokit_hid_element_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2020. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace pqrs { 10 | namespace osx { 11 | enum class iokit_hid_element_type { 12 | input_misc = kIOHIDElementTypeInput_Misc, 13 | input_button = kIOHIDElementTypeInput_Button, 14 | input_axis = kIOHIDElementTypeInput_Axis, 15 | input_scancodes = kIOHIDElementTypeInput_ScanCodes, 16 | input_null = kIOHIDElementTypeInput_NULL, 17 | output = kIOHIDElementTypeOutput, 18 | feature = kIOHIDElementTypeFeature, 19 | collection = kIOHIDElementTypeCollection, 20 | }; 21 | 22 | inline const char* get_iokit_hid_element_type_name(iokit_hid_element_type type) { 23 | switch (type) { 24 | #define GET_IOKIT_HID_ELEMENT_TYPE_NAME_RETURN_NAME(TYPE) \ 25 | case iokit_hid_element_type::TYPE: \ 26 | return #TYPE; 27 | 28 | GET_IOKIT_HID_ELEMENT_TYPE_NAME_RETURN_NAME(input_misc); 29 | GET_IOKIT_HID_ELEMENT_TYPE_NAME_RETURN_NAME(input_button); 30 | GET_IOKIT_HID_ELEMENT_TYPE_NAME_RETURN_NAME(input_axis); 31 | GET_IOKIT_HID_ELEMENT_TYPE_NAME_RETURN_NAME(input_scancodes); 32 | GET_IOKIT_HID_ELEMENT_TYPE_NAME_RETURN_NAME(input_null); 33 | GET_IOKIT_HID_ELEMENT_TYPE_NAME_RETURN_NAME(output); 34 | GET_IOKIT_HID_ELEMENT_TYPE_NAME_RETURN_NAME(feature); 35 | GET_IOKIT_HID_ELEMENT_TYPE_NAME_RETURN_NAME(collection); 36 | 37 | #undef GET_IOKIT_HID_ELEMENT_TYPE_NAME_RETURN_NAME 38 | } 39 | 40 | return "unknown"; 41 | } 42 | } // namespace osx 43 | } // namespace pqrs 44 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_hid_value.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::osx::iokit_hid_value v4.0 4 | 5 | // (C) Copyright Takayama Fumihiko 2019. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace pqrs { 16 | namespace osx { 17 | class iokit_hid_value final { 18 | public: 19 | iokit_hid_value(void) : time_stamp_(chrono::absolute_time_point(0)), 20 | integer_value_(0) { 21 | } 22 | 23 | iokit_hid_value(chrono::absolute_time_point time_stamp, 24 | CFIndex integer_value, 25 | std::optional usage_page, 26 | std::optional usage, 27 | std::optional logical_max, 28 | std::optional logical_min) : time_stamp_(time_stamp), 29 | integer_value_(integer_value), 30 | usage_page_(usage_page), 31 | usage_(usage), 32 | logical_max_(logical_max), 33 | logical_min_(logical_min) { 34 | } 35 | 36 | iokit_hid_value(IOHIDValueRef value) : iokit_hid_value() { 37 | if (value) { 38 | time_stamp_ = chrono::absolute_time_point(IOHIDValueGetTimeStamp(value)); 39 | integer_value_ = IOHIDValueGetIntegerValue(value); 40 | 41 | auto e = iokit_hid_element(IOHIDValueGetElement(value)); 42 | usage_page_ = e.get_usage_page(); 43 | usage_ = e.get_usage(); 44 | logical_max_ = e.get_logical_max(); 45 | logical_min_ = e.get_logical_min(); 46 | } 47 | } 48 | 49 | chrono::absolute_time_point get_time_stamp(void) const { 50 | return time_stamp_; 51 | } 52 | 53 | iokit_hid_value& set_time_stamp(chrono::absolute_time_point value) { 54 | time_stamp_ = value; 55 | return *this; 56 | } 57 | 58 | CFIndex get_integer_value(void) const { 59 | return integer_value_; 60 | } 61 | 62 | iokit_hid_value& set_integer_value(CFIndex value) { 63 | integer_value_ = value; 64 | return *this; 65 | } 66 | 67 | std::optional get_usage_page(void) const { 68 | return usage_page_; 69 | } 70 | 71 | iokit_hid_value& set_usage_page(const std::optional& value) { 72 | usage_page_ = value; 73 | return *this; 74 | } 75 | 76 | std::optional get_usage(void) const { 77 | return usage_; 78 | } 79 | 80 | iokit_hid_value& set_usage(const std::optional& value) { 81 | usage_ = value; 82 | return *this; 83 | } 84 | 85 | std::optional get_logical_max(void) const { 86 | return logical_max_; 87 | } 88 | 89 | iokit_hid_value& set_logical_max(CFIndex value) { 90 | logical_max_ = value; 91 | return *this; 92 | } 93 | 94 | std::optional get_logical_min(void) const { 95 | return logical_min_; 96 | } 97 | 98 | iokit_hid_value& set_logical_min(CFIndex value) { 99 | logical_min_ = value; 100 | return *this; 101 | } 102 | 103 | bool conforms_to(hid::usage_page::value_t usage_page, 104 | hid::usage::value_t usage) const { 105 | return usage_page_ == usage_page && 106 | usage_ == usage; 107 | } 108 | 109 | bool operator==(const iokit_hid_value& other) const { 110 | return time_stamp_ == other.time_stamp_ && 111 | integer_value_ == other.integer_value_ && 112 | usage_page_ == other.usage_page_ && 113 | usage_ == other.usage_ && 114 | logical_max_ == other.logical_max_ && 115 | logical_min_ == other.logical_min_; 116 | } 117 | 118 | bool operator!=(const iokit_hid_value& other) const { 119 | return !(*this == other); 120 | } 121 | 122 | private: 123 | chrono::absolute_time_point time_stamp_; 124 | CFIndex integer_value_; 125 | std::optional usage_page_; 126 | std::optional usage_; 127 | std::optional logical_max_; 128 | std::optional logical_min_; 129 | }; 130 | } // namespace osx 131 | } // namespace pqrs 132 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_hid_value/extra/nlohmann_json.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace pqrs { 12 | namespace osx { 13 | // iokit_hid_value 14 | 15 | inline void to_json(nlohmann::json& j, const iokit_hid_value& value) { 16 | j = nlohmann::json::object(); 17 | 18 | j["time_stamp"] = type_safe::get(value.get_time_stamp()); 19 | 20 | j["integer_value"] = value.get_integer_value(); 21 | 22 | if (auto usage_page = value.get_usage_page()) { 23 | j["usage_page"] = *usage_page; 24 | } 25 | 26 | if (auto usage = value.get_usage()) { 27 | j["usage"] = *usage; 28 | } 29 | 30 | if (auto logical_max = value.get_logical_max()) { 31 | j["logical_max"] = *logical_max; 32 | } 33 | 34 | if (auto logical_min = value.get_logical_min()) { 35 | j["logical_min"] = *logical_min; 36 | } 37 | } 38 | 39 | inline void from_json(const nlohmann::json& j, iokit_hid_value& hid_value) { 40 | using namespace std::string_literals; 41 | 42 | if (!j.is_object()) { 43 | json::requires_object(j, "json"); 44 | } 45 | 46 | for (const auto& [key, value] : j.items()) { 47 | if (key == "time_stamp") { 48 | json::requires_number(value, "`"s + key + "`"); 49 | 50 | hid_value.set_time_stamp(chrono::absolute_time_point(value.get())); 51 | 52 | } else if (key == "integer_value") { 53 | json::requires_number(value, "`"s + key + "`"); 54 | 55 | hid_value.set_integer_value(value.get()); 56 | 57 | } else if (key == "usage_page") { 58 | json::requires_number(value, "`"s + key + "`"); 59 | 60 | hid_value.set_usage_page(value.get()); 61 | 62 | } else if (key == "usage") { 63 | json::requires_number(value, "`"s + key + "`"); 64 | 65 | hid_value.set_usage(value.get()); 66 | 67 | } else if (key == "logical_max") { 68 | json::requires_number(value, "`"s + key + "`"); 69 | 70 | hid_value.set_logical_max(value.get()); 71 | 72 | } else if (key == "logical_min") { 73 | json::requires_number(value, "`"s + key + "`"); 74 | 75 | hid_value.set_logical_min(value.get()); 76 | 77 | } else { 78 | throw json::unmarshal_error("unknown key: `"s + key + "`"s); 79 | } 80 | } 81 | } 82 | } // namespace osx 83 | } // namespace pqrs 84 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_iterator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::osx::iokit_iterator v1.1 4 | 5 | // (C) Copyright Takayama Fumihiko 2019. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace osx { 14 | class iokit_iterator final { 15 | public: 16 | // 17 | // Constructors 18 | // 19 | 20 | iokit_iterator(void) : iokit_iterator(IO_OBJECT_NULL) { 21 | } 22 | 23 | explicit iokit_iterator(io_iterator_t iterator) : iterator_(iterator) { 24 | } 25 | 26 | explicit iokit_iterator(const iokit_object_ptr& iterator) : iterator_(iterator) { 27 | } 28 | 29 | // 30 | // Methods 31 | // 32 | 33 | const iokit_object_ptr& get(void) const { 34 | return iterator_; 35 | } 36 | 37 | iokit_object_ptr next(void) const { 38 | iokit_object_ptr result; 39 | 40 | if (iterator_) { 41 | auto it = IOIteratorNext(*iterator_); 42 | if (it) { 43 | result = iokit_object_ptr(it); 44 | IOObjectRelease(it); 45 | } 46 | } 47 | 48 | return result; 49 | } 50 | 51 | void reset(void) const { 52 | if (iterator_) { 53 | IOIteratorReset(*iterator_); 54 | } 55 | } 56 | 57 | bool valid(void) const { 58 | if (iterator_) { 59 | return IOIteratorIsValid(*iterator_); 60 | } 61 | return false; 62 | } 63 | 64 | operator bool(void) const { 65 | return valid(); 66 | } 67 | 68 | private: 69 | iokit_object_ptr iterator_; 70 | }; 71 | } // namespace osx 72 | } // namespace pqrs 73 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_object_ptr.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::osx::iokit_object_ptr v3.1 4 | 5 | // (C) Copyright Takayama Fumihiko 2018. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace pqrs { 15 | namespace osx { 16 | class iokit_object_ptr final { 17 | public: 18 | // 19 | // Constructors 20 | // 21 | 22 | iokit_object_ptr(void) : iokit_object_ptr(IO_OBJECT_NULL) { 23 | } 24 | 25 | explicit iokit_object_ptr(io_object_t p) : p_(p) { 26 | if (p_) { 27 | IOObjectRetain(p_); 28 | } 29 | } 30 | 31 | iokit_object_ptr(const iokit_object_ptr& other) : p_(IO_OBJECT_NULL) { 32 | *this = other; 33 | } 34 | 35 | iokit_object_ptr& operator=(const iokit_object_ptr& other) { 36 | auto old = p_; 37 | 38 | p_ = other.p_; 39 | if (p_) { 40 | IOObjectRetain(p_); 41 | } 42 | 43 | if (old) { 44 | IOObjectRelease(old); 45 | } 46 | 47 | return *this; 48 | } 49 | 50 | ~iokit_object_ptr(void) { 51 | reset(); 52 | } 53 | 54 | // 55 | // Pointer methods 56 | // 57 | 58 | const io_object_t& get(void) const { 59 | return p_; 60 | } 61 | 62 | io_object_t& get(void) { 63 | return const_cast((static_cast(*this)).get()); 64 | } 65 | 66 | void reset(void) { 67 | if (p_) { 68 | IOObjectRelease(p_); 69 | p_ = IO_OBJECT_NULL; 70 | } 71 | } 72 | 73 | // 74 | // Utility methods 75 | // 76 | 77 | uint32_t kernel_retain_count(void) const { 78 | if (p_) { 79 | return IOObjectGetKernelRetainCount(p_); 80 | } 81 | 82 | return 0; 83 | } 84 | 85 | uint32_t user_retain_count(void) const { 86 | if (p_) { 87 | return IOObjectGetUserRetainCount(p_); 88 | } 89 | 90 | return 0; 91 | } 92 | 93 | bool conforms_to(const io_name_t class_name) const { 94 | if (p_) { 95 | return IOObjectConformsTo(p_, class_name); 96 | } 97 | 98 | return false; 99 | } 100 | 101 | std::optional class_name(void) const { 102 | if (p_) { 103 | io_name_t name; 104 | kern_return r = IOObjectGetClass(p_, name); 105 | if (r) { 106 | return name; 107 | } 108 | } 109 | 110 | return std::nullopt; 111 | } 112 | 113 | // 114 | // Operators 115 | // 116 | 117 | operator bool(void) const { 118 | return p_ != IO_OBJECT_NULL; 119 | } 120 | 121 | const io_object_t& operator*(void)const { 122 | return get(); 123 | } 124 | 125 | io_object_t& operator*(void) { 126 | return get(); 127 | } 128 | 129 | private: 130 | io_object_t p_; 131 | }; 132 | } // namespace osx 133 | } // namespace pqrs 134 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_types.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::osx::iokit_types v6.2 4 | 5 | // (C) Copyright Takayama Fumihiko 2018. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include "iokit_types/hash.hpp" 10 | #include "iokit_types/iokit_hid_location_id.hpp" 11 | #include "iokit_types/iokit_keyboard_type.hpp" 12 | #include "iokit_types/iokit_mach_port.hpp" 13 | #include "iokit_types/iokit_registry_entry_id.hpp" 14 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_types/extra/boost.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace pqrs { 10 | namespace osx { 11 | namespace iokit_hid_location_id { 12 | inline std::size_t hash_value(const value_t& value) { 13 | return std::hash{}(value); 14 | } 15 | } // namespace iokit_hid_location_id 16 | 17 | namespace iokit_keyboard_type { 18 | inline std::size_t hash_value(const value_t& value) { 19 | return std::hash{}(value); 20 | } 21 | } // namespace iokit_keyboard_type 22 | 23 | namespace iokit_registry_entry_id { 24 | inline std::size_t hash_value(const value_t& value) { 25 | return std::hash{}(value); 26 | } 27 | } // namespace iokit_registry_entry_id 28 | 29 | inline std::size_t hash_value(const std::tuple& value) { 30 | return std::hash>{}(value); 31 | } 32 | } // namespace osx 33 | } // namespace pqrs 34 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_types/extra/nlohmann_json.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | 10 | namespace pqrs { 11 | namespace osx { 12 | namespace iokit_hid_location_id { 13 | inline void to_json(nlohmann::json& j, const value_t& value) { 14 | j = type_safe::get(value); 15 | } 16 | 17 | inline void from_json(const nlohmann::json& j, value_t& value) { 18 | json::requires_number(j, "json"); 19 | 20 | value = value_t(j.get>()); 21 | } 22 | } // namespace iokit_hid_location_id 23 | 24 | namespace iokit_keyboard_type { 25 | inline void to_json(nlohmann::json& j, const value_t& value) { 26 | j = type_safe::get(value); 27 | } 28 | 29 | inline void from_json(const nlohmann::json& j, value_t& value) { 30 | json::requires_number(j, "json"); 31 | 32 | value = value_t(j.get>()); 33 | } 34 | } // namespace iokit_keyboard_type 35 | 36 | namespace iokit_registry_entry_id { 37 | inline void to_json(nlohmann::json& j, const value_t& value) { 38 | j = type_safe::get(value); 39 | } 40 | 41 | inline void from_json(const nlohmann::json& j, value_t& value) { 42 | json::requires_number(j, "json"); 43 | 44 | value = value_t(j.get>()); 45 | } 46 | } // namespace iokit_registry_entry_id 47 | } // namespace osx 48 | } // namespace pqrs 49 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_types/hash.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "iokit_hid_location_id.hpp" 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace std { 14 | template <> 15 | struct hash> { 16 | size_t operator()(const std::tuple& tuple) const { 17 | size_t h = 0; 18 | pqrs::hash::combine(h, type_safe::get(std::get<0>(tuple))); 19 | pqrs::hash::combine(h, type_safe::get(std::get<1>(tuple))); 20 | pqrs::hash::combine(h, type_safe::get(std::get<2>(tuple))); 21 | return h; 22 | } 23 | }; 24 | } // namespace std 25 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_types/iokit_hid_location_id.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace osx { 14 | namespace iokit_hid_location_id { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison, 17 | type_safe::strong_typedef_op::relational_comparison { 18 | using strong_typedef::strong_typedef; 19 | 20 | constexpr auto operator<=>(const value_t& other) const { 21 | return type_safe::get(*this) <=> type_safe::get(other); 22 | } 23 | }; 24 | 25 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 26 | return stream << type_safe::get(value); 27 | } 28 | } // namespace iokit_hid_location_id 29 | } // namespace osx 30 | } // namespace pqrs 31 | 32 | namespace std { 33 | template <> 34 | struct hash : type_safe::hashable { 35 | }; 36 | } // namespace std 37 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_types/iokit_keyboard_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace osx { 14 | namespace iokit_keyboard_type { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison, 17 | type_safe::strong_typedef_op::relational_comparison { 18 | using strong_typedef::strong_typedef; 19 | 20 | constexpr auto operator<=>(const value_t& other) const { 21 | return type_safe::get(*this) <=> type_safe::get(other); 22 | } 23 | }; 24 | 25 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 26 | return stream << type_safe::get(value); 27 | } 28 | 29 | // 30 | // values 31 | // 32 | 33 | constexpr value_t ansi(40); 34 | constexpr value_t iso(41); 35 | constexpr value_t jis(42); 36 | 37 | // 38 | // methods 39 | // 40 | 41 | inline std::string make_string(value_t t) { 42 | if (t == iso) { 43 | return "iso"; 44 | } else if (t == jis) { 45 | return "jis"; 46 | } 47 | return "ansi"; 48 | } 49 | } // namespace iokit_keyboard_type 50 | } // namespace osx 51 | } // namespace pqrs 52 | 53 | namespace std { 54 | template <> 55 | struct hash : type_safe::hashable { 56 | }; 57 | } // namespace std 58 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_types/iokit_mach_port.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2022. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace osx { 14 | namespace iokit_mach_port { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison, 17 | type_safe::strong_typedef_op::relational_comparison { 18 | using strong_typedef::strong_typedef; 19 | 20 | constexpr auto operator<=>(const value_t& other) const { 21 | return type_safe::get(*this) <=> type_safe::get(other); 22 | } 23 | }; 24 | 25 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 26 | return stream << type_safe::get(value); 27 | } 28 | 29 | // 30 | // values 31 | // 32 | 33 | constexpr value_t null(0); 34 | } // namespace iokit_mach_port 35 | } // namespace osx 36 | } // namespace pqrs 37 | 38 | namespace std { 39 | template <> 40 | struct hash : type_safe::hashable { 41 | }; 42 | } // namespace std 43 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/osx/iokit_types/iokit_registry_entry_id.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace osx { 14 | namespace iokit_registry_entry_id { 15 | struct value_t : type_safe::strong_typedef, 16 | type_safe::strong_typedef_op::equality_comparison, 17 | type_safe::strong_typedef_op::relational_comparison { 18 | using strong_typedef::strong_typedef; 19 | 20 | constexpr auto operator<=>(const value_t& other) const { 21 | return type_safe::get(*this) <=> type_safe::get(other); 22 | } 23 | }; 24 | 25 | inline std::ostream& operator<<(std::ostream& stream, const value_t& value) { 26 | return stream << type_safe::get(value); 27 | } 28 | } // namespace iokit_registry_entry_id 29 | } // namespace osx 30 | } // namespace pqrs 31 | 32 | namespace std { 33 | template <> 34 | struct hash : type_safe::hashable { 35 | }; 36 | } // namespace std 37 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/string.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::string v1.5 4 | 5 | // (C) Copyright Takayama Fumihiko 2018. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | #include "string/predicate.hpp" 10 | #include "string/trim.hpp" 11 | #include "string/truncate.hpp" 12 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/string/predicate.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2019. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | namespace pqrs { 10 | namespace string { 11 | // Polyfill of std::string_view::starts_with (C++20) 12 | inline bool starts_with(const std::string_view& s, const std::string_view& prefix) { 13 | return s.compare(0, prefix.size(), prefix) == 0; 14 | } 15 | 16 | // Polyfill of std::string_view::ends_with (C++20) 17 | inline bool ends_with(const std::string_view& s, const std::string_view& suffix) { 18 | if (s.size() < suffix.size()) { 19 | return false; 20 | } 21 | 22 | return s.compare(s.size() - suffix.size(), suffix.size(), suffix) == 0; 23 | } 24 | } // namespace string 25 | } // namespace pqrs 26 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/string/trim.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2018. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace pqrs { 13 | namespace string { 14 | inline void trim_left(std::string& s) { 15 | s.erase(s.begin(), 16 | std::find_if(s.begin(), 17 | s.end(), 18 | [](int c) { 19 | return !std::isspace(c); 20 | })); 21 | } 22 | 23 | inline void trim_right(std::string& s) { 24 | s.erase(std::find_if(s.rbegin(), 25 | s.rend(), 26 | [](int c) { 27 | return !std::isspace(c); 28 | }) 29 | .base(), 30 | s.end()); 31 | } 32 | 33 | inline void trim(std::string& s) { 34 | trim_left(s); 35 | trim_right(s); 36 | } 37 | 38 | inline std::string trim_left_copy(const std::string_view& s) { 39 | std::string result(s); 40 | trim_left(result); 41 | return result; 42 | } 43 | 44 | inline std::string trim_right_copy(const std::string_view& s) { 45 | std::string result(s); 46 | trim_right(result); 47 | return result; 48 | } 49 | 50 | inline std::string trim_copy(const std::string_view& s) { 51 | std::string result(s); 52 | trim(result); 53 | return result; 54 | } 55 | 56 | inline void trim_invalid_right(std::string& s) { 57 | auto pos = utf8::find_invalid(s); 58 | if (pos != std::string::npos) { 59 | s = s.substr(0, pos); 60 | } 61 | } 62 | 63 | inline std::string trim_invalid_right_copy(const std::string_view& s) { 64 | std::string result(s); 65 | trim_invalid_right(result); 66 | return result; 67 | } 68 | } // namespace string 69 | } // namespace pqrs 70 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/string/truncate.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // (C) Copyright Takayama Fumihiko 2020. 4 | // Distributed under the Boost Software License, Version 1.0. 5 | // (See http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace pqrs { 12 | namespace string { 13 | inline std::string truncate(const std::string_view& s, 14 | size_t length, 15 | const std::string_view& placeholder = "...") { 16 | // Replace invalid character to ensure no invalid characters until the end of string before create substring. 17 | auto valid_string = utf8::replace_invalid(s); 18 | 19 | if (valid_string.length() <= length || 20 | length <= placeholder.length()) { 21 | return trim_invalid_right_copy(valid_string.substr(0, length)); 22 | 23 | } else { 24 | // Append placeholder 25 | std::stringstream ss; 26 | ss << trim_invalid_right_copy(valid_string.substr(0, length - placeholder.length())) 27 | << placeholder; 28 | return ss.str(); 29 | } 30 | } 31 | } // namespace string 32 | } // namespace pqrs 33 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/thread_wait.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::thread_wait v1.4 4 | 5 | // (C) Copyright Takayama Fumihiko 2018. 6 | // Distributed under the Boost Software License, Version 1.0. 7 | // (See http://www.boost.org/LICENSE_1_0.txt) 8 | 9 | // `pqrs::thread_wait` can be used safely in a multi-threaded environment. 10 | 11 | #include 12 | #include 13 | 14 | namespace pqrs { 15 | class thread_wait { 16 | public: 17 | // We have to use shared_ptr to avoid SEGV from a spuriously wake. 18 | // 19 | // Note: 20 | // If we don't use shared_ptr, `thread_wait::notify` rarely causes SEGV in the following case. 21 | // 22 | // 1. `notify` set notify_ = true. 23 | // 2. `wait_notice` exits by spuriously wake. 24 | // 3. `wait` is destructed. 25 | // 4. `notify` calls `cv_.notify_all` with released `cv_`. (SEGV) 26 | // 27 | // A bad example: 28 | // ---------------------------------------- 29 | // { 30 | // pqrs::thread_wait w; 31 | // std::thread t([&w] { 32 | // w.notify(); // `notify` rarely causes SEGV. 33 | // }); 34 | // t.detach(); 35 | // w.wait_notice(); 36 | // } 37 | // ---------------------------------------- 38 | // 39 | // A good example: 40 | // ---------------------------------------- 41 | // { 42 | // auto w = pqrs::make_thread_wait(); 43 | // std::thread t([w] { 44 | // w->notify(); 45 | // }); 46 | // t.detach(); 47 | // w->wait_notice(); 48 | // } 49 | // ---------------------------------------- 50 | 51 | static std::shared_ptr make_thread_wait(void) { 52 | struct impl : thread_wait { 53 | impl(void) : thread_wait() {} 54 | }; 55 | return std::make_shared(); 56 | } 57 | 58 | virtual ~thread_wait(void) { 59 | } 60 | 61 | void wait_notice(void) { 62 | std::unique_lock lock(mutex_); 63 | 64 | cv_.wait(lock, [this] { 65 | return notify_; 66 | }); 67 | } 68 | 69 | void notify(void) { 70 | { 71 | std::lock_guard lock(mutex_); 72 | 73 | notify_ = true; 74 | } 75 | 76 | cv_.notify_all(); 77 | } 78 | 79 | private: 80 | thread_wait(void) : notify_(false) { 81 | } 82 | 83 | bool notify_; 84 | std::mutex mutex_; 85 | std::condition_variable cv_; 86 | }; 87 | 88 | inline std::shared_ptr make_thread_wait(void) { 89 | return thread_wait::make_thread_wait(); 90 | } 91 | } // namespace pqrs 92 | -------------------------------------------------------------------------------- /vendor/vendor/include/pqrs/weakify.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // pqrs::weakify v1.0 4 | 5 | // Created by Justin Spahr-Summers on 2011-05-04. 6 | // Copyright (C) 2012 Justin Spahr-Summers. 7 | // Released under the MIT license. 8 | 9 | // 2019 Takayama Fumihiko 10 | // Copied @weakify and @strongify from libextobjc and modified them. 11 | // https://github.com/jspahrsummers/libextobjc/blob/master/extobjc/EXTScope.h 12 | 13 | #import 14 | 15 | #define weakify(VAR) \ 16 | autoreleasepool {} \ 17 | __weak __typeof(VAR) VAR##_weak_ = VAR; 18 | 19 | #define strongify(VAR) \ 20 | autoreleasepool {} \ 21 | _Pragma("clang diagnostic push"); \ 22 | _Pragma("clang diagnostic ignored \"-Wshadow\""); \ 23 | __strong typeof(VAR) VAR = VAR##_weak_; \ 24 | _Pragma("clang diagnostic pop"); 25 | -------------------------------------------------------------------------------- /vendor/vendor/include/type_safe/detail/aligned_union.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2020 Jonathan Müller 2 | // This file is subject to the license terms in the LICENSE file 3 | // found in the top-level directory of this distribution. 4 | 5 | #ifndef TYPE_SAFE_DETAIL_ALIGNED_UNION_HPP_INCLUDED 6 | #define TYPE_SAFE_DETAIL_ALIGNED_UNION_HPP_INCLUDED 7 | 8 | #if defined(TYPE_SAFE_IMPORT_STD_MODULE) 9 | import std; 10 | #else 11 | # include 12 | # include 13 | #endif 14 | 15 | namespace type_safe 16 | { 17 | namespace detail 18 | { 19 | // max for variadic number of types. 20 | template 21 | constexpr const T& max(const T& a) 22 | { 23 | return a; 24 | } 25 | 26 | template 27 | constexpr const T& max(const T& a, const T& b) 28 | { 29 | return a < b ? b : a; 30 | } 31 | 32 | template 33 | constexpr const T& max(const T& t, const Ts&... ts) 34 | { 35 | return max(t, max(ts...)); 36 | } 37 | 38 | template 39 | class aligned_union 40 | { 41 | public: 42 | static constexpr auto size_value = detail::max(sizeof(Types)...); 43 | static constexpr auto alignment_value = detail::max(alignof(Types)...); 44 | 45 | void* get() noexcept 46 | { 47 | return &storage_; 48 | } 49 | const void* get() const noexcept 50 | { 51 | return &storage_; 52 | } 53 | 54 | private: 55 | alignas(alignment_value) unsigned char storage_[size_value]; 56 | }; 57 | } // namespace detail 58 | } // namespace type_safe 59 | 60 | #endif // TYPE_SAFE_DETAIL_ALIGNED_UNION_HPP_INCLUDED 61 | -------------------------------------------------------------------------------- /vendor/vendor/include/type_safe/detail/all_of.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2020 Jonathan Müller 2 | // This file is subject to the license terms in the LICENSE file 3 | // found in the top-level directory of this distribution. 4 | 5 | #ifndef TYPE_SAFE_DETAIL_ALL_OF_HPP_INCLUDED 6 | #define TYPE_SAFE_DETAIL_ALL_OF_HPP_INCLUDED 7 | 8 | #if defined(TYPE_SAFE_IMPORT_STD_MODULE) 9 | import std; 10 | #else 11 | #include 12 | #endif 13 | 14 | namespace type_safe 15 | { 16 | namespace detail 17 | { 18 | template 19 | struct bool_sequence 20 | {}; 21 | 22 | template 23 | using all_of = std::is_same, bool_sequence<(true || Bs)...>>; 24 | 25 | template 26 | using none_of = std::is_same, bool_sequence<(false && Bs)...>>; 27 | 28 | template 29 | using any_of = std::integral_constant::value>; 30 | } // namespace detail 31 | } // namespace type_safe 32 | 33 | #endif // TYPE_SAFE_DETAIL_ALL_OF_HPP_INCLUDED 34 | -------------------------------------------------------------------------------- /vendor/vendor/include/type_safe/detail/assert.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2020 Jonathan Müller 2 | // This file is subject to the license terms in the LICENSE file 3 | // found in the top-level directory of this distribution. 4 | 5 | #ifndef TYPE_SAFE_DETAIL_ASSERT_HPP_INCLUDED 6 | #define TYPE_SAFE_DETAIL_ASSERT_HPP_INCLUDED 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace type_safe 13 | { 14 | namespace detail 15 | { 16 | struct assert_handler : debug_assert::set_level, 17 | debug_assert::default_handler 18 | {}; 19 | 20 | struct precondition_error_handler 21 | : debug_assert::set_level, 22 | debug_assert::default_handler 23 | {}; 24 | 25 | inline void on_disabled_exception() noexcept 26 | { 27 | struct handler : debug_assert::set_level<1>, debug_assert::default_handler 28 | {}; 29 | DEBUG_UNREACHABLE(handler{}, "attempt to throw an exception but exceptions are disabled"); 30 | } 31 | } // namespace detail 32 | } // namespace type_safe 33 | 34 | #endif // TYPE_SAFE_DETAIL_ASSERT_HPP_INCLUDED` 35 | -------------------------------------------------------------------------------- /vendor/vendor/include/type_safe/detail/assign_or_construct.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2020 Jonathan Müller 2 | // This file is subject to the license terms in the LICENSE file 3 | // found in the top-level directory of this distribution. 4 | 5 | #ifndef TYPE_SAFE_DETAIL_ASSIGN_OR_CONSTRUCT_HPP_INCLUDED 6 | #define TYPE_SAFE_DETAIL_ASSIGN_OR_CONSTRUCT_HPP_INCLUDED 7 | 8 | #if defined(TYPE_SAFE_IMPORT_STD_MODULE) 9 | import std; 10 | #else 11 | #include 12 | #endif 13 | 14 | namespace type_safe 15 | { 16 | namespace detail 17 | { 18 | // std::is_assignable but without user-defined conversions 19 | template 20 | struct is_direct_assignable 21 | { 22 | template 23 | struct consume_udc 24 | { 25 | operator U() const; 26 | }; 27 | 28 | template 29 | static std::true_type check(decltype(std::declval() = std::declval>(), 30 | 0)*); 31 | 32 | template 33 | static std::false_type check(...); 34 | 35 | static constexpr bool value = decltype(check(0))::value; 36 | }; 37 | } // namespace detail 38 | } // namespace type_safe 39 | 40 | #endif // TYPE_SAFE_DETAIL_ASSIGN_OR_CONSTRUCT_HPP_INCLUDED 41 | -------------------------------------------------------------------------------- /vendor/vendor/include/type_safe/detail/copy_move_control.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2020 Jonathan Müller 2 | // This file is subject to the license terms in the LICENSE file 3 | // found in the top-level directory of this distribution. 4 | 5 | #ifndef TYPE_SAFE_DETAIL_COPY_MOVE_CONTROL_HPP_INCLUDED 6 | #define TYPE_SAFE_DETAIL_COPY_MOVE_CONTROL_HPP_INCLUDED 7 | 8 | namespace type_safe 9 | { 10 | namespace detail 11 | { 12 | template 13 | struct copy_control; 14 | 15 | template <> 16 | struct copy_control 17 | { 18 | copy_control() noexcept = default; 19 | 20 | copy_control(const copy_control&) noexcept = default; 21 | copy_control& operator=(const copy_control&) noexcept = default; 22 | 23 | copy_control(copy_control&&) noexcept = default; 24 | copy_control& operator=(copy_control&&) noexcept = default; 25 | }; 26 | 27 | template <> 28 | struct copy_control 29 | { 30 | copy_control() noexcept = default; 31 | 32 | copy_control(const copy_control&) noexcept = delete; 33 | copy_control& operator=(const copy_control&) noexcept = delete; 34 | 35 | copy_control(copy_control&&) noexcept = default; 36 | copy_control& operator=(copy_control&&) noexcept = default; 37 | }; 38 | 39 | template 40 | struct move_control; 41 | 42 | template <> 43 | struct move_control 44 | { 45 | move_control() noexcept = default; 46 | 47 | move_control(const move_control&) noexcept = default; 48 | move_control& operator=(const move_control&) noexcept = default; 49 | 50 | move_control(move_control&&) noexcept = default; 51 | move_control& operator=(move_control&&) noexcept = default; 52 | }; 53 | 54 | template <> 55 | struct move_control 56 | { 57 | move_control() noexcept = default; 58 | 59 | move_control(const move_control&) noexcept = default; 60 | move_control& operator=(const move_control&) noexcept = default; 61 | 62 | move_control(move_control&&) noexcept = delete; 63 | move_control& operator=(move_control&&) noexcept = delete; 64 | }; 65 | } // namespace detail 66 | } // namespace type_safe 67 | 68 | #endif // TYPE_SAFE_DETAIL_COPY_MOVE_CONTROL_HPP_INCLUDED 69 | -------------------------------------------------------------------------------- /vendor/vendor/include/type_safe/detail/force_inline.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2020 Jonathan Müller 2 | // This file is subject to the license terms in the LICENSE file 3 | // found in the top-level directory of this distribution. 4 | 5 | #ifndef TYPE_SAFE_DETAIL_FORCE_INLINE_HPP_INCLUDED 6 | #define TYPE_SAFE_DETAIL_FORCE_INLINE_HPP_INCLUDED 7 | 8 | #include 9 | 10 | #define TYPE_SAFE_FORCE_INLINE DEBUG_ASSERT_FORCE_INLINE 11 | 12 | #endif // TYPE_SAFE_DETAIL_FORCE_INLINE_HPP_INCLUDED 13 | -------------------------------------------------------------------------------- /vendor/vendor/include/type_safe/detail/is_nothrow_swappable.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2020 Jonathan Müller 2 | // This file is subject to the license terms in the LICENSE file 3 | // found in the top-level directory of this distribution. 4 | 5 | #ifndef TYPE_SAFE_DETAIL_IS_NOTHROW_SWAPABLE_HPP_INCLUDED 6 | #define TYPE_SAFE_DETAIL_IS_NOTHROW_SWAPABLE_HPP_INCLUDED 7 | 8 | #if defined(TYPE_SAFE_IMPORT_STD_MODULE) 9 | import std; 10 | #else 11 | #include 12 | #endif 13 | 14 | namespace type_safe 15 | { 16 | namespace detail 17 | { 18 | template 19 | struct is_nothrow_swappable 20 | { 21 | template 22 | static auto adl_swap(int, U& a, U& b) noexcept(noexcept(swap(a, b))) 23 | -> decltype(swap(a, b)); 24 | 25 | template 26 | static auto adl_swap(short, U& a, U& b) noexcept(noexcept(std::swap(a, b))) 27 | -> decltype(std::swap(a, b)); 28 | 29 | static void adl_swap(...) noexcept(false); 30 | 31 | static constexpr bool value = noexcept(adl_swap(0, std::declval(), std::declval())); 32 | }; 33 | } // namespace detail 34 | } // namespace type_safe 35 | 36 | #endif // TYPE_SAFE_DETAIL_IS_NOTHROW_SWAPABLE_HPP_INCLUDED 37 | -------------------------------------------------------------------------------- /vendor/vendor/include/type_safe/detail/map_invoke.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2020 Jonathan Müller 2 | // This file is subject to the license terms in the LICENSE file 3 | // found in the top-level directory of this distribution. 4 | 5 | #ifndef TYPE_SAFE_DETAIL_MAP_INVOKE_HPP_INCLUDED 6 | #define TYPE_SAFE_DETAIL_MAP_INVOKE_HPP_INCLUDED 7 | 8 | #if defined(TYPE_SAFE_IMPORT_STD_MODULE) 9 | import std; 10 | #else 11 | #include 12 | #endif 13 | 14 | namespace type_safe 15 | { 16 | namespace detail 17 | { 18 | template 19 | auto map_invoke(Func&& f, Value&& v, Args&&... args) 20 | -> decltype(std::forward(f)(std::forward(v), std::forward(args)...)) 21 | { 22 | return std::forward(f)(std::forward(v), std::forward(args)...); 23 | } 24 | 25 | template 26 | auto map_invoke(Func&& f, Value&& v) -> decltype(std::forward(v).*std::forward(f)) 27 | { 28 | return std::forward(v).*std::forward(f); 29 | } 30 | 31 | template 32 | auto map_invoke(Func&& f, Value&& v, Args&&... args) 33 | -> decltype((std::forward(v).*std::forward(f))(std::forward(args)...)) 34 | { 35 | return (std::forward(v).*std::forward(f))(std::forward(args)...); 36 | } 37 | } // namespace detail 38 | } // namespace type_safe 39 | 40 | #endif // TYPE_SAFE_MAP_INVOKE_HPP_INCLUDED 41 | -------------------------------------------------------------------------------- /vendor/vendor/include/type_safe/downcast.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2016-2020 Jonathan Müller 2 | // This file is subject to the license terms in the LICENSE file 3 | // found in the top-level directory of this distribution. 4 | 5 | #ifndef TYPE_SAFE_DOWNCAST_HPP_INCLUDED 6 | #define TYPE_SAFE_DOWNCAST_HPP_INCLUDED 7 | 8 | #if defined(TYPE_SAFE_IMPORT_STD_MODULE) 9 | import std; 10 | #else 11 | #include 12 | #endif 13 | 14 | #include 15 | #include 16 | 17 | namespace type_safe 18 | { 19 | /// Tag type to specify the derived type of a [ts::downcast](). 20 | /// 21 | /// Pass it as first parameter to the appropriate overload. 22 | template 23 | struct derived_type 24 | {}; 25 | 26 | namespace detail 27 | { 28 | // same type 29 | template 30 | bool is_safe_downcast(derived_type, const T&) 31 | { 32 | return true; 33 | } 34 | 35 | // polymorphic type, so we can check 36 | template 37 | auto is_safe_downcast(derived_type, const Base& obj) -> 38 | typename std::enable_if::value, bool>::type 39 | { 40 | #if TYPE_SAFE_USE_RTTI 41 | return dynamic_cast(&obj) != nullptr; 42 | #else 43 | return true; 44 | #endif 45 | } 46 | 47 | // non-polymorphic type, no check possible 48 | template 49 | auto is_safe_downcast(derived_type, const Base&) -> 50 | typename std::enable_if::value, bool>::type 51 | { 52 | return true; 53 | } 54 | 55 | template 56 | void validate_downcast(const Base& obj) noexcept 57 | { 58 | using derived_t = typename std::decay::type; 59 | static_assert(std::is_base_of::value, 60 | "can only downcast from base to derived class"); 61 | DEBUG_ASSERT(detail::is_safe_downcast(derived_type{}, obj), 62 | detail::precondition_error_handler{}, "not a safe downcast"); 63 | } 64 | } // namespace detail 65 | 66 | /// Casts an object of base class type to the derived class type. 67 | /// \returns The object converted as if `static_cast(obj)`. 68 | /// \requires `Base` must be a base class of `Derived`, 69 | /// and the dynamic type of `obj` must be `Derived`. 70 | template 71 | Derived downcast(Base& obj) noexcept 72 | { 73 | detail::validate_downcast(obj); 74 | return static_cast(obj); 75 | } 76 | 77 | /// Casts an object of base class type to the derived class type. 78 | /// \returns The object converted as if `static_cast(obj)`, 79 | /// where `derived_ref` is the type of `Derived` with matching qualifiers. 80 | /// \requires `Base` must be a base class of `Derived`, 81 | /// and the dynamic type of `obj` must be `Derived`. 82 | /// \group downcast_tag 83 | template 84 | Derived& downcast(derived_type, Base& obj) noexcept 85 | { 86 | detail::validate_downcast(obj); 87 | return static_cast(obj); 88 | } 89 | 90 | /// \group downcast_tag 91 | template 92 | const Derived& downcast(derived_type, const Base& obj) noexcept 93 | { 94 | detail::validate_downcast(obj); 95 | return static_cast(obj); 96 | } 97 | } // namespace type_safe 98 | 99 | #endif // TYPE_SAFE_DOWNCAST_HPP_INCLUDED 100 | -------------------------------------------------------------------------------- /vendor/vendor/include/utf8cpp/utf8.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | 28 | #ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | #define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 30 | 31 | /* 32 | To control the C++ language version used by the library, you can define UTF_CPP_CPLUSPLUS macro 33 | and set it to one of the values used by the __cplusplus predefined macro. 34 | 35 | For instance, 36 | #define UTF_CPP_CPLUSPLUS 199711L 37 | will cause the UTF-8 CPP library to use only types and language features available in the C++ 98 standard. 38 | Some library features will be disabled. 39 | 40 | If you leave UTF_CPP_CPLUSPLUS undefined, it will be internally assigned to __cplusplus. 41 | */ 42 | 43 | #include "utf8/checked.h" 44 | #include "utf8/unchecked.h" 45 | 46 | #endif // header guard 47 | -------------------------------------------------------------------------------- /vendor/vendor/include/utf8cpp/utf8/cpp11.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | 28 | #ifndef UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1 29 | #define UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1 30 | 31 | #include "checked.h" 32 | 33 | namespace utf8 34 | { 35 | inline void append16(utfchar32_t cp, std::u16string& s) 36 | { 37 | append16(cp, std::back_inserter(s)); 38 | } 39 | 40 | inline std::string utf16to8(const std::u16string& s) 41 | { 42 | std::string result; 43 | utf16to8(s.begin(), s.end(), std::back_inserter(result)); 44 | return result; 45 | } 46 | 47 | inline std::u16string utf8to16(const std::string& s) 48 | { 49 | std::u16string result; 50 | utf8to16(s.begin(), s.end(), std::back_inserter(result)); 51 | return result; 52 | } 53 | 54 | inline std::string utf32to8(const std::u32string& s) 55 | { 56 | std::string result; 57 | utf32to8(s.begin(), s.end(), std::back_inserter(result)); 58 | return result; 59 | } 60 | 61 | inline std::u32string utf8to32(const std::string& s) 62 | { 63 | std::u32string result; 64 | utf8to32(s.begin(), s.end(), std::back_inserter(result)); 65 | return result; 66 | } 67 | } // namespace utf8 68 | 69 | #endif // header guard 70 | 71 | -------------------------------------------------------------------------------- /vendor/vendor/include/utf8cpp/utf8/cpp17.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | 28 | #ifndef UTF8_FOR_CPP_7e906c01_03a3_4daf_b420_ea7ea952b3c9 29 | #define UTF8_FOR_CPP_7e906c01_03a3_4daf_b420_ea7ea952b3c9 30 | 31 | #include "cpp11.h" 32 | 33 | namespace utf8 34 | { 35 | inline std::string utf16to8(std::u16string_view s) 36 | { 37 | std::string result; 38 | utf16to8(s.begin(), s.end(), std::back_inserter(result)); 39 | return result; 40 | } 41 | 42 | inline std::u16string utf8to16(std::string_view s) 43 | { 44 | std::u16string result; 45 | utf8to16(s.begin(), s.end(), std::back_inserter(result)); 46 | return result; 47 | } 48 | 49 | inline std::string utf32to8(std::u32string_view s) 50 | { 51 | std::string result; 52 | utf32to8(s.begin(), s.end(), std::back_inserter(result)); 53 | return result; 54 | } 55 | 56 | inline std::u32string utf8to32(std::string_view s) 57 | { 58 | std::u32string result; 59 | utf8to32(s.begin(), s.end(), std::back_inserter(result)); 60 | return result; 61 | } 62 | 63 | inline std::size_t find_invalid(std::string_view s) 64 | { 65 | std::string_view::const_iterator invalid = find_invalid(s.begin(), s.end()); 66 | return (invalid == s.end()) ? std::string_view::npos : static_cast(invalid - s.begin()); 67 | } 68 | 69 | inline bool is_valid(std::string_view s) 70 | { 71 | return is_valid(s.begin(), s.end()); 72 | } 73 | 74 | inline std::string replace_invalid(std::string_view s, char32_t replacement) 75 | { 76 | std::string result; 77 | replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement); 78 | return result; 79 | } 80 | 81 | inline std::string replace_invalid(std::string_view s) 82 | { 83 | std::string result; 84 | replace_invalid(s.begin(), s.end(), std::back_inserter(result)); 85 | return result; 86 | } 87 | 88 | inline bool starts_with_bom(std::string_view s) 89 | { 90 | return starts_with_bom(s.begin(), s.end()); 91 | } 92 | 93 | } // namespace utf8 94 | 95 | #endif // header guard 96 | 97 | -------------------------------------------------------------------------------- /vendor/vendor/include/utf8cpp/utf8/cpp20.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | 28 | #ifndef UTF8_FOR_CPP_207e906c01_03a3_4daf_b420_ea7ea952b3c9 29 | #define UTF8_FOR_CPP_207e906c01_03a3_4daf_b420_ea7ea952b3c9 30 | 31 | #include "cpp17.h" 32 | 33 | namespace utf8 34 | { 35 | inline std::u8string utf16tou8(const std::u16string& s) 36 | { 37 | std::u8string result; 38 | utf16to8(s.begin(), s.end(), std::back_inserter(result)); 39 | return result; 40 | } 41 | 42 | inline std::u8string utf16tou8(std::u16string_view s) 43 | { 44 | std::u8string result; 45 | utf16to8(s.begin(), s.end(), std::back_inserter(result)); 46 | return result; 47 | } 48 | 49 | inline std::u16string utf8to16(const std::u8string& s) 50 | { 51 | std::u16string result; 52 | utf8to16(s.begin(), s.end(), std::back_inserter(result)); 53 | return result; 54 | } 55 | 56 | inline std::u16string utf8to16(const std::u8string_view& s) 57 | { 58 | std::u16string result; 59 | utf8to16(s.begin(), s.end(), std::back_inserter(result)); 60 | return result; 61 | } 62 | 63 | inline std::u8string utf32tou8(const std::u32string& s) 64 | { 65 | std::u8string result; 66 | utf32to8(s.begin(), s.end(), std::back_inserter(result)); 67 | return result; 68 | } 69 | 70 | inline std::u8string utf32tou8(const std::u32string_view& s) 71 | { 72 | std::u8string result; 73 | utf32to8(s.begin(), s.end(), std::back_inserter(result)); 74 | return result; 75 | } 76 | 77 | inline std::u32string utf8to32(const std::u8string& s) 78 | { 79 | std::u32string result; 80 | utf8to32(s.begin(), s.end(), std::back_inserter(result)); 81 | return result; 82 | } 83 | 84 | inline std::u32string utf8to32(const std::u8string_view& s) 85 | { 86 | std::u32string result; 87 | utf8to32(s.begin(), s.end(), std::back_inserter(result)); 88 | return result; 89 | } 90 | 91 | inline std::size_t find_invalid(const std::u8string& s) 92 | { 93 | std::u8string::const_iterator invalid = find_invalid(s.begin(), s.end()); 94 | return (invalid == s.end()) ? std::string_view::npos : static_cast(invalid - s.begin()); 95 | } 96 | 97 | inline bool is_valid(const std::u8string& s) 98 | { 99 | return is_valid(s.begin(), s.end()); 100 | } 101 | 102 | inline std::u8string replace_invalid(const std::u8string& s, char32_t replacement) 103 | { 104 | std::u8string result; 105 | replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement); 106 | return result; 107 | } 108 | 109 | inline std::u8string replace_invalid(const std::u8string& s) 110 | { 111 | std::u8string result; 112 | replace_invalid(s.begin(), s.end(), std::back_inserter(result)); 113 | return result; 114 | } 115 | 116 | inline bool starts_with_bom(const std::u8string& s) 117 | { 118 | return starts_with_bom(s.begin(), s.end()); 119 | } 120 | 121 | } // namespace utf8 122 | 123 | #endif // header guard 124 | 125 | --------------------------------------------------------------------------------